'packages/*/*.js',
'packages/vue/*/*.js',
'packages-private/benchmark/*',
+ 'packages-private/e2e-utils/*',
],
rules: {
'no-restricted-globals': 'off',
"format": "prettier --write --cache .",
"format-check": "prettier --check --cache .",
"test": "vitest",
- "test-unit": "vitest --project unit",
+ "test-unit": "vitest --project unit --project unit-jsdom",
"test-e2e": "node scripts/build.js vue -f global -d && vitest --project e2e",
+ "test-e2e-vapor": "pnpm run prepare-e2e-vapor && vitest --project e2e-vapor",
+ "prepare-e2e-vapor": "node scripts/build.js -f cjs+esm-bundler+esm-bundler-runtime && pnpm run -C packages-private/vapor-e2e-test build",
"test-dts": "run-s build-dts test-dts-only",
"test-dts-only": "tsc -p packages-private/dts-built-test/tsconfig.json && tsc -p ./packages-private/dts-test/tsconfig.test.json",
"test-coverage": "vitest run --project unit --coverage",
"release": "node scripts/release.js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
"dev-esm": "node scripts/dev.js -if esm-bundler-runtime",
- "dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs",
+ "dev-prepare-cjs": "node scripts/prepare-cjs.js || node scripts/build.js -f cjs",
"dev-compiler": "run-p \"dev template-explorer\" serve open",
"dev-sfc": "run-s dev-prepare-cjs dev-sfc-run",
"dev-sfc-serve": "vite packages-private/sfc-playground",
- "dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if vapor\" \"dev vue -ipf vapor\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
- "dev-vapor": "pnpm -C playground run dev",
+ "dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-browser-vapor\" \"dev vue -ipf esm-browser-vapor\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
+ "dev-vapor": "pnpm -C packages-private/local-playground run dev",
"serve": "serve",
"open": "open http://localhost:3000/packages-private/template-explorer/local.html",
- "build-sfc-playground": "run-s build-all-cjs build-all-esm build-sfc-playground-self",
- "build-all-cjs": "node scripts/build.js vue runtime compiler reactivity shared -af cjs",
- "build-all-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler+esm-browser+esm-bundler-runtime+esm-browser-runtime+vapor && node scripts/build.js compiler-sfc server-renderer -f esm-browser",
- "build-sfc-playground-self": "cd packages-private/sfc-playground && npm run build",
+ "build-sfc-playground": "run-s build-sfc-deps build-sfc-playground-self",
+ "build-sfc-deps": "node scripts/build.js -f ~global+global-runtime",
+ "build-sfc-playground-self": "pnpm run -C packages-private/sfc-playground build",
"preinstall": "npx only-allow pnpm",
"postinstall": "simple-git-hooks"
},
),
exec(
'pnpm',
- `run --silent build vue ${buildOptions} vapor`.split(' '),
+ `run --silent build vue ${buildOptions} esm-browser-vapor`.split(' '),
options,
),
])
const runtimePath = path.resolve(
import.meta.dirname,
- (isVapor
- ? '../../packages/vue/dist/vue.runtime-with-vapor.esm-browser'
- : '../../packages/vue/dist/vue.runtime.esm-browser') + prodSuffix,
+ '../../packages/vue/dist/vue.runtime-with-vapor.esm-browser' + prodSuffix,
)
const mode = isVapor ? 'vapor' : 'vdom'
'import.meta.env.IS_VAPOR': String(isVapor),
},
build: {
- minify: !devBuild && 'terser',
+ minify: !devBuild,
outDir: path.resolve('./client/dist', mode),
rollupOptions: {
onwarn(log, handler) {
"license": "MIT",
"type": "module",
"scripts": {
- "dev": "pnpm start --devBuild --noHeadless --skipBench --vdom",
+ "dev": "pnpm start --devBuild --skipBench --vdom",
"start": "node index.js"
},
"dependencies": {
"vite": "catalog:"
},
"devDependencies": {
- "@types/connect": "^3.4.38",
- "terser": "^5.33.0"
+ "@types/connect": "^3.4.38"
}
}
"vue": "workspace:*"
},
"devDependencies": {
- "@vitejs/plugin-vue": "https://pkg.pr.new/@vitejs/plugin-vue@c156992",
+ "@vitejs/plugin-vue": "catalog:",
"@vue/compiler-sfc": "workspace:*",
"vite": "catalog:",
"vite-hyper-config": "^0.4.0",
"compilerOptions": {
"isolatedDeclarations": false
},
- "include": ["."]
+ "include": [".", "../packages/vue/__tests__/e2e/e2eUtils.ts"]
}
--- /dev/null
+import puppeteer, {
+ type Browser,
+ type ClickOptions,
+ type LaunchOptions,
+ type Page,
+} from 'puppeteer'
+
+export const E2E_TIMEOUT: number = 30 * 1000
+
+const puppeteerOptions: LaunchOptions = {
+ args: process.env.CI ? ['--no-sandbox', '--disable-setuid-sandbox'] : [],
+ headless: true,
+}
+
+const maxTries = 30
+export const timeout = (n: number): Promise<any> =>
+ new Promise(r => setTimeout(r, n))
+
+export async function expectByPolling(
+ poll: () => Promise<any>,
+ expected: string,
+): Promise<void> {
+ for (let tries = 0; tries < maxTries; tries++) {
+ const actual = (await poll()) || ''
+ if (actual.indexOf(expected) > -1 || tries === maxTries - 1) {
+ expect(actual).toMatch(expected)
+ break
+ } else {
+ await timeout(50)
+ }
+ }
+}
+
+interface PuppeteerUtils {
+ page: () => Page
+ click(selector: string, options?: ClickOptions): Promise<void>
+ count(selector: string): Promise<number>
+ text(selector: string): Promise<string | null>
+ value(selector: string): Promise<string>
+ html(selector: string): Promise<string>
+ classList(selector: string): Promise<string[]>
+ style(selector: string, property: keyof CSSStyleDeclaration): Promise<any>
+ children(selector: string): Promise<any[]>
+ isVisible(selector: string): Promise<boolean>
+ isChecked(selector: string): Promise<boolean>
+ isFocused(selector: string): Promise<boolean>
+ setValue(selector: string, value: string): Promise<any>
+ typeValue(selector: string, value: string): Promise<any>
+ enterValue(selector: string, value: string): Promise<any>
+ clearValue(selector: string): Promise<any>
+ timeout(time: number): Promise<any>
+ nextFrame(): Promise<any>
+}
+
+export function setupPuppeteer(args?: string[]): PuppeteerUtils {
+ let browser: Browser
+ let page: Page
+
+ const resolvedOptions = args
+ ? {
+ ...puppeteerOptions,
+ args: [...puppeteerOptions.args!, ...args],
+ }
+ : puppeteerOptions
+
+ beforeAll(async () => {
+ browser = await puppeteer.launch(resolvedOptions)
+ }, 20000)
+
+ beforeEach(async () => {
+ page = await browser.newPage()
+
+ await page.evaluateOnNewDocument(() => {
+ localStorage.clear()
+ })
+
+ page.on('console', e => {
+ if (e.type() === 'error') {
+ console.error(`Error from Puppeteer-loaded page:\n`, e.text())
+ }
+ })
+ })
+
+ afterEach(async () => {
+ await page.close()
+ })
+
+ afterAll(async () => {
+ await browser.close()
+ })
+
+ async function click(
+ selector: string,
+ options?: ClickOptions,
+ ): Promise<void> {
+ await page.click(selector, options)
+ }
+
+ async function count(selector: string): Promise<number> {
+ return (await page.$$(selector)).length
+ }
+
+ async function text(selector: string): Promise<string | null> {
+ return page.$eval(selector, node => node.textContent)
+ }
+
+ async function value(selector: string): Promise<string> {
+ return page.$eval(selector, node => (node as HTMLInputElement).value)
+ }
+
+ async function html(selector: string): Promise<string> {
+ return page.$eval(selector, node => node.innerHTML)
+ }
+
+ async function classList(selector: string): Promise<string[]> {
+ return page.$eval(selector, (node: any) => [...node.classList])
+ }
+
+ async function children(selector: string): Promise<any[]> {
+ return page.$eval(selector, (node: any) => [...node.children])
+ }
+
+ async function style(
+ selector: string,
+ property: keyof CSSStyleDeclaration,
+ ): Promise<any> {
+ return await page.$eval(
+ selector,
+ (node, property) => {
+ return window.getComputedStyle(node)[property]
+ },
+ property,
+ )
+ }
+
+ async function isVisible(selector: string): Promise<boolean> {
+ const display = await page.$eval(selector, node => {
+ return window.getComputedStyle(node).display
+ })
+ return display !== 'none'
+ }
+
+ async function isChecked(selector: string) {
+ return await page.$eval(
+ selector,
+ node => (node as HTMLInputElement).checked,
+ )
+ }
+
+ async function isFocused(selector: string) {
+ return await page.$eval(selector, node => node === document.activeElement)
+ }
+
+ async function setValue(selector: string, value: string) {
+ await page.$eval(
+ selector,
+ (node, value) => {
+ ;(node as HTMLInputElement).value = value as string
+ node.dispatchEvent(new Event('input'))
+ },
+ value,
+ )
+ }
+
+ async function typeValue(selector: string, value: string) {
+ const el = (await page.$(selector))!
+ await el.evaluate(node => ((node as HTMLInputElement).value = ''))
+ await el.type(value)
+ }
+
+ async function enterValue(selector: string, value: string) {
+ const el = (await page.$(selector))!
+ await el.evaluate(node => ((node as HTMLInputElement).value = ''))
+ await el.type(value)
+ await el.press('Enter')
+ }
+
+ async function clearValue(selector: string) {
+ return await page.$eval(
+ selector,
+ node => ((node as HTMLInputElement).value = ''),
+ )
+ }
+
+ function timeout(time: number) {
+ return page.evaluate(time => {
+ return new Promise(r => {
+ setTimeout(r, time)
+ })
+ }, time)
+ }
+
+ function nextFrame() {
+ return page.evaluate(() => {
+ return new Promise(resolve => {
+ requestAnimationFrame(() => {
+ requestAnimationFrame(resolve)
+ })
+ })
+ })
+ }
+
+ return {
+ page: () => page,
+ click,
+ count,
+ text,
+ value,
+ html,
+ classList,
+ style,
+ children,
+ isVisible,
+ isChecked,
+ isFocused,
+ setValue,
+ typeValue,
+ enterValue,
+ clearValue,
+ timeout,
+ nextFrame,
+ }
+}
--- /dev/null
+test('bar', () => {})
--- /dev/null
+import path from 'node:path'
+import {
+ E2E_TIMEOUT,
+ setupPuppeteer,
+} from '../../../packages/vue/__tests__/e2e/e2eUtils'
+import connect from 'connect'
+import sirv from 'sirv'
+
+describe('vdom / vapor interop', () => {
+ const { page, click, text, enterValue } = setupPuppeteer()
+
+ let server: any
+ const port = '8193'
+ beforeAll(() => {
+ server = connect()
+ .use(sirv(path.resolve(import.meta.dirname, '../dist')))
+ .listen(port)
+ process.on('SIGTERM', () => server && server.close())
+ })
+
+ afterAll(() => {
+ server.close()
+ })
+
+ test(
+ 'should work',
+ async () => {
+ const baseUrl = `http://localhost:${port}/interop`
+ await page().goto(baseUrl)
+
+ expect(await text('.vapor > h2')).toContain('Vapor component in VDOM')
+
+ expect(await text('.vapor-prop')).toContain('hello')
+
+ const t = await text('.vdom-slot-in-vapor-default')
+ expect(t).toContain('slot prop: slot prop')
+ expect(t).toContain('component prop: hello')
+
+ await click('.change-vdom-slot-in-vapor-prop')
+ expect(await text('.vdom-slot-in-vapor-default')).toContain(
+ 'slot prop: changed',
+ )
+
+ expect(await text('.vdom-slot-in-vapor-test')).toContain('A test slot')
+
+ await click('.toggle-vdom-slot-in-vapor')
+ expect(await text('.vdom-slot-in-vapor-test')).toContain(
+ 'fallback content',
+ )
+
+ await click('.toggle-vdom-slot-in-vapor')
+ expect(await text('.vdom-slot-in-vapor-test')).toContain('A test slot')
+
+ expect(await text('.vdom > h2')).toContain('VDOM component in Vapor')
+
+ expect(await text('.vdom-prop')).toContain('hello')
+
+ const tt = await text('.vapor-slot-in-vdom-default')
+ expect(tt).toContain('slot prop: slot prop')
+ expect(tt).toContain('component prop: hello')
+
+ await click('.change-vapor-slot-in-vdom-prop')
+ expect(await text('.vapor-slot-in-vdom-default')).toContain(
+ 'slot prop: changed',
+ )
+
+ expect(await text('.vapor-slot-in-vdom-test')).toContain('fallback')
+
+ await click('.toggle-vapor-slot-in-vdom-default')
+ expect(await text('.vapor-slot-in-vdom-default')).toContain(
+ 'default slot fallback',
+ )
+
+ await click('.toggle-vapor-slot-in-vdom-default')
+
+ await enterValue('input', 'bye')
+ expect(await text('.vapor-prop')).toContain('bye')
+ expect(await text('.vdom-slot-in-vapor-default')).toContain('bye')
+ expect(await text('.vdom-prop')).toContain('bye')
+ expect(await text('.vapor-slot-in-vdom-default')).toContain('bye')
+ },
+ E2E_TIMEOUT,
+ )
+})
--- /dev/null
+<a href="/interop/">VDOM / Vapor interop</a>
+<a href="/todomvc/">Vapor TodoMVC</a>
--- /dev/null
+<script setup lang="ts">
+import { ref } from 'vue'
+import VaporComp from './VaporComp.vue'
+
+const msg = ref('hello')
+const passSlot = ref(true)
+</script>
+
+<template>
+ <input v-model="msg" />
+ <button class="toggle-vdom-slot-in-vapor" @click="passSlot = !passSlot">
+ toggle #test slot
+ </button>
+ <VaporComp :msg="msg">
+ <template #default="{ foo }">
+ <div>slot prop: {{ foo }}</div>
+ <div>component prop: {{ msg }}</div>
+ </template>
+
+ <template #test v-if="passSlot">A test slot</template>
+ </VaporComp>
+</template>
--- /dev/null
+<script setup vapor lang="ts">
+import { ref } from 'vue'
+import VdomComp from './VdomComp.vue'
+
+defineProps<{
+ msg: string
+}>()
+
+const ok = ref(true)
+const passSlot = ref(true)
+const slotProp = ref('slot prop')
+</script>
+
+<template>
+ <div class="vapor" style="border: 2px solid red; padding: 10px">
+ <h2>This is a Vapor component in VDOM</h2>
+ <p class="vapor-prop">props.msg: {{ msg }}</p>
+
+ <button @click="ok = !ok">Toggle slots</button>
+
+ <div v-if="ok" style="border: 2px solid orange; padding: 10px">
+ <h3>vdom slots in vapor component</h3>
+ <button
+ class="change-vdom-slot-in-vapor-prop"
+ @click="slotProp = 'changed'"
+ >
+ change slot prop
+ </button>
+ <div class="vdom-slot-in-vapor-default">
+ #default: <slot :foo="slotProp" />
+ </div>
+ <div class="vdom-slot-in-vapor-test">
+ #test: <slot name="test">fallback content</slot>
+ </div>
+ </div>
+
+ <button
+ class="toggle-vapor-slot-in-vdom-default"
+ @click="passSlot = !passSlot"
+ >
+ Toggle default slot to vdom
+ </button>
+ <VdomComp :msg="msg">
+ <template #default="{ foo }" v-if="passSlot">
+ <div>slot prop: {{ foo }}</div>
+ <div>component prop: {{ msg }}</div>
+ </template>
+ </VdomComp>
+ </div>
+</template>
--- /dev/null
+<script setup lang="ts">
+import { ref } from 'vue'
+
+defineProps<{
+ msg: string
+}>()
+
+const bar = ref('slot prop')
+</script>
+
+<template>
+ <div class="vdom" style="border: 2px solid blue; padding: 10px">
+ <h2>This is a VDOM component in Vapor</h2>
+ <p class="vdom-prop">props.msg: {{ msg }}</p>
+ <div style="border: 2px solid aquamarine; padding: 10px">
+ <h3>vapor slots in vdom</h3>
+ <button class="change-vapor-slot-in-vdom-prop" @click="bar = 'changed'">
+ Change slot prop
+ </button>
+ <div class="vapor-slot-in-vdom-default">
+ #default: <slot :foo="bar">default slot fallback</slot>
+ </div>
+ <div class="vapor-slot-in-vdom-test">
+ #test <slot name="test">fallback</slot>
+ </div>
+ </div>
+ </div>
+</template>
--- /dev/null
+<script type="module" src="./main.ts"></script>
+<div id="app"></div>
--- /dev/null
+import { createApp, vaporInteropPlugin } from 'vue'
+import App from './App.vue'
+
+createApp(App).use(vaporInteropPlugin).mount('#app')
--- /dev/null
+{
+ "name": "vapor-e2e-test",
+ "private": true,
+ "version": "0.0.0",
+ "type": "module",
+ "scripts": {
+ "dev": "vite dev",
+ "build": "vite build"
+ },
+ "devDependencies": {
+ "@types/connect": "^3.4.38",
+ "@vitejs/plugin-vue": "catalog:",
+ "connect": "^3.7.0",
+ "sirv": "^2.0.4",
+ "vite": "catalog:",
+ "vue": "workspace:*"
+ }
+}
--- /dev/null
+<script type="module" src="./main.ts"></script>
--- /dev/null
+import { defineConfig } from 'vite'
+import Vue from '@vitejs/plugin-vue'
+import * as CompilerSFC from 'vue/compiler-sfc'
+import { resolve } from 'node:path'
+
+export default defineConfig({
+ plugins: [
+ Vue({
+ compiler: CompilerSFC,
+ }),
+ ],
+ build: {
+ rollupOptions: {
+ input: {
+ interop: resolve(import.meta.dirname, 'interop/index.html'),
+ todomvc: resolve(import.meta.dirname, 'todomvc/index.html'),
+ },
+ },
+ },
+})
page.on('console', e => {
if (e.type() === 'error') {
- const err = e.args()[0]
- console.error(`Error from Puppeteer-loaded page:\n`, err.remoteObject())
+ console.error(`Error from Puppeteer-loaded page:\n`, e.text())
}
})
})
"global-runtime",
"esm-browser",
"esm-browser-runtime",
- "vapor"
+ "esm-browser-vapor"
]
},
"repository": {
specifier: ^7.25.2
version: 7.26.0
'@vitejs/plugin-vue':
- specifier: ^5.2.1
+ specifier: https://pkg.pr.new/@vitejs/plugin-vue@c156992
version: 5.2.1
estree-walker:
specifier: ^2.0.2
'@types/connect':
specifier: ^3.4.38
version: 3.4.38
- terser:
- specifier: ^5.33.0
- version: 5.33.0
packages-private/dts-built-test:
dependencies:
specifier: workspace:*
version: link:../../packages/vue
+ packages-private/e2e-utils: {}
+
packages-private/local-playground:
dependencies:
'@vueuse/core':
version: link:../../packages/vue
devDependencies:
'@vitejs/plugin-vue':
- specifier: https://pkg.pr.new/@vitejs/plugin-vue@c156992
+ specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
'@vue/compiler-sfc':
specifier: workspace:*
devDependencies:
'@vitejs/plugin-vue':
specifier: 'catalog:'
- version: 5.2.1(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
+ version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
vite:
specifier: 'catalog:'
version: 6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1)
specifier: ^1.2.1
version: 1.2.1
+ packages-private/vapor-e2e-test:
+ devDependencies:
+ '@types/connect':
+ specifier: ^3.4.38
+ version: 3.4.38
+ '@vitejs/plugin-vue':
+ specifier: 'catalog:'
+ version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
+ connect:
+ specifier: ^3.7.0
+ version: 3.7.0
+ sirv:
+ specifier: ^2.0.4
+ version: 2.0.4
+ vite:
+ specifier: 'catalog:'
+ version: 6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1)
+ vue:
+ specifier: workspace:*
+ version: link:../../packages/vue
+
packages-private/vite-debug:
devDependencies:
'@vitejs/plugin-vue':
specifier: 'catalog:'
- version: 5.2.1(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
+ version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)
vite:
specifier: 'catalog:'
version: 6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1)
resolution: {integrity: sha512-v/BpkeeYAsPkKCkR8BDwcno0llhzWVqPOamQrAEMdpZav2Y9OVjd9dwJyBLJWwf335B5DmlifECIkZRJCaGaHA==}
engines: {node: ^18.18.0 || ^20.9.0 || >=21.1.0}
- '@vitejs/plugin-vue@5.2.1':
- resolution: {integrity: sha512-cxh314tzaWwOLqVes2gnnCtvBDcM1UMdn+iFR+UjAn411dPT3tOmqrJjbMd7koZpMAmBM/GqeV4n9ge7JSiJJQ==}
- engines: {node: ^18.0.0 || >=20.0.0}
- peerDependencies:
- vite: ^5.0.0 || ^6.0.0
- vue: ^3.2.25
-
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@c156992':
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@c156992}
version: 5.2.1
dependencies:
'@jridgewell/gen-mapping': 0.3.5
'@jridgewell/trace-mapping': 0.3.25
+ optional: true
'@jridgewell/sourcemap-codec@1.5.0': {}
'@typescript-eslint/types': 8.20.0
eslint-visitor-keys: 4.2.0
- '@vitejs/plugin-vue@5.2.1(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@packages+vue)':
- dependencies:
- vite: 6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1)
- vue: link:packages/vue
-
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1))(vue@3.5.13(typescript@5.6.2))':
dependencies:
vite: 6.1.0(@types/node@22.10.7)(sass@1.83.4)(terser@5.33.0)(yaml@2.6.1)
buffer-crc32@0.2.13: {}
- buffer-from@1.1.2: {}
+ buffer-from@1.1.2:
+ optional: true
buffer@5.7.1:
dependencies:
commander@12.1.0: {}
- commander@2.20.3: {}
+ commander@2.20.3:
+ optional: true
commondir@1.0.1: {}
dependencies:
buffer-from: 1.1.2
source-map: 0.6.1
+ optional: true
source-map@0.6.1: {}
acorn: 8.14.0
commander: 2.20.3
source-map-support: 0.5.21
+ optional: true
test-exclude@7.0.1:
dependencies:
'magic-string': ^0.30.11
'source-map-js': ^1.2.0
'vite': ^6.1.0
- '@vitejs/plugin-vue': ^5.2.1
+ '@vitejs/plugin-vue': https://pkg.pr.new/@vitejs/plugin-vue@c156992
* @template {keyof T} K
* @typedef { Omit<T, K> & Required<Pick<T, K>> } MarkRequired
*/
-/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime' | 'vapor'} PackageFormat */
+/** @typedef {'cjs' | 'esm-bundler' | 'global' | 'global-runtime' | 'esm-browser' | 'esm-bundler-runtime' | 'esm-browser-runtime' | 'esm-browser-vapor'} PackageFormat */
/** @typedef {MarkRequired<import('rollup').OutputOptions, 'file' | 'format'>} OutputOptions */
if (!process.env.TARGET) {
},
// The vapor format is a esm-browser + runtime only build that is meant for
// the SFC playground only.
- vapor: {
+ 'esm-browser-vapor': {
file: resolve(`dist/${name}.runtime-with-vapor.esm-browser.js`),
format: 'es',
},
if (format === 'cjs') {
packageConfigs.push(createProductionConfig(format))
}
- if (format === 'vapor' || /^(global|esm-browser)(-runtime)?/.test(format)) {
+ if (
+ format === 'esm-browser-vapor' ||
+ /^(global|esm-browser)(-runtime)?/.test(format)
+ ) {
packageConfigs.push(createMinifiedConfig(format))
}
})
const isProductionBuild =
process.env.__DEV__ === 'false' || /\.prod\.js$/.test(output.file)
const isBundlerESMBuild = /esm-bundler/.test(format)
- const isBrowserESMBuild = /esm-browser/.test(format) || format === 'vapor'
+ const isBrowserESMBuild = /esm-browser/.test(format)
const isServerRenderer = name === 'server-renderer'
const isCJSBuild = format === 'cjs'
const isGlobalBuild = /global/.test(format)
output.name = packageOptions.name
}
- let entryFile =
- pkg.name === 'vue' &&
- (format === 'vapor' || format.startsWith('esm-bundler'))
- ? 'runtime-with-vapor.ts'
- : /\bruntime\b/.test(format)
- ? `runtime.ts`
- : `index.ts`
+ let entryFile = 'index.ts'
+ if (pkg.name === 'vue') {
+ if (format === 'esm-browser-vapor' || format === 'esm-bundler-runtime') {
+ entryFile = 'runtime-with-vapor.ts'
+ } else if (format === 'esm-bundler') {
+ entryFile = 'index-with-vapor.ts'
+ } else if (format.includes('runtime')) {
+ entryFile = 'runtime.ts'
+ }
+ }
// the compat build needs both default AND named exports. This will cause
// Rollup to complain for non-ESM targets, so we use separate entries for
return
}
+ let resolvedFormats
if (formats) {
- let resolvedFormats = formats.split('+')
+ const isNegation = formats.startsWith('~')
+ resolvedFormats = (isNegation ? formats.slice(1) : formats).split('+')
const pkgFormats = pkg.buildOptions?.formats
if (pkgFormats) {
- resolvedFormats = resolvedFormats.filter(f => pkgFormats.includes(f))
+ if (isNegation) {
+ resolvedFormats = pkgFormats.filter(f => !resolvedFormats.includes(f))
+ } else {
+ resolvedFormats = resolvedFormats.filter(f => pkgFormats.includes(f))
+ }
}
if (!resolvedFormats.length) {
return
`COMMIT:${commit}`,
`NODE_ENV:${env}`,
`TARGET:${target}`,
- formats ? `FORMATS:${formats}` : ``,
+ resolvedFormats ? `FORMATS:${resolvedFormats.join('+')}` : ``,
prodOnly ? `PROD_ONLY:true` : ``,
sourceMap ? `SOURCE_MAP:true` : ``,
]
* @returns {Promise<void>}
*/
async function checkAllSizes(targets) {
- if (devOnly || (formats && !formats.includes('global'))) {
+ if (
+ devOnly ||
+ (formats && (formats.startsWith('~') || !formats.includes('global')))
+ ) {
return
}
console.log()
: 'esm'
const postfix =
- format === 'vapor'
+ format === 'esm-browser-vapor'
? 'runtime-with-vapor.esm-browser'
: format.endsWith('-runtime')
? `runtime.${format.replace(/-runtime$/, '')}`
}
const entry =
- format === 'vapor'
+ format === 'esm-browser-vapor'
? 'runtime-with-vapor.ts'
: format.endsWith('-runtime')
? 'runtime.ts'
*/
export function trimVaporExportsPlugin(format, pkgName) {
if (
- format === 'vapor' ||
+ format.includes('vapor') ||
format.startsWith('esm-bundler') ||
pkgName === '@vue/runtime-vapor'
) {
-import { defineConfig } from 'vitest/config'
+import { configDefaults, defineConfig } from 'vitest/config'
import { entries } from './scripts/aliases.js'
export default defineConfig({
},
},
setupFiles: 'scripts/setup-vitest.ts',
- environmentMatchGlobs: [
- ['packages/{vue,vue-compat,runtime-dom,runtime-vapor}/**', 'jsdom'],
- ],
sequence: {
hooks: 'list',
},
'packages/runtime-dom/src/components/Transition*',
],
},
+ workspace: [
+ {
+ extends: true,
+ test: {
+ name: 'unit',
+ exclude: [
+ ...configDefaults.exclude,
+ '**/e2e/**',
+ '**/vapor-e2e-test/**',
+ 'packages/{vue,vue-compat,runtime-dom,runtime-vapor}/**',
+ ],
+ },
+ },
+ {
+ extends: true,
+ test: {
+ name: 'unit-jsdom',
+ environment: 'jsdom',
+ include: [
+ 'packages/{vue,vue-compat,runtime-dom,runtime-vapor}/**/*.spec.ts',
+ ],
+ exclude: [...configDefaults.exclude, '**/e2e/**'],
+ },
+ },
+ {
+ extends: true,
+ test: {
+ name: 'e2e',
+ poolOptions: {
+ threads: {
+ singleThread: !!process.env.CI,
+ },
+ },
+ include: ['packages/vue/__tests__/e2e/*.spec.ts'],
+ },
+ },
+ {
+ extends: true,
+ test: {
+ name: 'e2e-vapor',
+ poolOptions: {
+ threads: {
+ singleThread: !!process.env.CI,
+ },
+ },
+ include: ['packages-private/vapor-e2e-test/__tests__/*.spec.ts'],
+ },
+ },
+ ],
},
})
+++ /dev/null
-import { mergeConfig } from 'vitest/config'
-import config from './vitest.config'
-
-export default mergeConfig(config, {
- test: {
- name: 'e2e',
- poolOptions: {
- threads: {
- singleThread: !!process.env.CI,
- },
- },
- include: ['packages/vue/__tests__/e2e/*.spec.ts'],
- },
-})
+++ /dev/null
-import { configDefaults, mergeConfig } from 'vitest/config'
-import config from './vitest.config'
-
-export default mergeConfig(config, {
- test: {
- name: 'unit',
- exclude: [...configDefaults.exclude, '**/e2e/**'],
- },
-})
+++ /dev/null
-import { defineWorkspace } from 'vitest/config'
-
-export default defineWorkspace([
- './vitest.unit.config.ts',
- './vitest.e2e.config.ts',
-])