chore: Merge branch 'minor' into vapor

This commit is contained in:
daiwei 2025-06-18 09:30:17 +08:00
commit a0c42ffbbc
39 changed files with 788 additions and 181 deletions

View File

@ -1,3 +1,41 @@
## [3.5.14](https://github.com/vuejs/core/compare/v3.5.13...v3.5.14) (2025-05-15)
### Bug Fixes
* **compat:** correct deprecation message for v-bind.sync usage ([#13137](https://github.com/vuejs/core/issues/13137)) ([466b30f](https://github.com/vuejs/core/commit/466b30f4049ec89fb282624ec17d1a93472ab93f)), closes [#13133](https://github.com/vuejs/core/issues/13133)
* **compiler-core:** remove slot cache from parent renderCache during unmounting ([#13215](https://github.com/vuejs/core/issues/13215)) ([5d166f3](https://github.com/vuejs/core/commit/5d166f3796a03a497435fc079c6a83a4e9c6cf52))
* **compiler-sfc:** fix scope handling for props destructure in function parameters and catch clauses ([8e34357](https://github.com/vuejs/core/commit/8e3435779a667de485cf9efd78667d0ca14c5f84)), closes [#12790](https://github.com/vuejs/core/issues/12790)
* **compiler-sfc:** treat the return value of `useTemplateRef` as a definite ref ([#13197](https://github.com/vuejs/core/issues/13197)) ([8ae1122](https://github.com/vuejs/core/commit/8ae11226e8ee938615e17c7b81dc38ae3f7cefb9))
* **compiler:** fix spelling error in domTagConfig ([#13043](https://github.com/vuejs/core/issues/13043)) ([388295b](https://github.com/vuejs/core/commit/388295b27f3cc69eba25d325bbe60a36a3df831a))
* **customFormatter:** properly accessing ref value during debugger ([#12948](https://github.com/vuejs/core/issues/12948)) ([fdbd026](https://github.com/vuejs/core/commit/fdbd02658301dd794fe0c84f0018d080a07fca9f))
* **hmr/teleport:** adjust static children traversal for HMR in dev mode ([#12819](https://github.com/vuejs/core/issues/12819)) ([5e37dd0](https://github.com/vuejs/core/commit/5e37dd009562bcd8080a200c32abde2d6e4f0305)), closes [#12816](https://github.com/vuejs/core/issues/12816)
* **hmr:** avoid hydration for hmr root reload ([#12450](https://github.com/vuejs/core/issues/12450)) ([1f98a9c](https://github.com/vuejs/core/commit/1f98a9c493d01c21befa90107f0593bc92a58932)), closes [vitejs/vite-plugin-vue#146](https://github.com/vitejs/vite-plugin-vue/issues/146) [vitejs/vite-plugin-vue#477](https://github.com/vitejs/vite-plugin-vue/issues/477)
* **hmr:** avoid hydration for hmr updating ([#12262](https://github.com/vuejs/core/issues/12262)) ([9c4dbbc](https://github.com/vuejs/core/commit/9c4dbbc5185125835ad3e49baba303bd54676111)), closes [#7706](https://github.com/vuejs/core/issues/7706) [#8170](https://github.com/vuejs/core/issues/8170)
* **reactivity:** ensure markRaw objects are not reactive ([#12824](https://github.com/vuejs/core/issues/12824)) ([295b5ec](https://github.com/vuejs/core/commit/295b5ec19b6a52c4a56652cc4d6e93a4ea7c14ed)), closes [#12807](https://github.com/vuejs/core/issues/12807)
* **reactivity:** ensure multiple effectScope on() and off() calls maintains correct active scope ([22dcbf3](https://github.com/vuejs/core/commit/22dcbf3e20eb84f69c8952f6f70d9990136a4a68)), closes [#12631](https://github.com/vuejs/core/issues/12631) [#12632](https://github.com/vuejs/core/issues/12632) [#12641](https://github.com/vuejs/core/issues/12641)
* **reactivity:** should not recompute if computed does not track reactive data ([#12341](https://github.com/vuejs/core/issues/12341)) ([0b23fd2](https://github.com/vuejs/core/commit/0b23fd23833cf085e7e112bf4435cfc9b360d072)), closes [#12337](https://github.com/vuejs/core/issues/12337)
* **runtime-core:** stop tracking deps in setRef during unmount ([#13210](https://github.com/vuejs/core/issues/13210)) ([016c472](https://github.com/vuejs/core/commit/016c472bd2e7604b21c69dee1da8545ce26e4d2f))
* **runtime-core:** update __vnode of static nodes when patching along the optimized path ([#13223](https://github.com/vuejs/core/issues/13223)) ([b3ecee3](https://github.com/vuejs/core/commit/b3ecee3da8ed5c55dea89ce6b4b376b2b722b018))
* **runtime-core:** inherit comment nodes during block patch in production build ([#10748](https://github.com/vuejs/core/issues/10748)) ([6264505](https://github.com/vuejs/core/commit/626450590d81f79117b34d2a73073b1dc8f551bd)), closes [#10747](https://github.com/vuejs/core/issues/10747) [#12650](https://github.com/vuejs/core/issues/12650)
* **runtime-core:** prevent unmounted vnode from being inserted during transition leave ([#12862](https://github.com/vuejs/core/issues/12862)) ([d6a6ec1](https://github.com/vuejs/core/commit/d6a6ec13ce521683bfb2a22932778ef7b51f8600)), closes [#12860](https://github.com/vuejs/core/issues/12860)
* **runtime-core:** respect immutability for readonly reactive arrays in `v-for` ([#13091](https://github.com/vuejs/core/issues/13091)) ([3f27c58](https://github.com/vuejs/core/commit/3f27c58ffbd4309df369bc89493fdc284dc540bb)), closes [#13087](https://github.com/vuejs/core/issues/13087)
* **runtime-dom:** always treat autocorrect as attribute ([#13001](https://github.com/vuejs/core/issues/13001)) ([1499135](https://github.com/vuejs/core/commit/1499135c227236e037bb746beeb777941b0b58ff)), closes [#5705](https://github.com/vuejs/core/issues/5705)
* **slots:** properly warn if slot invoked in setup ([#12195](https://github.com/vuejs/core/issues/12195)) ([9196222](https://github.com/vuejs/core/commit/9196222ae1d63b52b35ac5fbf5e71494587ccf05)), closes [#12194](https://github.com/vuejs/core/issues/12194)
* **ssr:** properly init slots during ssr rendering ([#12441](https://github.com/vuejs/core/issues/12441)) ([2206cd2](https://github.com/vuejs/core/commit/2206cd235a1627c540e795e378b7564a55b47313)), closes [#12438](https://github.com/vuejs/core/issues/12438)
* **transition:** fix KeepAlive with transition out-in mode behavior in production ([#12468](https://github.com/vuejs/core/issues/12468)) ([343c891](https://github.com/vuejs/core/commit/343c89122448719bd6ed6bd9de986dfb2721d6bf)), closes [#12465](https://github.com/vuejs/core/issues/12465)
* **TransitionGroup:** reset prevChildren to prevent memory leak ([#13183](https://github.com/vuejs/core/issues/13183)) ([8b848cb](https://github.com/vuejs/core/commit/8b848cbbd2af337d23e19e202f9ab433f8580855)), closes [#13181](https://github.com/vuejs/core/issues/13181)
* **types:** allow return any for Options API lifecycle hooks ([#5914](https://github.com/vuejs/core/issues/5914)) ([06310e8](https://github.com/vuejs/core/commit/06310e82f5bed62d1b9733dcb18cd8d6edc988de))
* **types:** the directive's modifiers should be optional ([#12605](https://github.com/vuejs/core/issues/12605)) ([10e54dc](https://github.com/vuejs/core/commit/10e54dcc86a7967f3196d96200bcbd1d3d42082f))
* **typos:** fix comments referencing transformElement.ts ([#12551](https://github.com/vuejs/core/issues/12551))[ci-skip] ([11c053a](https://github.com/vuejs/core/commit/11c053a5429ad0d27a0e2c78b6b026ea00ace116))
### Features
* **types:** add type TemplateRef ([#12645](https://github.com/vuejs/core/issues/12645)) ([636a861](https://github.com/vuejs/core/commit/636a8619f06c71dfd79f7f6412fd130c4f84226f))
## [3.5.13](https://github.com/vuejs/core/compare/v3.5.12...v3.5.13) (2024-11-15) ## [3.5.13](https://github.com/vuejs/core/compare/v3.5.12...v3.5.13) (2024-11-15)
@ -8,7 +46,7 @@
* **custom-element:** avoid triggering mutationObserver when relecting props ([352bc88](https://github.com/vuejs/core/commit/352bc88c1bd2fda09c61ab17ea1a5967ffcd7bc0)), closes [#12214](https://github.com/vuejs/core/issues/12214) [#12215](https://github.com/vuejs/core/issues/12215) * **custom-element:** avoid triggering mutationObserver when relecting props ([352bc88](https://github.com/vuejs/core/commit/352bc88c1bd2fda09c61ab17ea1a5967ffcd7bc0)), closes [#12214](https://github.com/vuejs/core/issues/12214) [#12215](https://github.com/vuejs/core/issues/12215)
* **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4)) * **deps:** update dependency postcss to ^8.4.48 ([#12356](https://github.com/vuejs/core/issues/12356)) ([b5ff930](https://github.com/vuejs/core/commit/b5ff930089985a58c3553977ef999cec2a6708a4))
* **hydration:** the component vnode's el should be updated when a mismatch occurs. ([#12255](https://github.com/vuejs/core/issues/12255)) ([a20a4cb](https://github.com/vuejs/core/commit/a20a4cb36a3e717d1f8f259d0d59f133f508ff0a)), closes [#12253](https://github.com/vuejs/core/issues/12253) * **hydration:** the component vnode's el should be updated when a mismatch occurs. ([#12255](https://github.com/vuejs/core/issues/12255)) ([a20a4cb](https://github.com/vuejs/core/commit/a20a4cb36a3e717d1f8f259d0d59f133f508ff0a)), closes [#12253](https://github.com/vuejs/core/issues/12253)
* **reactiivty:** avoid unnecessary watcher effect removal from inactive scope ([2193284](https://github.com/vuejs/core/commit/21932840eae72ffcd357a62ec596aaecc7ec224a)), closes [#5783](https://github.com/vuejs/core/issues/5783) [#5806](https://github.com/vuejs/core/issues/5806) * **reactivity:** avoid unnecessary watcher effect removal from inactive scope ([2193284](https://github.com/vuejs/core/commit/21932840eae72ffcd357a62ec596aaecc7ec224a)), closes [#5783](https://github.com/vuejs/core/issues/5783) [#5806](https://github.com/vuejs/core/issues/5806)
* **reactivity:** release nested effects/scopes on effect scope stop ([#12373](https://github.com/vuejs/core/issues/12373)) ([bee2f5e](https://github.com/vuejs/core/commit/bee2f5ee62dc0cd04123b737779550726374dd0a)), closes [#12370](https://github.com/vuejs/core/issues/12370) * **reactivity:** release nested effects/scopes on effect scope stop ([#12373](https://github.com/vuejs/core/issues/12373)) ([bee2f5e](https://github.com/vuejs/core/commit/bee2f5ee62dc0cd04123b737779550726374dd0a)), closes [#12370](https://github.com/vuejs/core/issues/12370)
* **runtime-dom:** set css vars before user onMounted hooks ([2d5c5e2](https://github.com/vuejs/core/commit/2d5c5e25e9b7a56e883674fb434135ac514429b5)), closes [#11533](https://github.com/vuejs/core/issues/11533) * **runtime-dom:** set css vars before user onMounted hooks ([2d5c5e2](https://github.com/vuejs/core/commit/2d5c5e25e9b7a56e883674fb434135ac514429b5)), closes [#11533](https://github.com/vuejs/core/issues/11533)
* **runtime-dom:** set css vars on update to handle child forcing reflow in onMount ([#11561](https://github.com/vuejs/core/issues/11561)) ([c4312f9](https://github.com/vuejs/core/commit/c4312f9c715c131a09e552ba46e9beb4b36d55e6)) * **runtime-dom:** set css vars on update to handle child forcing reflow in onMount ([#11561](https://github.com/vuejs/core/issues/11561)) ([c4312f9](https://github.com/vuejs/core/commit/c4312f9c715c131a09e552ba46e9beb4b36d55e6))

View File

@ -35,6 +35,7 @@ Please make sure to respect issue requirements and use [the new issue helper](ht
## Stay In Touch ## Stay In Touch
- [X](https://x.com/vuejs) - [X](https://x.com/vuejs)
- [Bluesky](https://bsky.app/profile/vuejs.org)
- [Blog](https://blog.vuejs.org/) - [Blog](https://blog.vuejs.org/)
- [Job Board](https://vuejobs.com/?ref=vuejs) - [Job Board](https://vuejobs.com/?ref=vuejs)

View File

@ -1,7 +1,7 @@
{ {
"private": true, "private": true,
"version": "3.5.13", "version": "3.5.14",
"packageManager": "pnpm@10.7.0", "packageManager": "pnpm@10.9.0",
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "node scripts/dev.js", "dev": "node scripts/dev.js",
@ -69,24 +69,24 @@
"@rollup/plugin-json": "^6.1.0", "@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^16.0.1", "@rollup/plugin-node-resolve": "^16.0.1",
"@rollup/plugin-replace": "5.0.4", "@rollup/plugin-replace": "5.0.4",
"@swc/core": "^1.11.13", "@swc/core": "^1.11.24",
"@types/hash-sum": "^1.0.2", "@types/hash-sum": "^1.0.2",
"@types/node": "^22.13.14", "@types/node": "^22.14.1",
"@types/semver": "^7.7.0", "@types/semver": "^7.7.0",
"@types/serve-handler": "^6.1.4", "@types/serve-handler": "^6.1.4",
"@vitest/ui": "^3.0.2", "@vitest/ui": "^3.0.2",
"@vitest/coverage-v8": "^3.0.9", "@vitest/coverage-v8": "^3.1.3",
"@vitest/eslint-plugin": "^1.1.38", "@vitest/eslint-plugin": "^1.1.44",
"@vue/consolidate": "1.0.0", "@vue/consolidate": "1.0.0",
"conventional-changelog-cli": "^5.0.0", "conventional-changelog-cli": "^5.0.0",
"enquirer": "^2.4.1", "enquirer": "^2.4.1",
"esbuild": "^0.25.2", "esbuild": "^0.25.4",
"esbuild-plugin-polyfill-node": "^0.3.0", "esbuild-plugin-polyfill-node": "^0.3.0",
"eslint": "^9.23.0", "eslint": "^9.25.1",
"eslint-plugin-import-x": "^4.9.4", "eslint-plugin-import-x": "^4.11.0",
"estree-walker": "catalog:", "estree-walker": "catalog:",
"jsdom": "^26.0.0", "jsdom": "^26.1.0",
"lint-staged": "^15.5.0", "lint-staged": "^15.5.1",
"lodash": "^4.17.21", "lodash": "^4.17.21",
"magic-string": "^0.30.17", "magic-string": "^0.30.17",
"markdown-table": "^3.0.4", "markdown-table": "^3.0.4",
@ -96,38 +96,21 @@
"prettier": "^3.5.3", "prettier": "^3.5.3",
"pretty-bytes": "^6.1.1", "pretty-bytes": "^6.1.1",
"pug": "^3.0.3", "pug": "^3.0.3",
"puppeteer": "~24.4.0", "puppeteer": "~24.8.2",
"rimraf": "^6.0.1", "rimraf": "^6.0.1",
"rollup": "^4.38.0", "rollup": "^4.40.2",
"rollup-plugin-dts": "^6.2.1", "rollup-plugin-dts": "^6.2.1",
"rollup-plugin-esbuild": "^6.2.1", "rollup-plugin-esbuild": "^6.2.1",
"rollup-plugin-polyfill-node": "^0.13.0", "rollup-plugin-polyfill-node": "^0.13.0",
"semver": "^7.7.1", "semver": "^7.7.1",
"serve": "^14.2.4", "serve": "^14.2.4",
"serve-handler": "^6.1.6", "serve-handler": "^6.1.6",
"simple-git-hooks": "^2.12.1", "simple-git-hooks": "^2.13.0",
"todomvc-app-css": "^2.4.3", "todomvc-app-css": "^2.4.3",
"tslib": "^2.8.1", "tslib": "^2.8.1",
"typescript": "~5.6.2", "typescript": "~5.6.2",
"typescript-eslint": "^8.28.0", "typescript-eslint": "^8.31.1",
"vite": "catalog:", "vite": "catalog:",
"vitest": "^3.0.9" "vitest": "^3.1.3"
},
"pnpm": {
"peerDependencyRules": {
"allowedVersions": {
"typescript-eslint>eslint": "^9.0.0",
"@typescript-eslint/eslint-plugin>eslint": "^9.0.0",
"@typescript-eslint/parser>eslint": "^9.0.0",
"@typescript-eslint/type-utils>eslint": "^9.0.0",
"@typescript-eslint/utils>eslint": "^9.0.0"
}
},
"onlyBuiltDependencies": [
"@swc/core",
"esbuild",
"puppeteer",
"simple-git-hooks"
]
} }
} }

View File

@ -11,7 +11,7 @@
"vue": "latest" "vue": "latest"
}, },
"devDependencies": { "devDependencies": {
"@vitejs/plugin-vue": "^5.2.3", "@vitejs/plugin-vue": "^5.2.4",
"vite": "^6.2.3" "vite": "^6.3.5"
} }
} }

View File

@ -170,6 +170,11 @@ describe('compiler: cacheStatic transform', () => {
{ {
/* _ slot flag */ /* _ slot flag */
}, },
{
type: NodeTypes.JS_PROPERTY,
key: { content: '__' },
value: { content: '[0]' },
},
], ],
}) })
}) })
@ -197,6 +202,11 @@ describe('compiler: cacheStatic transform', () => {
{ {
/* _ slot flag */ /* _ slot flag */
}, },
{
type: NodeTypes.JS_PROPERTY,
key: { content: '__' },
value: { content: '[0]' },
},
], ],
}) })
}) })

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/compiler-core", "name": "@vue/compiler-core",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/compiler-core", "description": "@vue/compiler-core",
"main": "index.js", "main": "index.js",
"module": "dist/compiler-core.esm-bundler.js", "module": "dist/compiler-core.esm-bundler.js",

View File

@ -12,11 +12,14 @@ import {
type RootNode, type RootNode,
type SimpleExpressionNode, type SimpleExpressionNode,
type SlotFunctionExpression, type SlotFunctionExpression,
type SlotsObjectProperty,
type TemplateChildNode, type TemplateChildNode,
type TemplateNode, type TemplateNode,
type TextCallNode, type TextCallNode,
type VNodeCall, type VNodeCall,
createArrayExpression, createArrayExpression,
createObjectProperty,
createSimpleExpression,
getVNodeBlockHelper, getVNodeBlockHelper,
getVNodeHelper, getVNodeHelper,
} from '../ast' } from '../ast'
@ -140,6 +143,7 @@ function walk(
} }
let cachedAsArray = false let cachedAsArray = false
const slotCacheKeys = []
if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) { if (toCache.length === children.length && node.type === NodeTypes.ELEMENT) {
if ( if (
node.tagType === ElementTypes.ELEMENT && node.tagType === ElementTypes.ELEMENT &&
@ -163,6 +167,7 @@ function walk(
// default slot // default slot
const slot = getSlotNode(node.codegenNode, 'default') const slot = getSlotNode(node.codegenNode, 'default')
if (slot) { if (slot) {
slotCacheKeys.push(context.cached.length)
slot.returns = getCacheExpression( slot.returns = getCacheExpression(
createArrayExpression(slot.returns as TemplateChildNode[]), createArrayExpression(slot.returns as TemplateChildNode[]),
) )
@ -186,6 +191,7 @@ function walk(
slotName.arg && slotName.arg &&
getSlotNode(parent.codegenNode, slotName.arg) getSlotNode(parent.codegenNode, slotName.arg)
if (slot) { if (slot) {
slotCacheKeys.push(context.cached.length)
slot.returns = getCacheExpression( slot.returns = getCacheExpression(
createArrayExpression(slot.returns as TemplateChildNode[]), createArrayExpression(slot.returns as TemplateChildNode[]),
) )
@ -196,10 +202,31 @@ function walk(
if (!cachedAsArray) { if (!cachedAsArray) {
for (const child of toCache) { for (const child of toCache) {
slotCacheKeys.push(context.cached.length)
child.codegenNode = context.cache(child.codegenNode!) child.codegenNode = context.cache(child.codegenNode!)
} }
} }
// put the slot cached keys on the slot object, so that the cache
// can be removed when component unmounting to prevent memory leaks
if (
slotCacheKeys.length &&
node.type === NodeTypes.ELEMENT &&
node.tagType === ElementTypes.COMPONENT &&
node.codegenNode &&
node.codegenNode.type === NodeTypes.VNODE_CALL &&
node.codegenNode.children &&
!isArray(node.codegenNode.children) &&
node.codegenNode.children.type === NodeTypes.JS_OBJECT_EXPRESSION
) {
node.codegenNode.children.properties.push(
createObjectProperty(
`__`,
createSimpleExpression(JSON.stringify(slotCacheKeys), false),
) as SlotsObjectProperty,
)
}
function getCacheExpression(value: JSChildNode): CacheExpression { function getCacheExpression(value: JSChildNode): CacheExpression {
const exp = context.cache(value) const exp = context.cache(value)
// #6978, #7138, #7114 // #6978, #7138, #7114

View File

@ -342,7 +342,6 @@ export function buildSlots(
: hasForwardedSlots(node.children) : hasForwardedSlots(node.children)
? SlotFlags.FORWARDED ? SlotFlags.FORWARDED
: SlotFlags.STABLE : SlotFlags.STABLE
let slots = createObjectExpression( let slots = createObjectExpression(
slotsProperties.concat( slotsProperties.concat(
createObjectProperty( createObjectProperty(

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/compiler-dom", "name": "@vue/compiler-dom",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/compiler-dom", "description": "@vue/compiler-dom",
"main": "index.js", "main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js", "module": "dist/compiler-dom.esm-bundler.js",

View File

@ -196,6 +196,25 @@ return () => {}
}" }"
`; `;
exports[`sfc reactive props destructure > handle function parameters with same name as destructured props 1`] = `
"
export default {
setup(__props) {
function test(value) {
try {
} catch {
}
}
console.log(__props.value)
return () => {}
}
}"
`;
exports[`sfc reactive props destructure > multi-variable declaration 1`] = ` exports[`sfc reactive props destructure > multi-variable declaration 1`] = `
" "
export default { export default {

View File

@ -360,6 +360,22 @@ describe('sfc reactive props destructure', () => {
expect(content).toMatch(`props: ['item'],`) expect(content).toMatch(`props: ['item'],`)
}) })
test('handle function parameters with same name as destructured props', () => {
const { content } = compile(`
<script setup>
const { value } = defineProps()
function test(value) {
try {
} catch {
}
}
console.log(value)
</script>
`)
assertCode(content)
expect(content).toMatch(`console.log(__props.value)`)
})
test('defineProps/defineEmits in multi-variable declaration (full removal)', () => { test('defineProps/defineEmits in multi-variable declaration (full removal)', () => {
const { content } = compile(` const { content } = compile(`
<script setup> <script setup>

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/compiler-sfc", "name": "@vue/compiler-sfc",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/compiler-sfc", "description": "@vue/compiler-sfc",
"main": "dist/compiler-sfc.cjs.js", "main": "dist/compiler-sfc.cjs.js",
"module": "dist/compiler-sfc.esm-browser.js", "module": "dist/compiler-sfc.esm-browser.js",
@ -63,6 +63,6 @@
"postcss-modules": "^6.0.1", "postcss-modules": "^6.0.1",
"postcss-selector-parser": "^7.1.0", "postcss-selector-parser": "^7.1.0",
"pug": "^3.0.3", "pug": "^3.0.3",
"sass": "^1.86.0" "sass": "^1.86.3"
} }
} }

View File

@ -1120,6 +1120,7 @@ function walkDeclaration(
m === userImportAliases['shallowRef'] || m === userImportAliases['shallowRef'] ||
m === userImportAliases['customRef'] || m === userImportAliases['customRef'] ||
m === userImportAliases['toRef'] || m === userImportAliases['toRef'] ||
m === userImportAliases['useTemplateRef'] ||
m === DEFINE_MODEL, m === DEFINE_MODEL,
) )
) { ) {

View File

@ -291,7 +291,8 @@ export function transformDestructuredProps(
parent && parentStack.pop() parent && parentStack.pop()
if ( if (
(node.type === 'BlockStatement' && !isFunctionType(parent!)) || (node.type === 'BlockStatement' && !isFunctionType(parent!)) ||
isFunctionType(node) isFunctionType(node) ||
node.type === 'CatchClause'
) { ) {
popScope() popScope()
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/compiler-ssr", "name": "@vue/compiler-ssr",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/compiler-ssr", "description": "@vue/compiler-ssr",
"main": "dist/compiler-ssr.cjs.js", "main": "dist/compiler-ssr.cjs.js",
"types": "dist/compiler-ssr.d.ts", "types": "dist/compiler-ssr.d.ts",

View File

@ -1017,6 +1017,17 @@ describe('reactivity/computed', () => {
expect(cValue.value).toBe(1) expect(cValue.value).toBe(1)
}) })
test('should not recompute if computed does not track reactive data', async () => {
const spy = vi.fn()
const c1 = computed(() => spy())
c1.value
ref(0).value++ // update globalVersion
c1.value
expect(spy).toBeCalledTimes(1)
})
test('computed should remain live after losing all subscribers', () => { test('computed should remain live after losing all subscribers', () => {
const state = reactive({ a: 1 }) const state = reactive({ a: 1 })
const p = computed(() => state.a + 1) const p = computed(() => state.a + 1)

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/reactivity", "name": "@vue/reactivity",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/reactivity", "description": "@vue/reactivity",
"main": "index.js", "main": "index.js",
"module": "dist/reactivity.esm-bundler.js", "module": "dist/reactivity.esm-bundler.js",

View File

@ -324,4 +324,98 @@ describe('component: slots', () => {
'Slot "default" invoked outside of the render function', 'Slot "default" invoked outside of the render function',
).not.toHaveBeenWarned() ).not.toHaveBeenWarned()
}) })
test('basic warn', () => {
const Comp = {
setup(_: any, { slots }: any) {
slots.default && slots.default()
return () => null
},
}
const App = {
setup() {
return () => h(Comp, () => h('div'))
},
}
createApp(App).mount(nodeOps.createElement('div'))
expect(
'Slot "default" invoked outside of the render function',
).toHaveBeenWarned()
})
test('basic warn when mounting another app in setup', () => {
const Comp = {
setup(_: any, { slots }: any) {
slots.default?.()
return () => null
},
}
const mountComp = () => {
createApp({
setup() {
return () => h(Comp, () => 'msg')
},
}).mount(nodeOps.createElement('div'))
}
const App = {
setup() {
mountComp()
return () => null
},
}
createApp(App).mount(nodeOps.createElement('div'))
expect(
'Slot "default" invoked outside of the render function',
).toHaveBeenWarned()
})
test('should not warn when render in setup', () => {
const container = {
setup(_: any, { slots }: any) {
return () => slots.default && slots.default()
},
}
const comp = h(container, null, () => h('div'))
const App = {
setup() {
render(h(comp), nodeOps.createElement('div'))
return () => null
},
}
createApp(App).mount(nodeOps.createElement('div'))
expect(
'Slot "default" invoked outside of the render function',
).not.toHaveBeenWarned()
})
test('basic warn when render in setup', () => {
const container = {
setup(_: any, { slots }: any) {
slots.default && slots.default()
return () => null
},
}
const comp = h(container, null, () => h('div'))
const App = {
setup() {
render(h(comp), nodeOps.createElement('div'))
return () => null
},
}
createApp(App).mount(nodeOps.createElement('div'))
expect(
'Slot "default" invoked outside of the render function',
).toHaveBeenWarned()
})
}) })

View File

@ -1198,4 +1198,51 @@ describe('BaseTransition', () => {
test('should not error on KeepAlive w/ function children', () => { test('should not error on KeepAlive w/ function children', () => {
expect(() => mount({}, () => () => h('div'), true)).not.toThrow() expect(() => mount({}, () => () => h('div'), true)).not.toThrow()
}) })
// #12465
test('mode: "out-in" w/ KeepAlive + fallthrough attrs (prod mode)', async () => {
__DEV__ = false
async function testOutIn({ trueBranch, falseBranch }: ToggleOptions) {
const toggle = ref(true)
const { props, cbs } = mockProps({ mode: 'out-in' }, true)
const root = nodeOps.createElement('div')
const App = {
render() {
return h(
BaseTransition,
{
...props,
class: 'test',
},
() =>
h(KeepAlive, null, toggle.value ? trueBranch() : falseBranch()),
)
},
}
render(h(App), root)
expect(serializeInner(root)).toBe(`<div class="test">0</div>`)
// trigger toggle
toggle.value = false
await nextTick()
expect(props.onBeforeLeave).toHaveBeenCalledTimes(1)
expect(serialize((props.onBeforeLeave as any).mock.calls[0][0])).toBe(
`<div class="test">0</div>`,
)
expect(props.onLeave).toHaveBeenCalledTimes(1)
expect(serialize((props.onLeave as any).mock.calls[0][0])).toBe(
`<div class="test">0</div>`,
)
expect(props.onAfterLeave).not.toHaveBeenCalled()
// enter should not have started
expect(props.onBeforeEnter).not.toHaveBeenCalled()
expect(props.onEnter).not.toHaveBeenCalled()
expect(props.onAfterEnter).not.toHaveBeenCalled()
cbs.doneLeave[`<div class="test">0</div>`]()
expect(serializeInner(root)).toBe(`<span class="test">0</span>`)
}
await runTestWithKeepAlive(testOutIn)
__DEV__ = true
})
}) })

View File

@ -10,14 +10,28 @@ import {
markRaw, markRaw,
nextTick, nextTick,
nodeOps, nodeOps,
onMounted,
h as originalH, h as originalH,
ref, ref,
render, render,
serialize,
serializeInner, serializeInner,
withDirectives, withDirectives,
} from '@vue/runtime-test' } from '@vue/runtime-test'
import { Fragment, createCommentVNode, createVNode } from '../../src/vnode' import {
Fragment,
createBlock,
createCommentVNode,
createTextVNode,
createVNode,
openBlock,
} from '../../src/vnode'
import { toDisplayString } from '@vue/shared'
import { compile, createApp as createDOMApp, render as domRender } from 'vue' import { compile, createApp as createDOMApp, render as domRender } from 'vue'
import type { HMRRuntime } from '../../src/hmr'
declare var __VUE_HMR_RUNTIME__: HMRRuntime
const { rerender, createRecord } = __VUE_HMR_RUNTIME__
describe('renderer: teleport', () => { describe('renderer: teleport', () => {
describe('eager mode', () => { describe('eager mode', () => {
@ -243,6 +257,39 @@ describe('renderer: teleport', () => {
expect(serializeInner(target)).toBe(`teleported`) expect(serializeInner(target)).toBe(`teleported`)
}) })
test('should traverse comment node after updating in optimize mode', async () => {
const target = nodeOps.createElement('div')
const root = nodeOps.createElement('div')
const count = ref(0)
let teleport
__DEV__ = false
render(
h(() => {
teleport =
(openBlock(),
createBlock(Teleport, { to: target }, [
createCommentVNode('comment in teleport'),
]))
return h('div', null, [
createTextVNode(toDisplayString(count.value)),
teleport,
])
}),
root,
)
const commentNode = teleport!.children[0].el
expect(serializeInner(root)).toBe(`<div>0</div>`)
expect(serializeInner(target)).toBe(`<!--comment in teleport-->`)
expect(serialize(commentNode)).toBe(`<!--comment in teleport-->`)
count.value = 1
await nextTick()
__DEV__ = true
expect(serializeInner(root)).toBe(`<div>1</div>`)
expect(teleport!.children[0].el).toBe(commentNode)
})
test('should remove children when unmounted', () => { test('should remove children when unmounted', () => {
const target = nodeOps.createElement('div') const target = nodeOps.createElement('div')
const root = nodeOps.createElement('div') const root = nodeOps.createElement('div')
@ -269,6 +316,34 @@ describe('renderer: teleport', () => {
testUnmount({ to: null, disabled: true }) testUnmount({ to: null, disabled: true })
}) })
// #10747
test('should unmount correctly when using top level comment in teleport', async () => {
const target = nodeOps.createElement('div')
const root = nodeOps.createElement('div')
const count = ref(0)
__DEV__ = false
render(
h(() => {
return h('div', null, [
createTextVNode(toDisplayString(count.value)),
(openBlock(),
createBlock(Teleport, { to: target }, [
createCommentVNode('comment in teleport'),
])),
])
}),
root,
)
count.value = 1
await nextTick()
__DEV__ = true
render(null, root)
expect(root.children.length).toBe(0)
})
test('component with multi roots should be removed when unmounted', () => { test('component with multi roots should be removed when unmounted', () => {
const target = nodeOps.createElement('div') const target = nodeOps.createElement('div')
const root = nodeOps.createElement('div') const root = nodeOps.createElement('div')
@ -741,4 +816,56 @@ describe('renderer: teleport', () => {
expect(tRefInMounted).toBe(target.children[1]) expect(tRefInMounted).toBe(target.children[1])
}) })
} }
test('handle update and hmr rerender', async () => {
const target = document.createElement('div')
const root = document.createElement('div')
const Comp = {
setup() {
const cls = ref('foo')
onMounted(() => {
// trigger update
cls.value = 'bar'
})
return { cls, target }
},
template: `
<Teleport :to="target">
<div :class="cls">
<div>
<slot></slot>
</div>
</div>
</Teleport>
`,
}
const appId = 'test-app-id'
const App = {
__hmrId: appId,
components: { Comp },
render() {
return originalH(Comp, null, { default: () => originalH('div', 'foo') })
},
}
createRecord(appId, App)
domRender(originalH(App), root)
expect(target.innerHTML).toBe(
'<div class="foo"><div><div>foo</div></div></div>',
)
await nextTick()
expect(target.innerHTML).toBe(
'<div class="bar"><div><div>foo</div></div></div>',
)
rerender(appId, () =>
originalH(Comp, null, { default: () => originalH('div', 'bar') }),
)
await nextTick()
expect(target.innerHTML).toBe(
'<div class="bar"><div><div>bar</div></div></div>',
)
})
}) })

View File

@ -1,4 +1,10 @@
import { isReactive, reactive, shallowReactive } from '../../src/index' import {
effect,
isReactive,
reactive,
readonly,
shallowReactive,
} from '../../src/index'
import { renderList } from '../../src/helpers/renderList' import { renderList } from '../../src/helpers/renderList'
describe('renderList', () => { describe('renderList', () => {
@ -65,4 +71,31 @@ describe('renderList', () => {
const shallowReactiveArray = shallowReactive([{ foo: 1 }]) const shallowReactiveArray = shallowReactive([{ foo: 1 }])
expect(renderList(shallowReactiveArray, isReactive)).toEqual([false]) expect(renderList(shallowReactiveArray, isReactive)).toEqual([false])
}) })
it('should not allow mutation', () => {
const arr = readonly(reactive([{ foo: 1 }]))
expect(
renderList(arr, item => {
;(item as any).foo = 0
return item.foo
}),
).toEqual([1])
expect(
`Set operation on key "foo" failed: target is readonly.`,
).toHaveBeenWarned()
})
it('should trigger effect for deep mutations in readonly reactive arrays', () => {
const arr = reactive([{ foo: 1 }])
const readonlyArr = readonly(arr)
let dummy
effect(() => {
dummy = renderList(readonlyArr, item => item.foo)
})
expect(dummy).toEqual([1])
arr[0].foo = 2
expect(dummy).toEqual([2])
})
}) })

View File

@ -32,10 +32,13 @@ import {
withCtx, withCtx,
withDirectives, withDirectives,
} from '@vue/runtime-dom' } from '@vue/runtime-dom'
import type { HMRRuntime } from '../src/hmr'
import { type SSRContext, renderToString } from '@vue/server-renderer' import { type SSRContext, renderToString } from '@vue/server-renderer'
import { PatchFlags, normalizeStyle } from '@vue/shared' import { PatchFlags, normalizeStyle } from '@vue/shared'
import { vShowOriginalDisplay } from '../../runtime-dom/src/directives/vShow' import { vShowOriginalDisplay } from '../../runtime-dom/src/directives/vShow'
import { expect } from 'vitest'
declare var __VUE_HMR_RUNTIME__: HMRRuntime
const { createRecord, reload } = __VUE_HMR_RUNTIME__
function mountWithHydration(html: string, render: () => any) { function mountWithHydration(html: string, render: () => any) {
const container = document.createElement('div') const container = document.createElement('div')
@ -1843,6 +1846,60 @@ describe('SSR hydration', () => {
} }
}) })
test('hmr reload child wrapped in KeepAlive', async () => {
const id = 'child-reload'
const Child = {
__hmrId: id,
template: `<div>foo</div>`,
}
createRecord(id, Child)
const appId = 'test-app-id'
const App = {
__hmrId: appId,
components: { Child },
template: `
<div>
<KeepAlive>
<Child />
</KeepAlive>
</div>
`,
}
const root = document.createElement('div')
root.innerHTML = await renderToString(h(App))
createSSRApp(App).mount(root)
expect(root.innerHTML).toBe('<div><div>foo</div></div>')
reload(id, {
__hmrId: id,
template: `<div>bar</div>`,
})
await nextTick()
expect(root.innerHTML).toBe('<div><div>bar</div></div>')
})
test('hmr root reload', async () => {
const appId = 'test-app-id'
const App = {
__hmrId: appId,
template: `<div>foo</div>`,
}
const root = document.createElement('div')
root.innerHTML = await renderToString(h(App))
createSSRApp(App).mount(root)
expect(root.innerHTML).toBe('<div>foo</div>')
reload(appId, {
__hmrId: appId,
template: `<div>bar</div>`,
})
await nextTick()
expect(root.innerHTML).toBe('<div>bar</div>')
})
describe('mismatch handling', () => { describe('mismatch handling', () => {
test('text node', () => { test('text node', () => {
const { container } = mountWithHydration(`foo`, () => 'bar') const { container } = mountWithHydration(`foo`, () => 'bar')

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/runtime-core", "name": "@vue/runtime-core",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/runtime-core", "description": "@vue/runtime-core",
"main": "index.js", "main": "index.js",
"module": "dist/runtime-core.esm-bundler.js", "module": "dist/runtime-core.esm-bundler.js",

View File

@ -837,7 +837,7 @@ export function setupComponent(
vi(instance) vi(instance)
} else { } else {
initProps(instance, props, isStateful, isSSR) initProps(instance, props, isStateful, isSSR)
initSlots(instance, children, optimized) initSlots(instance, children, optimized || isSSR)
} }
const setupResult = isStateful const setupResult = isStateful

View File

@ -17,7 +17,11 @@ import {
} from '@vue/shared' } from '@vue/shared'
import { warn } from './warning' import { warn } from './warning'
import { isKeepAlive } from './components/KeepAlive' import { isKeepAlive } from './components/KeepAlive'
import { type ContextualRenderFn, withCtx } from './componentRenderContext' import {
type ContextualRenderFn,
currentRenderingInstance,
withCtx,
} from './componentRenderContext'
import { isHmrUpdating } from './hmr' import { isHmrUpdating } from './hmr'
import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig' import { DeprecationTypes, isCompatEnabled } from './compat/compatConfig'
import { TriggerOpTypes, trigger } from '@vue/reactivity' import { TriggerOpTypes, trigger } from '@vue/reactivity'
@ -75,6 +79,11 @@ export type RawSlots = {
* @internal * @internal
*/ */
_?: SlotFlags _?: SlotFlags
/**
* cache indexes for slot content
* @internal
*/
__?: number[]
} }
const isInternalKey = (key: string) => key[0] === '_' || key === '$stable' const isInternalKey = (key: string) => key[0] === '_' || key === '$stable'
@ -98,7 +107,8 @@ const normalizeSlot = (
__DEV__ && __DEV__ &&
currentInstance && currentInstance &&
!currentInstance.vapor && !currentInstance.vapor &&
(!ctx || ctx.root === (currentInstance as ComponentInternalInstance).root) !(ctx === null && currentRenderingInstance) &&
!(ctx && ctx.root !== currentInstance.root)
) { ) {
warn( warn(
`Slot "${key}" invoked outside of the render function: ` + `Slot "${key}" invoked outside of the render function: ` +
@ -171,7 +181,7 @@ const assignSlots = (
// when rendering the optimized slots by manually written render function, // when rendering the optimized slots by manually written render function,
// do not copy the `slots._` compiler flag so that `renderSlot` creates // do not copy the `slots._` compiler flag so that `renderSlot` creates
// slot Fragment with BAIL patchFlag to force full updates // slot Fragment with BAIL patchFlag to force full updates
if (optimized || key !== '_') { if (optimized || !isInternalKey(key)) {
slots[key] = children[key] slots[key] = children[key]
} }
} }

View File

@ -501,9 +501,8 @@ function getInnerChild(vnode: VNode): VNode | undefined {
return vnode return vnode
} }
// #7121 ensure get the child component subtree in case // #7121,#12465 get the component subtree if it's been mounted
// it's been replaced during HMR if (vnode.component) {
if (__DEV__ && vnode.component) {
return vnode.component.subTree return vnode.component.subTree
} }

View File

@ -220,7 +220,8 @@ export const TeleportImpl = {
// even in block tree mode we need to make sure all root-level nodes // even in block tree mode we need to make sure all root-level nodes
// in the teleport inherit previous DOM references so that they can // in the teleport inherit previous DOM references so that they can
// be moved in future patches. // be moved in future patches.
traverseStaticChildren(n1, n2, true) // in dev mode, deep traversal is necessary for HMR
traverseStaticChildren(n1, n2, !__DEV__)
} else if (!optimized) { } else if (!optimized) {
patchChildren( patchChildren(
n1, n1,

View File

@ -1,9 +1,11 @@
import type { VNode, VNodeChild } from '../vnode' import type { VNode, VNodeChild } from '../vnode'
import { import {
isReactive, isReactive,
isReadonly,
isShallow, isShallow,
shallowReadArray, shallowReadArray,
toReactive, toReactive,
toReadonly,
} from '@vue/reactivity' } from '@vue/reactivity'
import { isArray, isObject, isString } from '@vue/shared' import { isArray, isObject, isString } from '@vue/shared'
import { warn } from '../warning' import { warn } from '../warning'
@ -69,14 +71,20 @@ export function renderList(
if (sourceIsArray || isString(source)) { if (sourceIsArray || isString(source)) {
const sourceIsReactiveArray = sourceIsArray && isReactive(source) const sourceIsReactiveArray = sourceIsArray && isReactive(source)
let needsWrap = false let needsWrap = false
let isReadonlySource = false
if (sourceIsReactiveArray) { if (sourceIsReactiveArray) {
needsWrap = !isShallow(source) needsWrap = !isShallow(source)
isReadonlySource = isReadonly(source)
source = shallowReadArray(source) source = shallowReadArray(source)
} }
ret = new Array(source.length) ret = new Array(source.length)
for (let i = 0, l = source.length; i < l; i++) { for (let i = 0, l = source.length; i < l; i++) {
ret[i] = renderItem( ret[i] = renderItem(
needsWrap ? toReactive(source[i]) : source[i], needsWrap
? isReadonlySource
? toReadonly(toReactive(source[i]))
: toReactive(source[i])
: source[i],
i, i,
undefined, undefined,
cached && cached[i], cached && cached[i],

View File

@ -1248,12 +1248,12 @@ function baseCreateRenderer(
} }
} }
// avoid hydration for hmr updating
if (__DEV__ && isHmrUpdating) initialVNode.el = null
// setup() is async. This component relies on async logic to be resolved // setup() is async. This component relies on async logic to be resolved
// before proceeding // before proceeding
if (__FEATURE_SUSPENSE__ && instance.asyncDep) { if (__FEATURE_SUSPENSE__ && instance.asyncDep) {
// avoid hydration for hmr updating
if (__DEV__ && isHmrUpdating) initialVNode.el = null
parentSuspense && parentSuspense &&
parentSuspense.registerDep(instance, setupRenderEffect, optimized) parentSuspense.registerDep(instance, setupRenderEffect, optimized)
@ -2169,7 +2169,9 @@ function baseCreateRenderer(
// unset ref // unset ref
if (ref != null) { if (ref != null) {
pauseTracking()
setRef(ref, null, parentSuspense, vnode, true) setRef(ref, null, parentSuspense, vnode, true)
resetTracking()
} }
// #6593 should clean memo cache when unmount // #6593 should clean memo cache when unmount
@ -2343,7 +2345,17 @@ function baseCreateRenderer(
unregisterHMR(instance) unregisterHMR(instance)
} }
const { bum, scope, job, subTree, um, m, a } = instance const {
bum,
scope,
job,
subTree,
um,
m,
a,
parent,
slots: { __: slotCacheKeys },
} = instance
invalidateMount(m) invalidateMount(m)
invalidateMount(a) invalidateMount(a)
@ -2352,6 +2364,13 @@ function baseCreateRenderer(
invokeArrayFns(bum) invokeArrayFns(bum)
} }
// remove slots content from parent renderCache
if (parent && isArray(slotCacheKeys)) {
slotCacheKeys.forEach(v => {
;(parent as ComponentInternalInstance).renderCache[v] = undefined
})
}
if ( if (
__COMPAT__ && __COMPAT__ &&
isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance) isCompatEnabled(DeprecationTypes.INSTANCE_EVENT_HOOKS, instance)
@ -2502,9 +2521,12 @@ function baseCreateRenderer(
// HMR root reload // HMR root reload
if (__DEV__) { if (__DEV__) {
app._context.reload = () => { app._context.reload = () => {
const cloned = cloneVNode(vnode)
// avoid hydration for hmr updating
cloned.el = null
// casting to ElementNamespace because TS doesn't guarantee type narrowing // casting to ElementNamespace because TS doesn't guarantee type narrowing
// over function boundaries // over function boundaries
render(cloneVNode(vnode), container, namespace as ElementNamespace) render(cloned, container, namespace as ElementNamespace)
} }
} }
@ -2610,11 +2632,15 @@ export function traverseStaticChildren(
if (c2.type === Text) { if (c2.type === Text) {
c2.el = c1.el c2.el = c1.el
} }
// also inherit for comment nodes, but not placeholders (e.g. v-if which // #2324 also inherit for comment nodes, but not placeholders (e.g. v-if which
// would have received .el during block patch) // would have received .el during block patch)
if (__DEV__ && c2.type === Comment && !c2.el) { if (c2.type === Comment && !c2.el) {
c2.el = c1.el c2.el = c1.el
} }
if (__DEV__) {
c2.el && (c2.el.__vnode = c2)
}
} }
} }
} }

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/runtime-dom", "name": "@vue/runtime-dom",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/runtime-dom", "description": "@vue/runtime-dom",
"main": "index.js", "main": "index.js",
"module": "dist/runtime-dom.esm-bundler.js", "module": "dist/runtime-dom.esm-bundler.js",

View File

@ -82,6 +82,7 @@ const TransitionGroupImpl: ComponentOptions = /*@__PURE__*/ decorate({
moveClass, moveClass,
) )
) { ) {
prevChildren = []
return return
} }
@ -111,6 +112,7 @@ const TransitionGroupImpl: ComponentOptions = /*@__PURE__*/ decorate({
}) })
el.addEventListener('transitionend', cb) el.addEventListener('transitionend', cb)
}) })
prevChildren = []
}) })
return () => { return () => {

View File

@ -1,4 +1,4 @@
import { createApp } from 'vue' import { createApp, defineAsyncComponent, h } from 'vue'
import { renderToString } from '../src/renderToString' import { renderToString } from '../src/renderToString'
const components = { const components = {
@ -154,6 +154,38 @@ describe('ssr: slot', () => {
).toBe(`<div><p>1</p><p>2</p></div>`) ).toBe(`<div><p>1</p><p>2</p></div>`)
}) })
// #12438
test('async component slot with v-if true', async () => {
const Layout = defineAsyncComponent(() =>
Promise.resolve({
template: `<div><slot name="header">default header</slot></div>`,
}),
)
const LayoutLoader = {
setup(_: any, context: any) {
return () => h(Layout, {}, context.slots)
},
}
expect(
await renderToString(
createApp({
components: {
LayoutLoader,
},
template: `
<Suspense>
<LayoutLoader>
<template v-if="true" #header>
new header
</template>
</LayoutLoader>
</Suspense>
`,
}),
),
).toBe(`<div><!--[--> new header <!--]--></div>`)
})
// #11326 // #11326
test('dynamic component slot', async () => { test('dynamic component slot', async () => {
expect( expect(

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/server-renderer", "name": "@vue/server-renderer",
"version": "3.5.13", "version": "3.5.14",
"description": "@vue/server-renderer", "description": "@vue/server-renderer",
"main": "index.js", "main": "index.js",
"module": "dist/server-renderer.esm-bundler.js", "module": "dist/server-renderer.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/shared", "name": "@vue/shared",
"version": "3.5.13", "version": "3.5.14",
"description": "internal utils shared across @vue packages", "description": "internal utils shared across @vue packages",
"main": "index.js", "main": "index.js",
"module": "dist/shared.esm-bundler.js", "module": "dist/shared.esm-bundler.js",

View File

@ -1,6 +1,6 @@
{ {
"name": "@vue/compat", "name": "@vue/compat",
"version": "3.5.13", "version": "3.5.14",
"description": "Vue 3 compatibility build for Vue 2", "description": "Vue 3 compatibility build for Vue 2",
"main": "index.js", "main": "index.js",
"module": "dist/vue.runtime.esm-bundler.js", "module": "dist/vue.runtime.esm-bundler.js",

View File

@ -647,4 +647,55 @@ describe('e2e: TransitionGroup', () => {
}, },
E2E_TIMEOUT, E2E_TIMEOUT,
) )
test(
'not leaking after children unmounted',
async () => {
const client = await page().createCDPSession()
await page().evaluate(async () => {
const { createApp, ref, nextTick } = (window as any).Vue
const show = ref(true)
createApp({
components: {
Child: {
setup: () => {
// Big arrays kick GC earlier
const test = ref([...Array(3000)].map((_, i) => ({ i })))
// @ts-expect-error - Custom property and same lib as runtime is used
window.__REF__ = new WeakRef(test)
return { test }
},
template: `
<p>{{ test.length }}</p>
`,
},
},
template: `
<transition-group>
<Child v-if="show" />
</transition-group>
`,
setup() {
return { show }
},
}).mount('#app')
show.value = false
await nextTick()
})
const isCollected = async () =>
// @ts-expect-error - Custom property
await page().evaluate(() => window.__REF__.deref() === undefined)
while ((await isCollected()) === false) {
await client.send('HeapProfiler.collectGarbage')
}
expect(await isCollected()).toBe(true)
},
E2E_TIMEOUT,
)
}) })

View File

@ -1,6 +1,6 @@
{ {
"name": "vue", "name": "vue",
"version": "3.5.13", "version": "3.5.14",
"description": "The progressive JavaScript framework for building modern web UI.", "description": "The progressive JavaScript framework for building modern web UI.",
"main": "index.js", "main": "index.js",
"module": "dist/vue.runtime.esm-bundler.js", "module": "dist/vue.runtime.esm-bundler.js",

View File

@ -7,14 +7,14 @@ settings:
catalogs: catalogs:
default: default:
'@babel/parser': '@babel/parser':
specifier: ^7.27.0 specifier: ^7.27.2
version: 7.27.5 version: 7.27.5
'@babel/types': '@babel/types':
specifier: ^7.27.0 specifier: ^7.27.1
version: 7.27.6 version: 7.27.6
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: https://pkg.pr.new/@vitejs/plugin-vue@c156992 specifier: ^5.2.4
version: 5.2.1 version: 5.2.4
estree-walker: estree-walker:
specifier: ^2.0.2 specifier: ^2.0.2
version: 2.0.2 version: 2.0.2
@ -54,13 +54,13 @@ importers:
specifier: 5.0.4 specifier: 5.0.4
version: 5.0.4(rollup@4.43.0) version: 5.0.4(rollup@4.43.0)
'@swc/core': '@swc/core':
specifier: ^1.11.13 specifier: ^1.11.24
version: 1.12.1 version: 1.12.1
'@types/hash-sum': '@types/hash-sum':
specifier: ^1.0.2 specifier: ^1.0.2
version: 1.0.2 version: 1.0.2
'@types/node': '@types/node':
specifier: ^22.13.14 specifier: ^22.14.1
version: 22.15.32 version: 22.15.32
'@types/semver': '@types/semver':
specifier: ^7.7.0 specifier: ^7.7.0
@ -69,10 +69,10 @@ importers:
specifier: ^6.1.4 specifier: ^6.1.4
version: 6.1.4 version: 6.1.4
'@vitest/coverage-v8': '@vitest/coverage-v8':
specifier: ^3.0.9 specifier: ^3.1.3
version: 3.2.4(vitest@3.2.4) version: 3.2.4(vitest@3.2.4)
'@vitest/eslint-plugin': '@vitest/eslint-plugin':
specifier: ^1.1.38 specifier: ^1.1.44
version: 1.2.7(eslint@9.29.0)(typescript@5.6.3)(vitest@3.2.4) version: 1.2.7(eslint@9.29.0)(typescript@5.6.3)(vitest@3.2.4)
'@vitest/ui': '@vitest/ui':
specifier: ^3.0.2 specifier: ^3.0.2
@ -87,25 +87,25 @@ importers:
specifier: ^2.4.1 specifier: ^2.4.1
version: 2.4.1 version: 2.4.1
esbuild: esbuild:
specifier: ^0.25.2 specifier: ^0.25.4
version: 0.25.5 version: 0.25.5
esbuild-plugin-polyfill-node: esbuild-plugin-polyfill-node:
specifier: ^0.3.0 specifier: ^0.3.0
version: 0.3.0(esbuild@0.25.5) version: 0.3.0(esbuild@0.25.5)
eslint: eslint:
specifier: ^9.23.0 specifier: ^9.25.1
version: 9.29.0 version: 9.29.0
eslint-plugin-import-x: eslint-plugin-import-x:
specifier: ^4.9.4 specifier: ^4.11.0
version: 4.15.2(@typescript-eslint/utils@8.34.1(eslint@9.29.0)(typescript@5.6.3))(eslint@9.29.0) version: 4.15.2(@typescript-eslint/utils@8.34.1(eslint@9.29.0)(typescript@5.6.3))(eslint@9.29.0)
estree-walker: estree-walker:
specifier: 'catalog:' specifier: 'catalog:'
version: 2.0.2 version: 2.0.2
jsdom: jsdom:
specifier: ^26.0.0 specifier: ^26.1.0
version: 26.1.0 version: 26.1.0
lint-staged: lint-staged:
specifier: ^15.5.0 specifier: ^15.5.1
version: 15.5.2 version: 15.5.2
lodash: lodash:
specifier: ^4.17.21 specifier: ^4.17.21
@ -135,13 +135,13 @@ importers:
specifier: ^3.0.3 specifier: ^3.0.3
version: 3.0.3 version: 3.0.3
puppeteer: puppeteer:
specifier: ~24.4.0 specifier: ~24.8.2
version: 24.4.0(typescript@5.6.3) version: 24.8.2(typescript@5.6.3)
rimraf: rimraf:
specifier: ^6.0.1 specifier: ^6.0.1
version: 6.0.1 version: 6.0.1
rollup: rollup:
specifier: ^4.38.0 specifier: ^4.40.2
version: 4.43.0 version: 4.43.0
rollup-plugin-dts: rollup-plugin-dts:
specifier: ^6.2.1 specifier: ^6.2.1
@ -162,7 +162,7 @@ importers:
specifier: ^6.1.6 specifier: ^6.1.6
version: 6.1.6 version: 6.1.6
simple-git-hooks: simple-git-hooks:
specifier: ^2.12.1 specifier: ^2.13.0
version: 2.13.0 version: 2.13.0
todomvc-app-css: todomvc-app-css:
specifier: ^2.4.3 specifier: ^2.4.3
@ -174,20 +174,20 @@ importers:
specifier: ~5.6.2 specifier: ~5.6.2
version: 5.6.3 version: 5.6.3
typescript-eslint: typescript-eslint:
specifier: ^8.28.0 specifier: ^8.31.1
version: 8.34.1(eslint@9.29.0)(typescript@5.6.3) version: 8.34.1(eslint@9.29.0)(typescript@5.6.3)
vite: vite:
specifier: 'catalog:' specifier: 'catalog:'
version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0) version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0)
vitest: vitest:
specifier: ^3.0.9 specifier: ^3.1.3
version: 3.2.4(@types/node@22.15.32)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.89.2)(yaml@2.8.0) version: 3.2.4(@types/node@22.15.32)(@vitest/ui@3.2.4)(jsdom@26.1.0)(sass@1.89.2)(yaml@2.8.0)
packages-private/benchmark: packages-private/benchmark:
dependencies: dependencies:
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 'catalog:' specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@3.5.13(typescript@5.6.3)) version: 5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.6.3))
connect: connect:
specifier: ^3.7.0 specifier: ^3.7.0
version: 3.7.0 version: 3.7.0
@ -234,7 +234,7 @@ importers:
devDependencies: devDependencies:
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 'catalog:' specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue) version: 5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)
'@vue/compiler-sfc': '@vue/compiler-sfc':
specifier: workspace:* specifier: workspace:*
version: link:../../packages/compiler-sfc version: link:../../packages/compiler-sfc
@ -265,7 +265,7 @@ importers:
devDependencies: devDependencies:
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 'catalog:' specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue) version: 5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)
vite: vite:
specifier: 'catalog:' specifier: 'catalog:'
version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0) version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0)
@ -289,7 +289,7 @@ importers:
version: 3.4.38 version: 3.4.38
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 'catalog:' specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue) version: 5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)
connect: connect:
specifier: ^3.7.0 specifier: ^3.7.0
version: 3.7.0 version: 3.7.0
@ -307,7 +307,7 @@ importers:
devDependencies: devDependencies:
'@vitejs/plugin-vue': '@vitejs/plugin-vue':
specifier: 'catalog:' specifier: 'catalog:'
version: https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue) version: 5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)
vite: vite:
specifier: 'catalog:' specifier: 'catalog:'
version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0) version: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0)
@ -407,7 +407,7 @@ importers:
specifier: ^3.0.3 specifier: ^3.0.3
version: 3.0.3 version: 3.0.3
sass: sass:
specifier: ^1.86.0 specifier: ^1.86.3
version: 1.89.2 version: 1.89.2
packages/compiler-ssr: packages/compiler-ssr:
@ -1120,8 +1120,8 @@ packages:
'@polka/url@1.0.0-next.29': '@polka/url@1.0.0-next.29':
resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==} resolution: {integrity: sha512-wwQAWhWSuHaag8c4q/KN/vCoeOJYshAIvMQwD4GpSb3OiZklFfvAgmj0VCBBImRpuF/aFgIRzllXlVX93Jevww==}
'@puppeteer/browsers@2.8.0': '@puppeteer/browsers@2.10.4':
resolution: {integrity: sha512-yTwt2KWRmCQAfhvbCRjebaSX8pV1//I0Y3g+A7f/eS7gf0l4eRJoUCvcYdVtboeU4CTOZQuqYbZNS8aBYb8ROQ==} resolution: {integrity: sha512-9DxbZx+XGMNdjBynIs4BRSz+M3iRDeB7qRcAr6UORFLphCIM2x3DXgOucvADiifcqCE4XePFUKcnaAMyGbrDlQ==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -1568,9 +1568,8 @@ packages:
cpu: [x64] cpu: [x64]
os: [win32] os: [win32]
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@c156992': '@vitejs/plugin-vue@5.2.4':
resolution: {tarball: https://pkg.pr.new/@vitejs/plugin-vue@c156992} resolution: {integrity: sha512-7Yx/SXSOcQq5HiiV3orevHUFn+pmMB4cgbEkDYgnkUWb0WfeQ/wa2yFv6D5ICiCQOVpjA7vYDXrC7AGO8yjDHA==}
version: 5.2.1
engines: {node: ^18.0.0 || >=20.0.0} engines: {node: ^18.0.0 || >=20.0.0}
peerDependencies: peerDependencies:
vite: ^5.0.0 || ^6.0.0 vite: ^5.0.0 || ^6.0.0
@ -1631,41 +1630,41 @@ packages:
'@vitest/utils@3.2.4': '@vitest/utils@3.2.4':
resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==} resolution: {integrity: sha512-fB2V0JFrQSMsCo9HiSq3Ezpdv4iYaXRG1Sx8edX3MwxfyNn83mKiGzOcH+Fkxt4MHxr3y42fQi1oeAInqgX2QA==}
'@vue/compiler-core@3.5.13': '@vue/compiler-core@3.5.14':
resolution: {integrity: sha512-oOdAkwqUfW1WqpwSYJce06wvt6HljgY3fGeM9NcVA1HaYOij3mZG9Rkysn0OHuyUAGMbEbARIpsG+LPVlBJ5/Q==} resolution: {integrity: sha512-k7qMHMbKvoCXIxPhquKQVw3Twid3Kg4s7+oYURxLGRd56LiuHJVrvFKI4fm2AM3c8apqODPfVJGoh8nePbXMRA==}
'@vue/compiler-dom@3.5.13': '@vue/compiler-dom@3.5.14':
resolution: {integrity: sha512-ZOJ46sMOKUjO3e94wPdCzQ6P1Lx/vhp2RSvfaab88Ajexs0AHeV0uasYhi99WPaogmBlRHNRuly8xV75cNTMDA==} resolution: {integrity: sha512-1aOCSqxGOea5I80U2hQJvXYpPm/aXo95xL/m/mMhgyPUsKe9jhjwWpziNAw7tYRnbz1I61rd9Mld4W9KmmRoug==}
'@vue/compiler-sfc@3.5.13': '@vue/compiler-sfc@3.5.14':
resolution: {integrity: sha512-6VdaljMpD82w6c2749Zhf5T9u5uLBWKnVue6XWxprDobftnletJ8+oel7sexFfM3qIxNmVE7LSFGTpv6obNyaQ==} resolution: {integrity: sha512-9T6m/9mMr81Lj58JpzsiSIjBgv2LiVoWjIVa7kuXHICUi8LiDSIotMpPRXYJsXKqyARrzjT24NAwttrMnMaCXA==}
'@vue/compiler-ssr@3.5.13': '@vue/compiler-ssr@3.5.14':
resolution: {integrity: sha512-wMH6vrYHxQl/IybKJagqbquvxpWCuVYpoUJfCqFZwa/JY1GdATAQ+TgVtgrwwMZ0D07QhA99rs/EAAWfvG6KpA==} resolution: {integrity: sha512-Y0G7PcBxr1yllnHuS/NxNCSPWnRGH4Ogrp0tsLA5QemDZuJLs99YjAKQ7KqkHE0vCg4QTKlQzXLKCMF7WPSl7Q==}
'@vue/consolidate@1.0.0': '@vue/consolidate@1.0.0':
resolution: {integrity: sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==} resolution: {integrity: sha512-oTyUE+QHIzLw2PpV14GD/c7EohDyP64xCniWTcqcEmTd699eFqTIwOmtDYjcO1j3QgdXoJEoWv1/cCdLrRoOfg==}
engines: {node: '>= 0.12.0'} engines: {node: '>= 0.12.0'}
'@vue/reactivity@3.5.13': '@vue/reactivity@3.5.14':
resolution: {integrity: sha512-NaCwtw8o48B9I6L1zl2p41OHo/2Z4wqYGGIK1Khu5T7yxrn+ATOixn/Udn2m+6kZKB/J7cuT9DbWWhRxqixACg==} resolution: {integrity: sha512-7cK1Hp343Fu/SUCCO52vCabjvsYu7ZkOqyYu7bXV9P2yyfjUMUXHZafEbq244sP7gf+EZEz+77QixBTuEqkQQw==}
'@vue/repl@4.6.1': '@vue/repl@4.6.1':
resolution: {integrity: sha512-tgeEa+QXzqbFsAIbq/dCXzOJxIW2Nq1F79KXRjbKyPt1ODpCx86bDbFgNzFcBEK3In2/mjPTMpN7fSD6Ig0Qsw==} resolution: {integrity: sha512-tgeEa+QXzqbFsAIbq/dCXzOJxIW2Nq1F79KXRjbKyPt1ODpCx86bDbFgNzFcBEK3In2/mjPTMpN7fSD6Ig0Qsw==}
'@vue/runtime-core@3.5.13': '@vue/runtime-core@3.5.14':
resolution: {integrity: sha512-Fj4YRQ3Az0WTZw1sFe+QDb0aXCerigEpw418pw1HBUKFtnQHWzwojaukAs2X/c9DQz4MQ4bsXTGlcpGxU/RCIw==} resolution: {integrity: sha512-w9JWEANwHXNgieAhxPpEpJa+0V5G0hz3NmjAZwlOebtfKyp2hKxKF0+qSh0Xs6/PhfGihuSdqMprMVcQU/E6ag==}
'@vue/runtime-dom@3.5.13': '@vue/runtime-dom@3.5.14':
resolution: {integrity: sha512-dLaj94s93NYLqjLiyFzVs9X6dWhTdAlEAciC3Moq7gzAc13VJUdCnjjRurNM6uTLFATRHexHCTu/Xp3eW6yoog==} resolution: {integrity: sha512-lCfR++IakeI35TVR80QgOelsUIdcKjd65rWAMfdSlCYnaEY5t3hYwru7vvcWaqmrK+LpI7ZDDYiGU5V3xjMacw==}
'@vue/server-renderer@3.5.13': '@vue/server-renderer@3.5.14':
resolution: {integrity: sha512-wAi4IRJV/2SAW3htkTlB+dHeRmpTiVIK1OGLWV1yeStVSebSQQOwGwIq0D3ZIoBj2C2qpgz5+vX9iEBkTdk5YA==} resolution: {integrity: sha512-Rf/ISLqokIvcySIYnv3tNWq40PLpNLDLSJwwVWzG6MNtyIhfbcrAxo5ZL9nARJhqjZyWWa40oRb2IDuejeuv6w==}
peerDependencies: peerDependencies:
vue: 3.5.13 vue: 3.5.14
'@vue/shared@3.5.13': '@vue/shared@3.5.14':
resolution: {integrity: sha512-/hnE/qP5ZoGpol0a5mDi45bOd7t3tjYJBjsgCsivow7D48cJeV5l05RD82lPqi7gRiphZM37rnhW1l6ZoCNNnQ==} resolution: {integrity: sha512-oXTwNxVfc9EtP1zzXAlSlgARLXNC84frFYkS0HHz0h3E4WZSP9sywqjqzGCP9Y34M8ipNmd380pVgmMuwELDyQ==}
'@vueuse/core@11.3.0': '@vueuse/core@11.3.0':
resolution: {integrity: sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==} resolution: {integrity: sha512-7OC4Rl1f9G8IT6rUfi9JrKiXy4bfmHhZ5x2Ceojy0jnd3mHNEvV4JaRygH362ror6/NZ+Nl+n13LPzGiPN8cKA==}
@ -1887,8 +1886,8 @@ packages:
resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==} resolution: {integrity: sha512-Qgzu8kfBvo+cA4962jnP1KkS6Dop5NS6g7R5LFYJr4b8Ub94PPQXUksCw9PvXoeXPRRddRNC5C1JQUR2SMGtnA==}
engines: {node: '>= 14.16.0'} engines: {node: '>= 14.16.0'}
chromium-bidi@2.1.2: chromium-bidi@5.1.0:
resolution: {integrity: sha512-vtRWBK2uImo5/W2oG6/cDkkHSm+2t6VHgnj+Rcwhb0pP74OoUb4GipyRX/T/y39gYQPhioP0DPShn+A7P6CHNw==} resolution: {integrity: sha512-9MSRhWRVoRPDG0TgzkHrshFSJJNZzfY5UFqUMuksg7zL1yoZIZ3jLB0YAgHclbiAxPI86pBnwDX1tbzoiV8aFw==}
peerDependencies: peerDependencies:
devtools-protocol: '*' devtools-protocol: '*'
@ -2117,8 +2116,8 @@ packages:
engines: {node: '>=0.10'} engines: {node: '>=0.10'}
hasBin: true hasBin: true
devtools-protocol@0.0.1413902: devtools-protocol@0.0.1439962:
resolution: {integrity: sha512-yRtvFD8Oyk7C9Os3GmnFZLu53yAfsnyw1s+mLmHHUK0GQEc9zthHWvS1r67Zqzm5t7v56PILHIVZ7kmFMaL2yQ==} resolution: {integrity: sha512-jJF48UdryzKiWhJ1bLKr7BFWUQCEIT5uCNbDLqkQJBtkFxYzILJH44WN0PDKMIlGDN7Utb8vyUY85C3w4R/t2g==}
doctypes@1.1.0: doctypes@1.1.0:
resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==} resolution: {integrity: sha512-LLBi6pEqS6Do3EKQ3J0NqHWV5hhb78Pi8vvESYwyOy2c31ZEZVdtitdzsQsKb7878PEERhzUk0ftqGhG6Mz+pQ==}
@ -3229,12 +3228,12 @@ packages:
resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==} resolution: {integrity: sha512-vYt7UD1U9Wg6138shLtLOvdAu+8DsC/ilFtEVHcH+wydcSpNE20AfSOduf6MkRFahL5FY7X1oU7nKVZFtfq8Fg==}
engines: {node: '>=6'} engines: {node: '>=6'}
puppeteer-core@24.4.0: puppeteer-core@24.8.2:
resolution: {integrity: sha512-eFw66gCnWo0X8Hyf9KxxJtms7a61NJVMiSaWfItsFPzFBsjsWdmcNlBdsA1WVwln6neoHhsG+uTVesKmTREn/g==} resolution: {integrity: sha512-wNw5cRZOHiFibWc0vdYCYO92QuKTbJ8frXiUfOq/UGJWMqhPoBThTKkV+dJ99YyWfzJ2CfQQ4T1nhhR0h8FlVw==}
engines: {node: '>=18'} engines: {node: '>=18'}
puppeteer@24.4.0: puppeteer@24.8.2:
resolution: {integrity: sha512-E4JhJzjS8AAI+6N/b+Utwarhz6zWl3+MR725fal+s3UlOlX2eWdsvYYU+Q5bXMjs9eZEGkNQroLkn7j11s2k1Q==} resolution: {integrity: sha512-Sn6SBPwJ6ASFvQ7knQkR+yG7pcmr4LfXzmoVp3NR0xXyBbPhJa8a8ybtb6fnw1g/DD/2t34//yirubVczko37w==}
engines: {node: '>=18'} engines: {node: '>=18'}
hasBin: true hasBin: true
@ -3829,8 +3828,8 @@ packages:
'@vue/composition-api': '@vue/composition-api':
optional: true optional: true
vue@3.5.13: vue@3.5.14:
resolution: {integrity: sha512-wmeiSMxkZCSc+PM2w2VRsOYAZC8GdipNFRTsLSfodVqI9mbejKeXEGr8SckuLnrQPGe3oJN5c3K0vpoU9q/wCQ==} resolution: {integrity: sha512-LbOm50/vZFG6Mhy6KscQYXZMQ0LMCC/y40HDJPPvGFQ+i/lUH+PJHR6C3assgOQiXdl6tAfsXHbXYVBZZu65ew==}
peerDependencies: peerDependencies:
typescript: '*' typescript: '*'
peerDependenciesMeta: peerDependenciesMeta:
@ -4358,7 +4357,7 @@ snapshots:
'@polka/url@1.0.0-next.29': {} '@polka/url@1.0.0-next.29': {}
'@puppeteer/browsers@2.8.0': '@puppeteer/browsers@2.10.4':
dependencies: dependencies:
debug: 4.4.1 debug: 4.4.1
extract-zip: 2.0.1 extract-zip: 2.0.1
@ -4737,12 +4736,12 @@ snapshots:
'@unrs/resolver-binding-win32-x64-msvc@1.9.0': '@unrs/resolver-binding-win32-x64-msvc@1.9.0':
optional: true optional: true
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@3.5.13(typescript@5.6.3))': '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@3.5.14(typescript@5.6.3))':
dependencies: dependencies:
vite: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0) vite: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0)
vue: 3.5.13(typescript@5.6.3) vue: 3.5.14(typescript@5.6.3)
'@vitejs/plugin-vue@https://pkg.pr.new/@vitejs/plugin-vue@c156992(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)': '@vitejs/plugin-vue@5.2.4(vite@6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0))(vue@packages+vue)':
dependencies: dependencies:
vite: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0) vite: 6.3.5(@types/node@22.15.32)(sass@1.89.2)(yaml@2.8.0)
vue: link:packages/vue vue: link:packages/vue
@ -4829,63 +4828,63 @@ snapshots:
loupe: 3.1.4 loupe: 3.1.4
tinyrainbow: 2.0.0 tinyrainbow: 2.0.0
'@vue/compiler-core@3.5.13': '@vue/compiler-core@3.5.14':
dependencies: dependencies:
'@babel/parser': 7.27.5 '@babel/parser': 7.27.5
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
entities: 4.5.0 entities: 4.5.0
estree-walker: 2.0.2 estree-walker: 2.0.2
source-map-js: 1.2.1 source-map-js: 1.2.1
'@vue/compiler-dom@3.5.13': '@vue/compiler-dom@3.5.14':
dependencies: dependencies:
'@vue/compiler-core': 3.5.13 '@vue/compiler-core': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
'@vue/compiler-sfc@3.5.13': '@vue/compiler-sfc@3.5.14':
dependencies: dependencies:
'@babel/parser': 7.27.5 '@babel/parser': 7.27.5
'@vue/compiler-core': 3.5.13 '@vue/compiler-core': 3.5.14
'@vue/compiler-dom': 3.5.13 '@vue/compiler-dom': 3.5.14
'@vue/compiler-ssr': 3.5.13 '@vue/compiler-ssr': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
estree-walker: 2.0.2 estree-walker: 2.0.2
magic-string: 0.30.17 magic-string: 0.30.17
postcss: 8.5.6 postcss: 8.5.6
source-map-js: 1.2.1 source-map-js: 1.2.1
'@vue/compiler-ssr@3.5.13': '@vue/compiler-ssr@3.5.14':
dependencies: dependencies:
'@vue/compiler-dom': 3.5.13 '@vue/compiler-dom': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
'@vue/consolidate@1.0.0': {} '@vue/consolidate@1.0.0': {}
'@vue/reactivity@3.5.13': '@vue/reactivity@3.5.14':
dependencies: dependencies:
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
'@vue/repl@4.6.1': {} '@vue/repl@4.6.1': {}
'@vue/runtime-core@3.5.13': '@vue/runtime-core@3.5.14':
dependencies: dependencies:
'@vue/reactivity': 3.5.13 '@vue/reactivity': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
'@vue/runtime-dom@3.5.13': '@vue/runtime-dom@3.5.14':
dependencies: dependencies:
'@vue/reactivity': 3.5.13 '@vue/reactivity': 3.5.14
'@vue/runtime-core': 3.5.13 '@vue/runtime-core': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
csstype: 3.1.3 csstype: 3.1.3
'@vue/server-renderer@3.5.13(vue@3.5.13(typescript@5.6.3))': '@vue/server-renderer@3.5.14(vue@3.5.14(typescript@5.6.3))':
dependencies: dependencies:
'@vue/compiler-ssr': 3.5.13 '@vue/compiler-ssr': 3.5.14
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
vue: 3.5.13(typescript@5.6.3) vue: 3.5.14(typescript@5.6.3)
'@vue/shared@3.5.13': {} '@vue/shared@3.5.14': {}
'@vueuse/core@11.3.0(vue@packages+vue)': '@vueuse/core@11.3.0(vue@packages+vue)':
dependencies: dependencies:
@ -5097,9 +5096,9 @@ snapshots:
dependencies: dependencies:
readdirp: 4.1.2 readdirp: 4.1.2
chromium-bidi@2.1.2(devtools-protocol@0.0.1413902): chromium-bidi@5.1.0(devtools-protocol@0.0.1439962):
dependencies: dependencies:
devtools-protocol: 0.0.1413902 devtools-protocol: 0.0.1439962
mitt: 3.0.1 mitt: 3.0.1
zod: 3.25.67 zod: 3.25.67
@ -5327,7 +5326,7 @@ snapshots:
detect-libc@1.0.3: detect-libc@1.0.3:
optional: true optional: true
devtools-protocol@0.0.1413902: {} devtools-protocol@0.0.1439962: {}
doctypes@1.1.0: {} doctypes@1.1.0: {}
@ -6516,12 +6515,12 @@ snapshots:
punycode@2.3.1: {} punycode@2.3.1: {}
puppeteer-core@24.4.0: puppeteer-core@24.8.2:
dependencies: dependencies:
'@puppeteer/browsers': 2.8.0 '@puppeteer/browsers': 2.10.4
chromium-bidi: 2.1.2(devtools-protocol@0.0.1413902) chromium-bidi: 5.1.0(devtools-protocol@0.0.1439962)
debug: 4.4.1 debug: 4.4.1
devtools-protocol: 0.0.1413902 devtools-protocol: 0.0.1439962
typed-query-selector: 2.12.0 typed-query-selector: 2.12.0
ws: 8.18.2 ws: 8.18.2
transitivePeerDependencies: transitivePeerDependencies:
@ -6530,13 +6529,13 @@ snapshots:
- supports-color - supports-color
- utf-8-validate - utf-8-validate
puppeteer@24.4.0(typescript@5.6.3): puppeteer@24.8.2(typescript@5.6.3):
dependencies: dependencies:
'@puppeteer/browsers': 2.8.0 '@puppeteer/browsers': 2.10.4
chromium-bidi: 2.1.2(devtools-protocol@0.0.1413902) chromium-bidi: 5.1.0(devtools-protocol@0.0.1439962)
cosmiconfig: 9.0.0(typescript@5.6.3) cosmiconfig: 9.0.0(typescript@5.6.3)
devtools-protocol: 0.0.1413902 devtools-protocol: 0.0.1439962
puppeteer-core: 24.4.0 puppeteer-core: 24.8.2
typed-query-selector: 2.12.0 typed-query-selector: 2.12.0
transitivePeerDependencies: transitivePeerDependencies:
- bare-buffer - bare-buffer
@ -7176,13 +7175,13 @@ snapshots:
dependencies: dependencies:
vue: link:packages/vue vue: link:packages/vue
vue@3.5.13(typescript@5.6.3): vue@3.5.14(typescript@5.6.3):
dependencies: dependencies:
'@vue/compiler-dom': 3.5.13 '@vue/compiler-dom': 3.5.14
'@vue/compiler-sfc': 3.5.13 '@vue/compiler-sfc': 3.5.14
'@vue/runtime-dom': 3.5.13 '@vue/runtime-dom': 3.5.14
'@vue/server-renderer': 3.5.13(vue@3.5.13(typescript@5.6.3)) '@vue/server-renderer': 3.5.14(vue@3.5.14(typescript@5.6.3))
'@vue/shared': 3.5.13 '@vue/shared': 3.5.14
optionalDependencies: optionalDependencies:
typescript: 5.6.3 typescript: 5.6.3

View File

@ -3,10 +3,25 @@ packages:
- 'packages-private/*' - 'packages-private/*'
catalog: catalog:
'@babel/parser': ^7.27.0 '@babel/parser': ^7.27.2
'@babel/types': ^7.27.0 '@babel/types': ^7.27.1
'estree-walker': ^2.0.2 'estree-walker': ^2.0.2
'vite': ^6.1.0 'vite': ^6.1.0
'@vitejs/plugin-vue': https://pkg.pr.new/@vitejs/plugin-vue@c156992 '@vitejs/plugin-vue': ^5.2.4
'magic-string': ^0.30.17 'magic-string': ^0.30.17
'source-map-js': ^1.2.1 'source-map-js': ^1.2.1
onlyBuiltDependencies:
- '@swc/core'
- 'esbuild'
- 'puppeteer'
- 'simple-git-hooks'
- 'unrs-resolver'
peerDependencyRules:
allowedVersions:
'typescript-eslint>eslint': '^9.0.0'
'@typescript-eslint/eslint-plugin>eslint': '^9.0.0'
'@typescript-eslint/parser>eslint': '^9.0.0'
'@typescript-eslint/type-utils>eslint': '^9.0.0'
'@typescript-eslint/utils>eslint': '^9.0.0'