Merge remote-tracking branch 'upstream/main'

This commit is contained in:
三咲智子 Kevin Deng 2024-09-17 10:32:28 +08:00
commit 594cb1412d
No known key found for this signature in database
298 changed files with 5808 additions and 2792 deletions

View File

@ -236,7 +236,7 @@ Tests that test against source code are grouped under `nr test-unit`, while test
### `nr test-dts`
Runs `nr build-dts` first, then verify the type tests in `packages/dts-test` are working correctly against the actual built type declarations.
Runs `nr build-dts` first, then verify the type tests in `packages-private/dts-test` are working correctly against the actual built type declarations.
## Project Structure
@ -335,7 +335,7 @@ Test coverage is continuously deployed at https://coverage.vuejs.org. PRs that i
### Testing Type Definition Correctness
Type tests are located in the `packages/dts-test` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by running `nr test-dts-only`.
Type tests are located in the `packages-private/dts-test` directory. To run the dts tests, run `nr test-dts`. Note that the type test requires all relevant `*.d.ts` files to be built first (and the script does it for you). Once the `d.ts` files are built and up-to-date, the tests can be re-run by running `nr test-dts-only`.
## Financial Contribution

View File

@ -17,8 +17,8 @@
{
groupName: 'playground',
matchFileNames: [
'packages/sfc-playground/package.json',
'packages/template-explorer/package.json',
'packages-private/sfc-playground/package.json',
'packages-private/template-explorer/package.json',
],
},
{
@ -54,5 +54,13 @@
// pinned
// https://github.com/vuejs/core/commit/a012e39b373f1b6918e5c89856e8f902e1bfa14d
'@rollup/plugin-replace',
// pinned
// only used in example for e2e tests
'marked',
// pinned, 5.0+ has exports issues
// https://github.com/vuejs/core/issues/11603
'entities',
],
}

View File

@ -3,6 +3,8 @@ on:
push:
branches:
- '**'
tags:
- '!**'
pull_request:
branches:
- main
@ -12,3 +14,29 @@ jobs:
test:
if: ${{ ! startsWith(github.event.head_commit.message, 'release:') && (github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository) }}
uses: ./.github/workflows/test.yml
continuous-release:
if: github.repository == 'vuejs/core'
runs-on: ubuntu-latest
steps:
- name: Checkout
uses: actions/checkout@v4
- name: Install pnpm
uses: pnpm/action-setup@v4
- name: Install Node.js
uses: actions/setup-node@v4
with:
node-version-file: '.node-version'
registry-url: 'https://registry.npmjs.org'
cache: 'pnpm'
- name: Install deps
run: pnpm install
- name: Build
run: pnpm build --withTypes
- name: Release
run: pnpx pkg-pr-new publish --compact --pnpm './packages/*'

View File

@ -0,0 +1,21 @@
name: Auto close issues with "can't reproduce" label
on:
schedule:
- cron: '0 0 * * *'
permissions:
issues: write
jobs:
close-issues:
if: github.repository == 'vuejs/core'
runs-on: ubuntu-latest
steps:
- name: can't reproduce
uses: actions-cool/issues-helper@v3
with:
actions: 'close-issues'
token: ${{ secrets.GITHUB_TOKEN }}
labels: "can't reproduce"
inactive-day: 3

View File

@ -9,7 +9,8 @@ jobs:
runs-on: ubuntu-latest
if: github.repository == 'vuejs/core' && github.event.issue.pull_request && startsWith(github.event.comment.body, '/ecosystem-ci run')
steps:
- uses: actions/github-script@v7
- name: Check user permission
uses: actions/github-script@v7
with:
script: |
const user = context.payload.sender.login
@ -43,7 +44,8 @@ jobs:
})
throw new Error('not allowed')
}
- uses: actions/github-script@v7
- name: Get PR info
uses: actions/github-script@v7
id: get-pr-data
with:
script: |
@ -56,9 +58,11 @@ jobs:
return {
num: context.issue.number,
branchName: pr.head.ref,
repo: pr.head.repo.full_name
repo: pr.head.repo.full_name,
commit: pr.head.sha
}
- uses: actions/github-script@v7
- name: Trigger run
uses: actions/github-script@v7
id: trigger
env:
COMMENT: ${{ github.event.comment.body }}
@ -80,6 +84,7 @@ jobs:
prNumber: '' + prData.num,
branchName: prData.branchName,
repo: prData.repo,
suite: suite === '' ? '-' : suite
suite: suite === '' ? '-' : suite,
commit: prData.commit
}
})

View File

@ -18,6 +18,7 @@ env:
jobs:
upload:
if: github.repository == 'vuejs/core'
runs-on: ubuntu-latest
steps:
@ -48,22 +49,14 @@ jobs:
path: temp/size-prev
if_no_artifact_found: warn
- name: Save PR number & base branch
if: ${{github.event_name == 'pull_request'}}
run: |
echo ${{ github.event.number }} > ./temp/size/number.txt
echo ${{ github.base_ref }} > ./temp/size/base.txt
- name: Upload Size Data
uses: actions/upload-artifact@v4
with:
name: size-data
path: temp/size
- name: Save PR number & base branch
if: ${{github.event_name == 'pull_request'}}
run: |
echo ${{ github.event.number }} > ./number.txt
echo ${{ github.base_ref }} > ./base.txt
- uses: actions/upload-artifact@v4
if: ${{github.event_name == 'pull_request'}}
with:
name: pr-info
path: |
number.txt
base.txt

View File

@ -18,6 +18,7 @@ jobs:
size-report:
runs-on: ubuntu-latest
if: >
github.repository == 'vuejs/core' &&
github.event.workflow_run.event == 'pull_request' &&
github.event.workflow_run.conclusion == 'success'
steps:
@ -35,25 +36,6 @@ jobs:
- name: Install dependencies
run: pnpm install
- name: Download PR info
uses: dawidd6/action-download-artifact@v6
with:
name: pr-info
run_id: ${{ github.event.workflow_run.id }}
path: /tmp/pr-info
- name: Read PR Number
id: pr-number
uses: juliangruber/read-file-action@v1
with:
path: /tmp/pr-info/number.txt
- name: Read PR base branch
id: pr-base
uses: juliangruber/read-file-action@v1
with:
path: /tmp/pr-info/base.txt
- name: Download Size Data
uses: dawidd6/action-download-artifact@v6
with:
@ -61,6 +43,18 @@ jobs:
run_id: ${{ github.event.workflow_run.id }}
path: temp/size
- name: Read PR Number
id: pr-number
uses: juliangruber/read-file-action@v1
with:
path: temp/size/number.txt
- name: Read base branch
id: pr-base
uses: juliangruber/read-file-action@v1
with:
path: temp/size/base.txt
- name: Download Previous Size Data
uses: dawidd6/action-download-artifact@v6
with:
@ -72,7 +66,7 @@ jobs:
if_no_artifact_found: warn
- name: Prepare report
run: pnpm tsx scripts/size-report.ts > size-report.md
run: node scripts/size-report.js > size-report.md
- name: Read Size Report
id: size-report

3
.vscode/extensions.json vendored Normal file
View File

@ -0,0 +1,3 @@
{
"recommendations": ["vitest.explorer"]
}

View File

@ -1,3 +1,245 @@
## [3.5.6](https://github.com/vuejs/core/compare/v3.5.5...v3.5.6) (2024-09-16)
### Bug Fixes
* **compile-dom:** should be able to stringify mathML ([#11891](https://github.com/vuejs/core/issues/11891)) ([85c138c](https://github.com/vuejs/core/commit/85c138ced108268f7656b568dfd3036a1e0aae34))
* **compiler-sfc:** preserve old behavior when using withDefaults with desutructure ([8492c3c](https://github.com/vuejs/core/commit/8492c3c49a922363d6c77ef192c133a8fbce6514)), closes [#11930](https://github.com/vuejs/core/issues/11930)
* **reactivity:** avoid exponential perf cost and reduce call stack depth for deeply chained computeds ([#11944](https://github.com/vuejs/core/issues/11944)) ([c74bb8c](https://github.com/vuejs/core/commit/c74bb8c2dd9e82aaabb0a2a2b368e900929b513b)), closes [#11928](https://github.com/vuejs/core/issues/11928)
* **reactivity:** rely on dirty check only when computed has deps ([#11931](https://github.com/vuejs/core/issues/11931)) ([aa5dafd](https://github.com/vuejs/core/commit/aa5dafd2b55d42d6a29316a3bc91aea85c676a0b)), closes [#11929](https://github.com/vuejs/core/issues/11929)
* **watch:** `once` option should be ignored by watchEffect ([#11884](https://github.com/vuejs/core/issues/11884)) ([49fa673](https://github.com/vuejs/core/commit/49fa673493d93b77ddba2165ab6545bae84fd1ae))
* **watch:** unwatch should be callable during SSR ([#11925](https://github.com/vuejs/core/issues/11925)) ([2d6adf7](https://github.com/vuejs/core/commit/2d6adf78a047eed091db277ffbd9df0822fb0bdd)), closes [#11924](https://github.com/vuejs/core/issues/11924)
## [3.5.5](https://github.com/vuejs/core/compare/v3.5.4...v3.5.5) (2024-09-13)
### Bug Fixes
* **compiler-core:** fix handling of delimiterOpen in VPre ([#11915](https://github.com/vuejs/core/issues/11915)) ([706d4ac](https://github.com/vuejs/core/commit/706d4ac1d0210b2d9134b3228280187fe02fc971)), closes [#11913](https://github.com/vuejs/core/issues/11913)
* **compiler-dom:** fix stringify static edge for partially eligible chunks in cached parent ([1d99d61](https://github.com/vuejs/core/commit/1d99d61c1bd77f9ea6743f6214a82add8346a121)), closes [#11879](https://github.com/vuejs/core/issues/11879) [#11890](https://github.com/vuejs/core/issues/11890)
* **compiler-dom:** should ignore leading newline in <textarea> per spec ([3c4bf76](https://github.com/vuejs/core/commit/3c4bf7627649ec1e3220f8c4e4163c20d2afb367))
* **compiler-sfc:** nested css supports atrule and comment ([#11899](https://github.com/vuejs/core/issues/11899)) ([0e7bc71](https://github.com/vuejs/core/commit/0e7bc717e6640644f062957ec5031506f0dab215)), closes [#11896](https://github.com/vuejs/core/issues/11896)
* **custom-element:** handle nested customElement mount w/ shadowRoot false ([#11861](https://github.com/vuejs/core/issues/11861)) ([f2d8019](https://github.com/vuejs/core/commit/f2d801918841e7673ff3f048d0d895592a2f7e23)), closes [#11851](https://github.com/vuejs/core/issues/11851) [#11871](https://github.com/vuejs/core/issues/11871)
* **hmr:** reload async child wrapped in Suspense + KeepAlive ([#11907](https://github.com/vuejs/core/issues/11907)) ([10a2c60](https://github.com/vuejs/core/commit/10a2c6053bd30d160d0214bb3566f540187e6874)), closes [#11868](https://github.com/vuejs/core/issues/11868)
* **hydration:** fix mismatch of leading newline in `<textarea>` and `<pre>` ([a5f3c2e](https://github.com/vuejs/core/commit/a5f3c2eb4d2e7fae93ff93ce865b269f01cc825e)), closes [#11873](https://github.com/vuejs/core/issues/11873) [#11874](https://github.com/vuejs/core/issues/11874)
* **reactivity:** properly clean up deps, fix memory leak ([8ea5d6d](https://github.com/vuejs/core/commit/8ea5d6d6981ab7febda0be43c3c92b18869c3a2a)), closes [#11901](https://github.com/vuejs/core/issues/11901)
* **runtime-core:** properly update async component nested in KeepAlive ([#11917](https://github.com/vuejs/core/issues/11917)) ([7fe6c79](https://github.com/vuejs/core/commit/7fe6c795a1fc7ddcea5ad91a56141561192373ac)), closes [#11916](https://github.com/vuejs/core/issues/11916)
* **TransitionGroup:** not warn unkeyed text children with whitespece preserve ([#11888](https://github.com/vuejs/core/issues/11888)) ([7571f20](https://github.com/vuejs/core/commit/7571f20bc3d1854377a146f41d211e05bb68cd47)), closes [#11885](https://github.com/vuejs/core/issues/11885)
## [3.5.4](https://github.com/vuejs/core/compare/v3.5.3...v3.5.4) (2024-09-10)
### Bug Fixes
* **compiler-sfc:** correct scoped injection for nesting selector ([#11854](https://github.com/vuejs/core/issues/11854)) ([b1de75e](https://github.com/vuejs/core/commit/b1de75ed04626b6423085dfde91fb0cb481a25e8)), closes [#10567](https://github.com/vuejs/core/issues/10567)
* **reactivity:** fix markRaw error on already marked object ([#11864](https://github.com/vuejs/core/issues/11864)) ([67d6596](https://github.com/vuejs/core/commit/67d6596d40b1807b9cd8eb0d9282932ea77be3c0)), closes [#11862](https://github.com/vuejs/core/issues/11862)
* Revert "fix: Revert "fix(reactivity): self-referencing computed should refresh"" ([e596378](https://github.com/vuejs/core/commit/e596378e0be728dad7d60938449f3fa557ca2ec9))
* **runtime-core:** handle shallow reactive arrays in renderList correctly ([#11870](https://github.com/vuejs/core/issues/11870)) ([ced59ab](https://github.com/vuejs/core/commit/ced59ab8f2f2e89c13119bab3a0c25a1a1f1c3d6)), closes [#11869](https://github.com/vuejs/core/issues/11869)
* **types:** correctly infer `TypeEmits` with both tuple and function syntax ([#11840](https://github.com/vuejs/core/issues/11840)) ([dad6738](https://github.com/vuejs/core/commit/dad673809929c084dcb8e42640eb7daa675d4ea4)), closes [#11836](https://github.com/vuejs/core/issues/11836)
### Performance Improvements
* **reactivity:** trigger deps directly instead of storing in an array first ([#11695](https://github.com/vuejs/core/issues/11695)) ([f80d447](https://github.com/vuejs/core/commit/f80d447c17662556e9e3f99f6d199967f4c8cf3d))
## [3.5.3](https://github.com/vuejs/core/compare/v3.5.2...v3.5.3) (2024-09-06)
### Bug Fixes
* **hydration:** check __asyncHydrate presence for vue3-lazy-hydration compat ([#11825](https://github.com/vuejs/core/issues/11825)) ([8e6c337](https://github.com/vuejs/core/commit/8e6c3378676be05cea7f53664442acdfb86784f9)), closes [#11793](https://github.com/vuejs/core/issues/11793)
* Revert "fix(reactivity): self-referencing computed should refresh" ([35c760f](https://github.com/vuejs/core/commit/35c760f82f749f7c6e3f9bfead8221ce498e892f))
* **ssr:** respect app.config.warnHandler during ssr ([bf3d9a2](https://github.com/vuejs/core/commit/bf3d9a2af41659a743706306fc798b3d215df5af)), closes [#11830](https://github.com/vuejs/core/issues/11830)
* **Transition:** handle KeepAlive child unmount in Transition out-in mode ([#11833](https://github.com/vuejs/core/issues/11833)) ([6b7901d](https://github.com/vuejs/core/commit/6b7901d28ed3a6a9242c666cc1b8e3c0b0b0fe62)), closes [#11775](https://github.com/vuejs/core/issues/11775)
* **useId:** make generated IDs selector compatible ([babfb4c](https://github.com/vuejs/core/commit/babfb4cbcbf98601d76c1d7653eae8d250ce2710)), closes [#11828](https://github.com/vuejs/core/issues/11828)
## [3.5.2](https://github.com/vuejs/core/compare/v3.5.1...v3.5.2) (2024-09-05)
### Bug Fixes
* **reactivity:** make toRaw work on proxies created by proxyRef ([46c3ab1](https://github.com/vuejs/core/commit/46c3ab1d714024894fa1d33e495d5d35c7817d4d))
* **reactivity:** pass oldValue to computed getter ([#11813](https://github.com/vuejs/core/issues/11813)) ([98864a7](https://github.com/vuejs/core/commit/98864a7ef5c8080c407166c8221488a4eacbbc81)), closes [#11812](https://github.com/vuejs/core/issues/11812)
* **reactivity:** prevent endless recursion in computed getters ([#11797](https://github.com/vuejs/core/issues/11797)) ([716275d](https://github.com/vuejs/core/commit/716275d1b1d2383d8ef0306fcd94558d4d9170f2))
* **reactivity:** self-referencing computed should refresh ([e84c4a6](https://github.com/vuejs/core/commit/e84c4a608e9dc96fb2a4a29d538bcc64f26103a2)), closes [/github.com/vuejs/core/pull/11797#issuecomment-2330738633](https://github.com//github.com/vuejs/core/pull/11797/issues/issuecomment-2330738633)
* **scheduler:** prevent duplicate jobs being queued ([#11826](https://github.com/vuejs/core/issues/11826)) ([df56cc5](https://github.com/vuejs/core/commit/df56cc528793b1d6131a1e64095dd5cb95c56bee)), closes [#11712](https://github.com/vuejs/core/issues/11712) [#11807](https://github.com/vuejs/core/issues/11807)
* **suspense:** avoid updating anchor if activeBranch has not been rendered to the actual container ([#11818](https://github.com/vuejs/core/issues/11818)) ([3c0d531](https://github.com/vuejs/core/commit/3c0d531fa7fe762bfe46fbe63f318adc95221795)), closes [#11806](https://github.com/vuejs/core/issues/11806)
* **Transition:** handle KeepAlive child unmount in Transition out-in mode ([#11778](https://github.com/vuejs/core/issues/11778)) ([3116553](https://github.com/vuejs/core/commit/311655352931863dfcf520b8cf29cebc5b7e1e00)), closes [#11775](https://github.com/vuejs/core/issues/11775)
* **types:** add HTMLDialogElement missing close event ([#11811](https://github.com/vuejs/core/issues/11811)) ([3634f7a](https://github.com/vuejs/core/commit/3634f7a4c1649ad2e7e969eb4512512868c61d01))
* **types:** added name attribute support to details tag ([#11823](https://github.com/vuejs/core/issues/11823)) ([c74176e](https://github.com/vuejs/core/commit/c74176ec7b4d1d34159ce21d600c04b157ac5549)), closes [#11821](https://github.com/vuejs/core/issues/11821)
* **types:** fix defineComponent props inference when setup() has explicit annotation ([fca20a3](https://github.com/vuejs/core/commit/fca20a39aa4a6f98c8f972bd435ebb7dc535648a)), closes [#11803](https://github.com/vuejs/core/issues/11803)
* **useTemplateRef:** properly fix readonly warning in dev and ensure prod behavior consistency ([9b7797d](https://github.com/vuejs/core/commit/9b7797d0d1fc773e979e042673d5b9b3151c40fc)), closes [#11808](https://github.com/vuejs/core/issues/11808) [#11816](https://github.com/vuejs/core/issues/11816) [#11810](https://github.com/vuejs/core/issues/11810)
### Features
* **compiler-core:** parse modifiers as expression to provide location data ([#11819](https://github.com/vuejs/core/issues/11819)) ([3f13203](https://github.com/vuejs/core/commit/3f13203564164eeb2945bdc0b9ef755c37477d75))
## [3.5.1](https://github.com/vuejs/core/compare/v3.5.0...v3.5.1) (2024-09-04)
### Bug Fixes
* **build:** improve built-in components treeshakability ([4eee630](https://github.com/vuejs/core/commit/4eee630b3122a10d0baf9b91358cfffa92d6fd81))
* **reactivity:** handle non-array arguments in reactive `concat` method ([#11794](https://github.com/vuejs/core/issues/11794)) ([475977a](https://github.com/vuejs/core/commit/475977a6f76b77392610e0a3ec2b0e076d1e1d59)), closes [#11792](https://github.com/vuejs/core/issues/11792)
* **Transition:** avoid applying transition hooks on comment vnode ([#11788](https://github.com/vuejs/core/issues/11788)) ([51912f8](https://github.com/vuejs/core/commit/51912f8a02e35f172f6d30ed7a2f3a92c1407cf9)), closes [#11782](https://github.com/vuejs/core/issues/11782)
* **types:** avoid using intersection type in `Readonly<...>` to fix JSDoc emit ([#11799](https://github.com/vuejs/core/issues/11799)) ([7518bc1](https://github.com/vuejs/core/commit/7518bc19dc73ba46dcf1eef6e23f9e6e75552675))
* **useTemplateRef:** fix readonly warning when useTemplateRef has same variable name as template ref ([bc63df0](https://github.com/vuejs/core/commit/bc63df01992fdbf0b6749ad234153725697ed896)), closes [#11795](https://github.com/vuejs/core/issues/11795) [#11802](https://github.com/vuejs/core/issues/11802) [#11804](https://github.com/vuejs/core/issues/11804)
# [3.5.0](https://github.com/vuejs/core/compare/v3.5.0-rc.1...v3.5.0) (2024-09-03)
## Aggregated Features List for 3.5 (alpha to stable)
### Reactivity
- **reactivity**: Refactor reactivity system to use version counting and doubly-linked list tracking ([#10397](https://github.com/vuejs/core/pull/10397)) ([05eb4e0](https://github.com/vuejs/core/commit/05eb4e0fefd585125dd60b7f8fe9c36928d921aa))
- **reactivity**: Optimize array tracking ([#9511](https://github.com/vuejs/core/pull/9511)) ([70196a4](https://github.com/vuejs/core/commit/70196a40cc078f50fcc1110c38c06fbcc70b205e))
- **compiler-sfc:** enable reactive props destructure by default ([d2dac0e](https://github.com/vuejs/core/commit/d2dac0e359c47d1ed0aa77eda488e76fd6466d2d))
- **reactivity:** `onEffectCleanup` API ([2cc5615](https://github.com/vuejs/core/commit/2cc5615590de77126e8df46136de0240dbde5004)), closes [#10173](https://github.com/vuejs/core/issues/10173)
- **reactivity:** add `failSilently` argument for `onScopeDispose` ([9a936aa](https://github.com/vuejs/core/commit/9a936aaec489c79433a32791ecf5ddb1739a62bd))
- **reactivity/watch:** base `watch`, `getCurrentWatcher`, and `onWatcherCleanup` ([#9927](https://github.com/vuejs/core/issues/9927)) ([205e5b5](https://github.com/vuejs/core/commit/205e5b5e277243c3af2c937d9bd46cf671296b72))
- **reactivity/watch:** add pause/resume for ReactiveEffect, EffectScope, and WatchHandle ([#9651](https://github.com/vuejs/core/issues/9651)) ([267093c](https://github.com/vuejs/core/commit/267093c31490050bfcf3ff2b30a2aefee2dad582))
- **watch:** support passing number to `deep` option to control the watch depth ([#9572](https://github.com/vuejs/core/issues/9572)) ([22f7d96](https://github.com/vuejs/core/commit/22f7d96757956ebe0baafe52256aa327908cc51c))
- **types:** export `MultiWatchSources` type ([#9563](https://github.com/vuejs/core/issues/9563)) ([998dca5](https://github.com/vuejs/core/commit/998dca59f140420280803233f41707580688562c))
- **types:** allow computed getter and setter types to be unrelated ([#11472](https://github.com/vuejs/core/issues/11472)) ([a01675e](https://github.com/vuejs/core/commit/a01675ef8f99b5acd6832c53051f4415b18609f2)), closes [#7271](https://github.com/vuejs/core/issues/7271)
### SSR
- **runtime-core:** `useId()` and `app.config.idPrefix` ([#11404](https://github.com/vuejs/core/issues/11404)) ([73ef156](https://github.com/vuejs/core/commit/73ef1561f6905d69f968c094d0180c61824f1247))
- **hydration:** lazy hydration strategies for async components ([#11458](https://github.com/vuejs/core/issues/11458)) ([d14a11c](https://github.com/vuejs/core/commit/d14a11c1cdcee88452f17ce97758743c863958f4))
- **hydration:** support suppressing hydration mismatch via data-allow-mismatch ([94fb2b8](https://github.com/vuejs/core/commit/94fb2b8106a66bcca1a3f922a246a29fdd1274b1))
### Custom Element
- **custom-element:** `useHost()` helper ([775103a](https://github.com/vuejs/core/commit/775103af37df69d34c79f12c4c1776c47d07f0a0))
- **custom-element:** `useShadowRoot()` helper ([5a1a89b](https://github.com/vuejs/core/commit/5a1a89bd6178cc2f84ba91da7d72aee4c6ec1282)), closes [#6113](https://github.com/vuejs/core/issues/6113) [#8195](https://github.com/vuejs/core/issues/8195)
- **custom-element:** expose `this.$host` in Options API ([1ef8f46](https://github.com/vuejs/core/commit/1ef8f46af0cfdec2fed66376772409e0aa25ad50))
- **custom-element:** inject child components styles to custom element shadow root ([#11517](https://github.com/vuejs/core/issues/11517)) ([56c76a8](https://github.com/vuejs/core/commit/56c76a8b05c45f782ed3a16ec77c6292b71a17f1)), closes [#4662](https://github.com/vuejs/core/issues/4662) [#7941](https://github.com/vuejs/core/issues/7941) [#7942](https://github.com/vuejs/core/issues/7942)
- **custom-element:** support configurable app instance in defineCustomElement ([6758c3c](https://github.com/vuejs/core/commit/6758c3cd0427f97394d95168c655dae3b7fa62cd)), closes [#4356](https://github.com/vuejs/core/issues/4356) [#4635](https://github.com/vuejs/core/issues/4635)
- **custom-element:** support css `:host` selector by applying css vars on host element ([#8830](https://github.com/vuejs/core/issues/8830)) ([03a9ea2](https://github.com/vuejs/core/commit/03a9ea2b88df0842a820e09f7445c4b9189e3fcb)), closes [#8826](https://github.com/vuejs/core/issues/8826)
- **custom-element:** support emit with options ([e181bff](https://github.com/vuejs/core/commit/e181bff6dc39d5cef92000c10291243c7d6e4d08)), closes [#7605](https://github.com/vuejs/core/issues/7605)
- **custom-element:** support expose on customElement ([#6256](https://github.com/vuejs/core/issues/6256)) ([af838c1](https://github.com/vuejs/core/commit/af838c1b5ec23552e52e64ffa7db0eb0246c3624)), closes [#5540](https://github.com/vuejs/core/issues/5540)
- **custom-element:** support `nonce` option for injected style tags ([bb4a02a](https://github.com/vuejs/core/commit/bb4a02a70c30e739a3c705b3d96d09258d7d7ded)), closes [#6530](https://github.com/vuejs/core/issues/6530)
- **custom-element:** support passing custom-element-specific options via 2nd argument of defineCustomElement ([60a88a2](https://github.com/vuejs/core/commit/60a88a2b129714186cf6ba66f30f31d733d0311e))
- **custom-element:** support `shadowRoot: false` in `defineCustomElement()` ([37d2ce5](https://github.com/vuejs/core/commit/37d2ce5d8e0fac4a00064f02b05f91f69b2d5d5e)), closes [#4314](https://github.com/vuejs/core/issues/4314) [#4404](https://github.com/vuejs/core/issues/4404)
### Teleport
- **teleport:** support deferred Teleport ([#11387](https://github.com/vuejs/core/issues/11387)) ([59a3e88](https://github.com/vuejs/core/commit/59a3e88903b10ac2278170a44d5a03f24fef23ef)), closes [#2015](https://github.com/vuejs/core/issues/2015) [#11386](https://github.com/vuejs/core/issues/11386)
- **teleport/transition:** support directly nesting Teleport inside Transition ([#6548](https://github.com/vuejs/core/issues/6548)) ([0e6e3c7](https://github.com/vuejs/core/commit/0e6e3c7eb0e5320b7c1818e025cb4a490fede9c0)), closes [#5836](https://github.com/vuejs/core/issues/5836)
### Misc
- **runtime-core:** `useTemplateRef()` ([3ba70e4](https://github.com/vuejs/core/commit/3ba70e49b5856c53611c314d4855d679a546a7df))
- **runtime-core:** add `app.onUnmount()` for registering cleanup functions ([#4619](https://github.com/vuejs/core/issues/4619)) ([582a3a3](https://github.com/vuejs/core/commit/582a3a382b1adda565bac576b913a88d9e8d7a9e)), closes [#4516](https://github.com/vuejs/core/issues/4516)
- **runtime-core:** add `app.config.throwUnhandledErrorInProduction` ([f476b7f](https://github.com/vuejs/core/commit/f476b7f030f2dd427ca655fcea36f4933a4b4da0)), closes [#7876](https://github.com/vuejs/core/issues/7876)
- **runtime-dom:** Trusted Types compatibility ([#10844](https://github.com/vuejs/core/issues/10844)) ([6d4eb94](https://github.com/vuejs/core/commit/6d4eb94853ed1b2b1675bdd7d5ba9c75cc6daed5))
- **compiler-core:** support `Symbol` global in template expressions ([#9069](https://github.com/vuejs/core/issues/9069)) ([a501a85](https://github.com/vuejs/core/commit/a501a85a7c910868e01a5c70a2abea4e9d9e87f3))
- **types:** export more emit related types ([#11017](https://github.com/vuejs/core/issues/11017)) ([189573d](https://github.com/vuejs/core/commit/189573dcee2a16bd3ed36ff5589d43f535e5e733))
* **types:** add loading prop to iframe ([#11767](https://github.com/vuejs/core/issues/11767)) ([d86fe0e](https://github.com/vuejs/core/commit/d86fe0ec002901dc359a0e85f3a421b4a8538d68))
### Internals
- **reactivity:** store value cache on CustomRefs impls ([#11539](https://github.com/vuejs/core/issues/11539)) ([e044b6e](https://github.com/vuejs/core/commit/e044b6e737efc9433d1d84590036b82280da6292))
- **types:** provide internal options for directly using user types in language tools ([#10801](https://github.com/vuejs/core/issues/10801)) ([75c8cf6](https://github.com/vuejs/core/commit/75c8cf63a1ef30ac84f91282d66ad3f57c6612e9))
- **types:** provide internal options for using refs type in language tools ([#11492](https://github.com/vuejs/core/issues/11492)) ([5ffd1a8](https://github.com/vuejs/core/commit/5ffd1a89455807d5069eb2c28eba0379641dca76))
## Bug Fixes
* **compiler-sfc:** fix import usage check for kebab-case same name shorthand binding ([0f7c0e5](https://github.com/vuejs/core/commit/0f7c0e5dc0eedada7a5194db87fd0a7dbd1d3354)), closes [#11745](https://github.com/vuejs/core/issues/11745) [#11754](https://github.com/vuejs/core/issues/11754)
* **cssVars:** correctly escape double quotes in SSR ([#11784](https://github.com/vuejs/core/issues/11784)) ([7b5b6e0](https://github.com/vuejs/core/commit/7b5b6e0275f35748dca6d7eb842f8ab2364c6b9a)), closes [#11779](https://github.com/vuejs/core/issues/11779)
* **deps:** update dependency postcss to ^8.4.44 ([#11774](https://github.com/vuejs/core/issues/11774)) ([cb843e0](https://github.com/vuejs/core/commit/cb843e0be31f9e563ccfc30eca0c06f2a224b505))
* **hydration:** escape css var name to avoid mismatch ([#11739](https://github.com/vuejs/core/issues/11739)) ([ca12e77](https://github.com/vuejs/core/commit/ca12e776bc53aaa31f2df6bb6edc6be1b2f10c37)), closes [#11735](https://github.com/vuejs/core/issues/11735)
* **hydration:** handle text nodes with 0 during hydration ([#11772](https://github.com/vuejs/core/issues/11772)) ([c756da2](https://github.com/vuejs/core/commit/c756da24b2d8635cf52b4c7d3abf5bf938852cc5)), closes [#11771](https://github.com/vuejs/core/issues/11771)
* **reactivity:** correctly handle method calls on user-extended arrays ([#11760](https://github.com/vuejs/core/issues/11760)) ([9817c80](https://github.com/vuejs/core/commit/9817c80187bec6a3344c74d65fac92262de0fcdd)), closes [#11759](https://github.com/vuejs/core/issues/11759)
* **runtime-dom:** avoid unnecessary prop patch for checkbox ([#11657](https://github.com/vuejs/core/issues/11657)) ([c3ce9fe](https://github.com/vuejs/core/commit/c3ce9fe3d8fc27d864ce7148cd36da882cfc21ab)), closes [#11647](https://github.com/vuejs/core/issues/11647)
* **runtime-dom:** prevent unnecessary DOM update from v-model ([#11656](https://github.com/vuejs/core/issues/11656)) ([b1be9bd](https://github.com/vuejs/core/commit/b1be9bd64f2c7c4286fecb25bad5d5edd49efce9)), closes [#11647](https://github.com/vuejs/core/issues/11647)
* **server-renderer:** Fix call to serverPrefetch in server renderer with an async setup ([#10893](https://github.com/vuejs/core/issues/10893)) ([6039e25](https://github.com/vuejs/core/commit/6039e25e04a8c1db5821955f011d57f1615807ab))
* **server-renderer:** render `className` during SSR ([#11722](https://github.com/vuejs/core/issues/11722)) ([52cdb0f](https://github.com/vuejs/core/commit/52cdb0f991dc154ae32a2900874d5dbc4e078565))
* **types/defineModel:** allow getter and setter types to be unrelated ([#11699](https://github.com/vuejs/core/issues/11699)) ([fe07f70](https://github.com/vuejs/core/commit/fe07f7073617df358c2f8cbc3de433359e873c96)), closes [#11697](https://github.com/vuejs/core/issues/11697)
# [3.5.0-rc.1](https://github.com/vuejs/core/compare/v3.5.0-beta.3...v3.5.0-rc.1) (2024-08-29)
### Bug Fixes
* **compiler-sfc:** skip circular tsconfig project reference ([#11680](https://github.com/vuejs/core/issues/11680)) ([9c4c2e5](https://github.com/vuejs/core/commit/9c4c2e51b045218d0c5ca64b4fb58b17d5d580cc)), closes [#11382](https://github.com/vuejs/core/issues/11382)
* **custom-element:** handle keys set on custom elements ([#11655](https://github.com/vuejs/core/issues/11655)) ([f1d1831](https://github.com/vuejs/core/commit/f1d1831f07fe52d5681a5ec9ec310572463abf26)), closes [#11641](https://github.com/vuejs/core/issues/11641)
* **deps:** update dependency monaco-editor to ^0.51.0 ([#11713](https://github.com/vuejs/core/issues/11713)) ([434f8a9](https://github.com/vuejs/core/commit/434f8a97c77f68aeae050e9e4e1f54f63bc4bd26))
* **keep-alive:** reset keep alive flag when the component is removed from include ([#11718](https://github.com/vuejs/core/issues/11718)) ([29c321b](https://github.com/vuejs/core/commit/29c321bfd33f9197244dec3d027077e63b2cdf2f)), closes [#11717](https://github.com/vuejs/core/issues/11717)
* **reactivity:** avoid infinite recursion when mutating ref wrapped in reactive ([313e4bf](https://github.com/vuejs/core/commit/313e4bf55214ac1e334a99c329a3ba5daca4f156)), closes [#11696](https://github.com/vuejs/core/issues/11696)
* **reactivity:** ensure watcher with once: true are properly removed from effect scope ([#11665](https://github.com/vuejs/core/issues/11665)) ([fbc0c42](https://github.com/vuejs/core/commit/fbc0c42bcf6dea5a6ae664223fa19d4375ca39f0))
* **runtime-dom:** setting innerHTML when patching props should go through trusted types ([d875de5](https://github.com/vuejs/core/commit/d875de54e9e03e0768fe550aa4c4886a4baf3bd7))
* **types:** GlobalDirective / GlobalComponents should not be records ([42e8df6](https://github.com/vuejs/core/commit/42e8df62030e7f2c287d9103f045e67b34a63e3b))
# [3.5.0-beta.3](https://github.com/vuejs/core/compare/v3.5.0-beta.2...v3.5.0-beta.3) (2024-08-20)
### Bug Fixes
* **reactivity:** extended methods respect reactive ([#11629](https://github.com/vuejs/core/issues/11629)) ([9de1d10](https://github.com/vuejs/core/commit/9de1d101f98bf6081f41038f6974826f190330a0)), closes [#11628](https://github.com/vuejs/core/issues/11628)
* **runtime-core:** correct type inference for PascalCase emits ([#11579](https://github.com/vuejs/core/issues/11579)) ([d7d0371](https://github.com/vuejs/core/commit/d7d0371e74707ee601020f67de88e091cdae2673)), closes [vuejs/language-tools#4269](https://github.com/vuejs/language-tools/issues/4269)
* **runtime-core:** ensure suspense content inherit scopeId ([#10652](https://github.com/vuejs/core/issues/10652)) ([ac2a410](https://github.com/vuejs/core/commit/ac2a410e46392db63ca4ed2db3c0fa71ebe1e855)), closes [#5148](https://github.com/vuejs/core/issues/5148)
* **runtime-core:** pre jobs without an id should run first ([#7746](https://github.com/vuejs/core/issues/7746)) ([b332f80](https://github.com/vuejs/core/commit/b332f80f0edb018229a23b43b93bb402b6368a3c))
* **ssr:** apply ssr props to the the fallback vnode-based branch in ssr ([#7247](https://github.com/vuejs/core/issues/7247)) ([98b83e8](https://github.com/vuejs/core/commit/98b83e86d16c635547a1e735e5fb675aea2f0f1b)), closes [#6123](https://github.com/vuejs/core/issues/6123)
* **types/custom-element:** `defineCustomElement` with required props ([#11578](https://github.com/vuejs/core/issues/11578)) ([5e0f6d5](https://github.com/vuejs/core/commit/5e0f6d5f8fe7c4eb8f247357c3e2e281726f36db))
* **types:** strip non-prop default values from return type of withDefaults ([#9998](https://github.com/vuejs/core/issues/9998)) ([44973bb](https://github.com/vuejs/core/commit/44973bb3e790db7d8aa7af4eda21c80cac73a8de)), closes [#9899](https://github.com/vuejs/core/issues/9899)
* **watch:** handle errors in computed used as watch source ([#11626](https://github.com/vuejs/core/issues/11626)) ([8bcaad4](https://github.com/vuejs/core/commit/8bcaad4a32cf0f1f89e0259f6a53036620b7fe9f)), closes [#11624](https://github.com/vuejs/core/issues/11624)
### Features
* **reactivity:** base `watch`, `getCurrentWatcher`, and `onWatcherCleanup` ([#9927](https://github.com/vuejs/core/issues/9927)) ([205e5b5](https://github.com/vuejs/core/commit/205e5b5e277243c3af2c937d9bd46cf671296b72))
### Performance Improvements
* **runtime-core:** use `apply` to avoid spreading. ([#5985](https://github.com/vuejs/core/issues/5985)) ([bb6babc](https://github.com/vuejs/core/commit/bb6babca8f206615d4e246457cd54d21bb3bc5a4))
# [3.5.0-beta.2](https://github.com/vuejs/core/compare/v3.5.0-beta.1...v3.5.0-beta.2) (2024-08-15)
### Bug Fixes
* **build:** revert entities to 4.5 to avoid runtime resolution errors ([e9e0815](https://github.com/vuejs/core/commit/e9e08155bf8d00c3327ed7371330eb2ae467e560)), closes [#11603](https://github.com/vuejs/core/issues/11603)
* **compiler-core:** use ast-based check for function expressions when possible ([5861229](https://github.com/vuejs/core/commit/58612294757480974e667652ede5bbcf72b1089d)), closes [#11615](https://github.com/vuejs/core/issues/11615)
* **compiler-sfc:** fix prefixIdentifier default value ([3d6f015](https://github.com/vuejs/core/commit/3d6f01571b3fb61b32da599d0419eff4e3ebb231))
* **compiler-sfc:** handle keyof operator with index object ([#11581](https://github.com/vuejs/core/issues/11581)) ([fe00815](https://github.com/vuejs/core/commit/fe008152c0612ff3ecc7ad88e7e66a06b1b2bc3f))
* **custom-element:** keep instance.isCE for backwards compat ([e19fc27](https://github.com/vuejs/core/commit/e19fc270428b59456fee43224990138c4d6ccb2d))
* **deps:** update dependency postcss to ^8.4.41 ([#11585](https://github.com/vuejs/core/issues/11585)) ([4c4e12a](https://github.com/vuejs/core/commit/4c4e12ae28d67d616924b0601e68adc551959971))
* **keep-alive:** ensure include/exclude regexp work with global flag ([#11595](https://github.com/vuejs/core/issues/11595)) ([3653bc0](https://github.com/vuejs/core/commit/3653bc0f45d6fedf84e29b64ca52584359c383c0))
* **reactivity:** ensure extended method arguments are not lost ([#11574](https://github.com/vuejs/core/issues/11574)) ([4085def](https://github.com/vuejs/core/commit/4085def1bae42d01ee3c22c731cc4a02096464ee)), closes [#11570](https://github.com/vuejs/core/issues/11570)
* **reactivity:** sync watch should be executed correctly ([#11589](https://github.com/vuejs/core/issues/11589)) ([3bda3e8](https://github.com/vuejs/core/commit/3bda3e83fd9e2fbe451a1c79dae82ff6a7467683)), closes [#11577](https://github.com/vuejs/core/issues/11577)
* **types/computed:** ensure type safety for `WritableComputedRef` ([#11608](https://github.com/vuejs/core/issues/11608)) ([5cf5a16](https://github.com/vuejs/core/commit/5cf5a1620d9a97382d386c277265d9dd051fe484))
* **types:** add fallback stub for DOM types when DOM lib is absent ([#11598](https://github.com/vuejs/core/issues/11598)) ([fee6697](https://github.com/vuejs/core/commit/fee669764fbf475adce9e47a7a73b4937ab31ffc))
### Features
* **deprecated:** remove deprecated parseExpressions option ([#11597](https://github.com/vuejs/core/issues/11597)) ([4e7d5db](https://github.com/vuejs/core/commit/4e7d5db4d276a5d4aaf3af7d43cfd28c171db307))
# [3.5.0-beta.1](https://github.com/vuejs/core/compare/v3.4.37...v3.5.0-beta.1) (2024-08-08)
@ -119,7 +361,7 @@
## Previous Changelogs
### 3.4.x (2023-10-28 - 2024-08-08)
### 3.4.x (2023-10-28 - 2024-08-15)
See [3.4 changelog](./changelogs/CHANGELOG-3.4.md)

View File

@ -10,6 +10,6 @@ Please note that we do not consider XSS via template expressions a valid attack
We would like to thank the following security researchers for responsibly disclosing security issues to us.
- Jeet Pal - [@jeetpal2007](https://github.com/jeetpal2007) | [Email](jeetpal2007@gmail.com) | [LinkedIn](https://in.linkedin.com/in/jeet-pal-22601a290)
- Jeet Pal - [@jeetpal2007](https://github.com/jeetpal2007) | [Email](mailto:jeetpal2007@gmail.com) | [LinkedIn](https://in.linkedin.com/in/jeet-pal-22601a290)
- Mix - [@mnixry](https://github.com/mnixry)
- Aviv Keller - [@RedYetiDev](https://github.com/redyetidev) | [LinkedIn](https://www.linkedin.com/in/redyetidev) <redyetidev@gmail.com>

View File

@ -1,3 +1,15 @@
## [3.4.38](https://github.com/vuejs/core/compare/v3.4.37...v3.4.38) (2024-08-15)
### Bug Fixes
* **build:** revert entities to 4.5 to avoid runtime resolution errors ([f349af7](https://github.com/vuejs/core/commit/f349af7b65b9f8605d8b7bafcc06c25ab1f2daf0)), closes [#11603](https://github.com/vuejs/core/issues/11603)
* **compiler-core:** use ast-based check for function expressions when possible ([236cac3](https://github.com/vuejs/core/commit/236cac3ff285890b8468dc827c463d87a91e516f)), closes [#11615](https://github.com/vuejs/core/issues/11615)
* **compiler-sfc:** handle keyof operator with index object ([#11581](https://github.com/vuejs/core/issues/11581)) ([74d26db](https://github.com/vuejs/core/commit/74d26dbbe3cf2f70d1b772284eec6743ea946f6d))
* **types:** add fallback stub for DOM types when DOM lib is absent ([#11598](https://github.com/vuejs/core/issues/11598)) ([4db0085](https://github.com/vuejs/core/commit/4db0085de316e1b773f474597915f9071d6ae6c6))
## [3.4.37](https://github.com/vuejs/core/compare/v3.4.36...v3.4.37) (2024-08-08)
@ -12,6 +24,7 @@
* Revert "fix(types/ref): correct type inference for nested refs ([#11536](https://github.com/vuejs/core/issues/11536))" ([3a56315](https://github.com/vuejs/core/commit/3a56315f94bc0e11cfbb288b65482ea8fc3a39b4))
* **runtime-core:** fix warning for missing event handler ([#11489](https://github.com/vuejs/core/issues/11489)) ([e359ff0](https://github.com/vuejs/core/commit/e359ff0046286aee03fe31656c023677be457e07)), closes [#4803](https://github.com/vuejs/core/issues/4803) [#8268](https://github.com/vuejs/core/issues/8268)
* **runtime-core:** prioritize using the provides from currentApp in nested createApp ([#11502](https://github.com/vuejs/core/issues/11502)) ([7e75de0](https://github.com/vuejs/core/commit/7e75de002f08076a02c9361a58fa1d0af1772964)), closes [#11488](https://github.com/vuejs/core/issues/11488)
* Note: this change will break `inject` calls inside Pinia stores that expects to be able to inject provided values from the component using the store. This is expected because the usage is relying on previously incorrect behavior.
* **runtime-dom:** apply css vars before mount ([#11538](https://github.com/vuejs/core/issues/11538)) ([fdc2a31](https://github.com/vuejs/core/commit/fdc2a31dbd4196d6432be16767a1bfdab1240d49)), closes [#11533](https://github.com/vuejs/core/issues/11533)
* **ssr:** ensure content is valid when rendering normal slot ([#11491](https://github.com/vuejs/core/issues/11491)) ([6c90324](https://github.com/vuejs/core/commit/6c903248703e2413c6197b9ad4d535f31c8eac39)), closes [#11326](https://github.com/vuejs/core/issues/11326)
* **types/ref:** correct type inference for nested refs ([#11536](https://github.com/vuejs/core/issues/11536)) ([536f623](https://github.com/vuejs/core/commit/536f62332c455ba82ef2979ba634b831f91928ba)), closes [#11532](https://github.com/vuejs/core/issues/11532) [#11537](https://github.com/vuejs/core/issues/11537)

View File

@ -76,7 +76,11 @@ export default tseslint.config(
// tests, no restrictions (runs in Node / Vitest with jsdom)
{
files: ['**/__tests__/**', 'packages/dts-test/**'],
files: [
'**/__tests__/**',
'packages-private/dts-test/**',
'packages-private/dts-build-test/**',
],
plugins: { vitest },
languageOptions: {
globals: {
@ -120,8 +124,8 @@ export default tseslint.config(
// Private package, browser only + no syntax restrictions
{
files: [
'packages/template-explorer/**',
'packages/sfc-playground/**',
'packages-private/template-explorer/**',
'packages-private/sfc-playground/**',
'playground/**',
],
rules: {

View File

@ -1,14 +1,14 @@
{
"private": true,
"version": "3.5.0-beta.1",
"packageManager": "pnpm@9.6.0",
"version": "3.5.6",
"packageManager": "pnpm@9.10.0",
"type": "module",
"scripts": {
"dev": "node scripts/dev.js vue vue-vapor",
"build": "node scripts/build.js",
"build-dts": "tsc -p tsconfig.build-browser.json && tsc -p tsconfig.build-node.json && rollup -c rollup.dts.config.js",
"clean": "rimraf packages/*/dist temp .eslintcache",
"size": "run-s \"size-*\" && tsx scripts/usage-size.ts",
"build-dts": "tsc -p tsconfig.build.json --noCheck && rollup -c rollup.dts.config.js",
"clean": "rimraf --glob packages/*/dist temp .eslintcache",
"size": "run-s \"size-*\" && node scripts/usage-size.js",
"size-global": "node scripts/build.js vue vue-vapor runtime-dom runtime-vapor compiler-dom compiler-vapor -f global -p --size",
"size-esm-runtime": "node scripts/build.js vue vue-vapor -f esm-bundler-runtime",
"size-esm": "node scripts/build.js runtime-shared runtime-dom runtime-vapor runtime-core reactivity shared -f esm-bundler",
@ -17,11 +17,11 @@
"format": "prettier --write --cache .",
"format-check": "prettier --check --cache .",
"test": "vitest",
"test-unit": "vitest -c vitest.unit.config.ts",
"test-e2e": "node scripts/build.js vue vue-vapor -f global -d && vitest -c vitest.e2e.config.ts",
"test-unit": "vitest --project unit",
"test-e2e": "node scripts/build.js vue vue-vapor -f global -d && vitest --project e2e",
"test-dts": "run-s build-dts test-dts-only",
"test-dts-only": "tsc -p packages/dts-built-test/tsconfig.json && tsc -p ./packages/dts-test/tsconfig.test.json",
"test-coverage": "vitest -c vitest.unit.config.ts --coverage",
"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",
"test-bench": "vitest bench",
"release": "node scripts/release.js",
"changelog": "conventional-changelog -p angular -i CHANGELOG.md -s",
@ -29,17 +29,17 @@
"dev-prepare-cjs": "node scripts/prepare-cjs.js || npm run build-all-cjs",
"dev-compiler": "run-p \"dev template-explorer\" serve",
"dev-sfc": "run-s dev-prepare-cjs dev-sfc-run",
"dev-sfc-serve": "vite packages/sfc-playground --host",
"dev-sfc-serve": "vite packages-private/sfc-playground --host",
"dev-sfc-run": "run-p \"dev compiler-sfc -f esm-browser\" \"dev vue -if esm-bundler-runtime\" \"dev vue -ipf esm-browser-runtime\" \"dev server-renderer -if esm-bundler\" dev-sfc-serve",
"dev-vapor": "pnpm -C playground run dev",
"serve": "serve",
"open": "open http://localhost:3000/packages/template-explorer/local.html",
"open": "open http://localhost:3000/packages-private/template-explorer/local.html",
"build-sfc-playground": "run-s build-all-cjs build-runtime-esm build-browser-esm build-ssr-esm build-sfc-playground-self",
"build-all-cjs": "node scripts/build.js vue runtime compiler reactivity shared -af cjs",
"build-runtime-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler-runtime && node scripts/build.js vue -f esm-browser-runtime",
"build-browser-esm": "node scripts/build.js runtime reactivity shared -af esm-bundler && node scripts/build.js vue -f esm-bundler && node scripts/build.js vue -f esm-browser",
"build-ssr-esm": "node scripts/build.js compiler-sfc server-renderer vue-vapor -f esm-browser",
"build-sfc-playground-self": "cd packages/sfc-playground && npm run build",
"build-sfc-playground-self": "cd packages-private/sfc-playground && npm run build",
"preinstall": "npx only-allow pnpm",
"postinstall": "simple-git-hooks"
},
@ -66,36 +66,36 @@
"@rollup/plugin-json": "^6.1.0",
"@rollup/plugin-node-resolve": "^15.2.3",
"@rollup/plugin-replace": "5.0.4",
"@swc/core": "^1.7.6",
"@swc/core": "^1.7.26",
"@types/hash-sum": "^1.0.2",
"@types/node": "^20.14.14",
"@types/node": "^20.16.5",
"@types/semver": "^7.5.8",
"@types/serve-handler": "^6.1.4",
"@vitest/coverage-istanbul": "^1.6.0",
"@vitest/ui": "^1.6.0",
"@vitest/coverage-v8": "^2.1.1",
"@vitest/ui": "^2.1.1",
"@vue/consolidate": "1.0.0",
"conventional-changelog-cli": "^5.0.0",
"enquirer": "^2.4.1",
"esbuild": "^0.23.0",
"esbuild": "^0.23.1",
"esbuild-plugin-polyfill-node": "^0.3.0",
"eslint": "^9.8.0",
"eslint-plugin-import-x": "^3.1.0",
"eslint": "^9.10.0",
"eslint-plugin-import-x": "^4.2.1",
"eslint-plugin-vitest": "^0.5.4",
"estree-walker": "catalog:",
"jsdom": "^24.1.1",
"lint-staged": "^15.2.8",
"jsdom": "^25.0.0",
"lint-staged": "^15.2.10",
"lodash": "^4.17.21",
"magic-string": "^0.30.11",
"markdown-table": "^3.0.3",
"marked": "^13.0.3",
"npm-run-all2": "^6.2.2",
"picocolors": "^1.0.1",
"marked": "13.0.3",
"npm-run-all2": "^6.2.3",
"picocolors": "^1.1.0",
"prettier": "^3.3.3",
"pretty-bytes": "^6.1.1",
"pug": "^3.0.3",
"puppeteer": "~22.15.0",
"puppeteer": "~23.3.0",
"rimraf": "^6.0.1",
"rollup": "^4.20.0",
"rollup": "^4.21.3",
"rollup-plugin-dts": "^6.1.1",
"rollup-plugin-esbuild": "^6.1.1",
"rollup-plugin-polyfill-node": "^0.13.0",
@ -104,12 +104,11 @@
"serve-handler": "^6.1.5",
"simple-git-hooks": "^2.11.1",
"todomvc-app-css": "^2.4.3",
"tslib": "^2.6.3",
"tsx": "^4.16.5",
"typescript": "~5.5.4",
"typescript-eslint": "^8.0.0",
"tslib": "^2.7.0",
"typescript": "~5.6.2",
"typescript-eslint": "^8.5.0",
"vite": "catalog:",
"vitest": "^1.6.0"
"vitest": "^2.1.1"
},
"pnpm": {
"peerDependencyRules": {

View File

@ -2,4 +2,4 @@
This package is private and for testing only. It is used to verify edge cases for external libraries that build their types using Vue core types - e.g. Vuetify as in [#8376](https://github.com/vuejs/core/issues/8376).
When running the `build-dts` task, this package's types are built alongside other packages. Then, during `test-dts-only` it is imported and used in [`packages/dts-test/built.test-d.ts`](https://github.com/vuejs/core/blob/main/packages/dts-test/built.test-d.ts) to verify that the built types work correctly.
When running the `build-dts` task, this package's types are built alongside other packages. Then, during `test-dts-only` it is imported and used in [`packages-private/dts-test/built.test-d.ts`](https://github.com/vuejs/core/blob/main/packages-private/dts-test/built.test-d.ts) to verify that the built types work correctly.

View File

@ -1,5 +1,5 @@
{
"name": "@vue/dts-built-test",
"name": "dts-built-test",
"private": true,
"version": "0.0.0",
"types": "dist/index.d.ts",

View File

@ -4,4 +4,4 @@ Tests TypeScript types to ensure the types remain as expected.
- This directory is included in the root `tsconfig.json`, where package imports are aliased to `src` directories, so in IDEs and the `pnpm check` script the types are validated against source code.
- When running `tsc` with `packages/dts-test/tsconfig.test.json`, packages are resolved using normal `node` resolution, so the types are validated against actual **built** types. This requires the types to be built first via `pnpm build-dts`.
- When running `tsc` with `packages-private/dts-test/tsconfig.test.json`, packages are resolved using normal `node` resolution, so the types are validated against actual **built** types. This requires the types to be built first via `pnpm build-dts`.

View File

@ -0,0 +1,19 @@
import { createApp } from 'vue'
import { expectType } from './utils'
const app = createApp({})
app.directive<HTMLElement, string, 'prevent' | 'stop', 'arg1' | 'arg2'>(
'custom',
{
mounted(el, binding) {
expectType<HTMLElement>(el)
expectType<string>(binding.value)
expectType<{ prevent: boolean; stop: boolean }>(binding.modifiers)
expectType<'arg1' | 'arg2'>(binding.arg!)
// @ts-expect-error not any
expectType<number>(binding.value)
},
},
)

View File

@ -1,4 +1,4 @@
import { CustomPropsNotErased } from '@vue/dts-built-test'
import { CustomPropsNotErased } from 'dts-built-test/src/index'
import { describe, expectType } from './utils'
declare module 'vue' {

View File

@ -480,6 +480,26 @@ describe('type inference w/ options API', () => {
})
})
// #4051
describe('type inference w/ empty prop object', () => {
const MyComponent = defineComponent({
props: {},
setup(props) {
return {}
},
render() {},
})
expectType<JSX.Element>(<MyComponent />)
// AllowedComponentProps
expectType<JSX.Element>(<MyComponent class={'foo'} />)
// ComponentCustomProps
expectType<JSX.Element>(<MyComponent custom={1} />)
// VNodeProps
expectType<JSX.Element>(<MyComponent key="1" />)
// @ts-expect-error
expectError(<MyComponent other="other" />)
})
describe('with mixins', () => {
const MixinA = defineComponent({
emits: ['bar'],
@ -906,12 +926,15 @@ describe('emits', () => {
emits: {
click: (n: number) => typeof n === 'number',
input: (b: string) => b.length > 1,
Focus: (f: boolean) => !!f,
},
setup(props, { emit }) {
expectType<((n: number) => boolean) | undefined>(props.onClick)
expectType<((b: string) => boolean) | undefined>(props.onInput)
expectType<((f: boolean) => boolean) | undefined>(props.onFocus)
emit('click', 1)
emit('input', 'foo')
emit('Focus', true)
// @ts-expect-error
emit('nope')
// @ts-expect-error
@ -922,6 +945,10 @@ describe('emits', () => {
emit('input')
// @ts-expect-error
emit('input', 1)
// @ts-expect-error
emit('focus')
// @ts-expect-error
emit('focus', true)
},
created() {
this.$emit('click', 1)
@ -936,6 +963,10 @@ describe('emits', () => {
this.$emit('input')
// @ts-expect-error
this.$emit('input', 1)
// @ts-expect-error
this.$emit('focus')
// @ts-expect-error
this.$emit('focus', true)
},
mounted() {
// #3599
@ -954,6 +985,10 @@ describe('emits', () => {
this.$emit('input')
// @ts-expect-error
this.$emit('input', 1)
// @ts-expect-error
this.$emit('focus')
// @ts-expect-error
this.$emit('focus', true)
})
},
})
@ -1006,6 +1041,18 @@ describe('emits', () => {
},
})
// #11803 manual props annotation in setup()
const Hello = defineComponent({
name: 'HelloWorld',
inheritAttrs: false,
props: { foo: String },
emits: {
customClick: (args: string) => typeof args === 'string',
},
setup(props: { foo?: string }) {},
})
;<Hello onCustomClick={() => {}} />
// without emits
defineComponent({
setup(props, { emit }) {
@ -1775,6 +1822,15 @@ describe('__typeRefs backdoor, object syntax', () => {
expectType<number>(refs.child.$refs.foo)
})
describe('__typeEl backdoor', () => {
const Comp = defineComponent({
__typeEl: {} as HTMLAnchorElement,
})
const c = new Comp()
expectType<HTMLAnchorElement>(c.$el)
})
defineComponent({
props: {
foo: [String, null],

View File

@ -99,4 +99,37 @@ describe('defineCustomElement using defineComponent return type', () => {
expectType<number | undefined>(instance.a)
instance.a = 42
})
test('with required props', () => {
const Comp1Vue = defineComponent({
props: {
a: { type: Number, required: true },
},
})
const Comp = defineCustomElement(Comp1Vue)
expectType<VueElementConstructor>(Comp)
const instance = new Comp()
expectType<number>(instance.a)
instance.a = 42
})
test('with default props', () => {
const Comp1Vue = defineComponent({
props: {
a: {
type: Number,
default: 1,
validator: () => true,
},
},
emits: ['click'],
})
const Comp = defineCustomElement(Comp1Vue)
expectType<VueElementConstructor>(Comp)
const instance = new Comp()
expectType<number>(instance.a)
instance.a = 42
})
})

View File

@ -4,6 +4,6 @@
"version": "0.0.0",
"dependencies": {
"vue": "workspace:*",
"@vue/dts-built-test": "workspace:*"
"dts-built-test": "workspace:*"
}
}

View File

@ -209,6 +209,14 @@ describe('allow computed getter and setter types to be unrelated', () => {
expectType<string>(c.value)
})
describe('Type safety for `WritableComputedRef` and `ComputedRef`', () => {
// @ts-expect-error
const writableComputed: WritableComputedRef<string> = computed(() => '')
// should allow
const immutableComputed: ComputedRef<string> = writableComputed
expectType<ComputedRef<string>>(immutableComputed)
})
// shallowRef
type Status = 'initial' | 'ready' | 'invalidating'
const shallowStatus = shallowRef<Status>('initial')

View File

@ -227,6 +227,19 @@ describe('withDefaults w/ boolean type', () => {
expectType<boolean | undefined>(res2.bool)
})
describe('withDefaults w/ defineProp type is different from the defaults type', () => {
const res1 = withDefaults(
defineProps<{
bool?: boolean
}>(),
{ bool: false, value: false },
)
expectType<boolean>(res1.bool)
// @ts-expect-error
res1.value
})
describe('defineProps w/ runtime declaration', () => {
// runtime declaration
const props = defineProps({
@ -414,6 +427,51 @@ describe('defineModel', () => {
defineModel<string>({ default: 123 })
// @ts-expect-error unknown props option
defineModel({ foo: 123 })
// unrelated getter and setter types
{
const modelVal = defineModel({
get(_: string[]): string {
return ''
},
set(_: number) {
return 1
},
})
expectType<string | undefined>(modelVal.value)
modelVal.value = 1
modelVal.value = undefined
// @ts-expect-error
modelVal.value = 'foo'
const [modelVal2] = modelVal
expectType<string | undefined>(modelVal2.value)
modelVal2.value = 1
modelVal2.value = undefined
// @ts-expect-error
modelVal.value = 'foo'
const count = defineModel('count', {
get(_: string[]): string {
return ''
},
set(_: number) {
return ''
},
})
expectType<string | undefined>(count.value)
count.value = 1
count.value = undefined
// @ts-expect-error
count.value = 'foo'
const [count2] = count
expectType<string | undefined>(count2.value)
count2.value = 1
count2.value = undefined
// @ts-expect-error
count2.value = 'foo'
}
})
describe('useModel', () => {

View File

@ -121,3 +121,5 @@ expectType<JSX.Element>(
xmlns="http://www.w3.org/2000/svg"
/>,
)
// details
expectType<JSX.Element>(<details name="details" />)

8
packages-private/global.d.ts vendored Normal file
View File

@ -0,0 +1,8 @@
/// <reference types="vite/client" />
// Global compile-time constants
declare var __COMMIT__: string
declare module 'file-saver' {
export function saveAs(blob: any, name: any): void
}

View File

@ -9,11 +9,11 @@
"serve": "vite preview"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"@vitejs/plugin-vue": "catalog:",
"vite": "catalog:"
},
"dependencies": {
"@vue/repl": "^4.3.1",
"@vue/repl": "^4.4.2",
"file-saver": "^2.0.5",
"jszip": "^3.10.1",
"vue": "workspace:*"

View File

Before

Width:  |  Height:  |  Size: 261 B

After

Width:  |  Height:  |  Size: 261 B

View File

@ -25,6 +25,12 @@ setVH()
const useSSRMode = ref(false)
const useVaporMode = ref(true)
const AUTO_SAVE_STORAGE_KEY = 'vue-sfc-playground-auto-save'
const initAutoSave: boolean = JSON.parse(
localStorage.getItem(AUTO_SAVE_STORAGE_KEY) ?? 'true',
)
const autoSave = ref(initAutoSave)
const {
vueVersion,
productionMode,
@ -163,6 +169,11 @@ function toggleVapor() {
useVaporMode.value = !useVaporMode.value
}
function toggleAutoSave() {
autoSave.value = !autoSave.value
localStorage.setItem(AUTO_SAVE_STORAGE_KEY, String(autoSave.value))
}
function reloadPage() {
replRef.value?.reload()
}
@ -186,9 +197,11 @@ onMounted(() => {
:prod="productionMode"
:ssr="useSSRMode"
:vapor="useVaporMode"
:autoSave="autoSave"
@toggle-theme="toggleTheme"
@toggle-prod="toggleProdMode"
@toggle-ssr="toggleSSR"
@toggle-autosave="toggleAutoSave"
@toggle-vapor="toggleVapor"
@reload-page="reloadPage"
/>
@ -199,6 +212,7 @@ onMounted(() => {
@keydown.ctrl.s.prevent
@keydown.meta.s.prevent
:ssr="useSSRMode"
:autoSave="autoSave"
:store="store"
:showCompileOutput="true"
:autoResize="true"

View File

@ -15,12 +15,14 @@ const props = defineProps<{
prod: boolean
ssr: boolean
vapor: boolean
autoSave: boolean
}>()
const emit = defineEmits([
'toggle-theme',
'toggle-ssr',
'toggle-prod',
'toggle-vapor',
'toggle-autosave',
'reload-page',
])
@ -117,6 +119,14 @@ function toggleDark() {
>
<span>{{ ssr ? 'SSR ON' : 'SSR OFF' }}</span>
</button>
<button
title="Toggle editor auto save mode"
class="toggle-autosave"
:class="{ enabled: autoSave }"
@click="$emit('toggle-autosave')"
>
<span>{{ autoSave ? 'AutoSave ON' : 'AutoSave OFF' }}</span>
</button>
<button title="Toggle dark mode" class="toggle-dark" @click="toggleDark">
<Sun class="light" />
<Moon class="dark" />
@ -135,7 +145,7 @@ function toggleDark() {
<Download />
</button>
<a
href="https://github.com/vuejs/core/tree/main/packages/sfc-playground"
href="https://github.com/vuejs/core/tree/main/packages-private/sfc-playground"
target="_blank"
title="View on GitHub"
class="github"
@ -210,7 +220,8 @@ h1 img {
.toggle-prod span,
.toggle-vapor span,
.toggle-ssr span {
.toggle-ssr span,
.toggle-autosave span {
font-size: 12px;
border-radius: 4px;
padding: 4px 6px;
@ -225,11 +236,13 @@ h1 img {
background: var(--purple);
}
.toggle-ssr span {
.toggle-ssr span,
.toggle-autosave span {
background-color: var(--btn-bg);
}
.toggle-ssr.enabled span {
.toggle-ssr.enabled span,
.toggle-autosave.enabled span {
color: #fff;
background-color: var(--green);
}

View File

@ -11,7 +11,7 @@
"vue": "^3.4.0"
},
"devDependencies": {
"@vitejs/plugin-vue": "^5.1.2",
"vite": "^5.3.5"
"@vitejs/plugin-vue": "^5.1.3",
"vite": "^5.4.5"
}
}

View File

@ -34,7 +34,7 @@ function copyVuePlugin(): Plugin {
name: 'copy-vue',
generateBundle() {
const copyFile = (file: string) => {
const filePath = path.resolve(__dirname, file)
const filePath = path.resolve(__dirname, '../../packages', file)
const basename = path.basename(file)
if (!fs.existsSync(filePath)) {
throw new Error(
@ -49,12 +49,12 @@ function copyVuePlugin(): Plugin {
})
}
copyFile(`../vue/dist/vue.esm-browser.js`)
copyFile(`../vue/dist/vue.esm-browser.prod.js`)
copyFile(`../vue/dist/vue.runtime.esm-browser.js`)
copyFile(`../vue/dist/vue.runtime.esm-browser.prod.js`)
copyFile(`../server-renderer/dist/server-renderer.esm-browser.js`)
copyFile(`../vue-vapor/dist/vue-vapor.esm-browser.js`)
copyFile(`vue/dist/vue.esm-browser.js`)
copyFile(`vue/dist/vue.esm-browser.prod.js`)
copyFile(`vue/dist/vue.runtime.esm-browser.js`)
copyFile(`vue/dist/vue.runtime.esm-browser.prod.js`)
copyFile(`server-renderer/dist/server-renderer.esm-browser.js`)
copyFile(`vue-vapor/dist/vue-vapor.esm-browser.js`)
},
}
}

View File

@ -12,7 +12,7 @@
},
"dependencies": {
"@vue/compiler-vapor": "workspace:^",
"monaco-editor": "^0.50.0",
"source-map-js": "^1.2.0"
"monaco-editor": "^0.51.0",
"source-map-js": "^1.2.1"
}
}

View File

@ -0,0 +1,7 @@
{
"extends": "../tsconfig.json",
"compilerOptions": {
"isolatedDeclarations": false
},
"include": ["."]
}

View File

@ -0,0 +1,15 @@
<script setup>
import { ref } from 'vue'
const count = ref(0)
</script>
<template>
<button @click="count++">{{ count }}</button>
</template>
<style>
button {
color: red;
}
</style>

View File

@ -0,0 +1 @@
This package is used for debugging issues that are related to `@vitejs/plugin-vue`, or can only be reproduced in a Vite-based setup. It aims to be as close to production as possible so Vue packages are resolved to the dist files instead of source.

View File

@ -0,0 +1,2 @@
<script type="module" src="./main.ts"></script>
<div id="app"></div>

View File

@ -0,0 +1,6 @@
import { createApp } from 'vue'
import App from './App.vue'
const app = createApp(App)
app.mount('#app')

View File

@ -0,0 +1,15 @@
{
"name": "vite-debug",
"private": true,
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build",
"serve": "vite preview"
},
"devDependencies": {
"@vitejs/plugin-vue": "catalog:",
"vite": "catalog:",
"vue": "workspace:*"
}
}

View File

@ -0,0 +1,7 @@
{
"compilerOptions": {
"module": "esnext",
"moduleResolution": "bundler"
},
"include": ["./*"]
}

View File

@ -0,0 +1,6 @@
import { defineConfig } from 'vite'
import vue from '@vitejs/plugin-vue'
export default defineConfig({
plugins: [vue()],
})

View File

@ -1358,7 +1358,27 @@ describe('compiler: parse', () => {
name: 'on',
rawName: 'v-on.enter',
arg: undefined,
modifiers: ['enter'],
modifiers: [
{
constType: 3,
content: 'enter',
isStatic: true,
loc: {
end: {
column: 16,
line: 1,
offset: 15,
},
source: 'enter',
start: {
column: 11,
line: 1,
offset: 10,
},
},
type: 4,
},
],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
@ -1377,7 +1397,46 @@ describe('compiler: parse', () => {
name: 'on',
rawName: 'v-on.enter.exact',
arg: undefined,
modifiers: ['enter', 'exact'],
modifiers: [
{
constType: 3,
content: 'enter',
isStatic: true,
loc: {
end: {
column: 16,
line: 1,
offset: 15,
},
source: 'enter',
start: {
column: 11,
line: 1,
offset: 10,
},
},
type: 4,
},
{
constType: 3,
content: 'exact',
isStatic: true,
loc: {
end: {
column: 22,
line: 1,
offset: 21,
},
source: 'exact',
start: {
column: 17,
line: 1,
offset: 16,
},
},
type: 4,
},
],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
@ -1406,7 +1465,46 @@ describe('compiler: parse', () => {
source: 'click',
},
},
modifiers: ['enter', 'exact'],
modifiers: [
{
constType: 3,
content: 'enter',
isStatic: true,
loc: {
end: {
column: 22,
line: 1,
offset: 21,
},
source: 'enter',
start: {
column: 17,
line: 1,
offset: 16,
},
},
type: 4,
},
{
constType: 3,
content: 'exact',
isStatic: true,
loc: {
end: {
column: 28,
line: 1,
offset: 27,
},
source: 'exact',
start: {
column: 23,
line: 1,
offset: 22,
},
},
type: 4,
},
],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
@ -1435,7 +1533,27 @@ describe('compiler: parse', () => {
source: '[a.b]',
},
},
modifiers: ['camel'],
modifiers: [
{
constType: 3,
content: 'camel',
isStatic: true,
loc: {
end: {
column: 22,
line: 1,
offset: 21,
},
source: 'camel',
start: {
column: 17,
line: 1,
offset: 16,
},
},
type: 4,
},
],
exp: undefined,
loc: {
start: { offset: 5, line: 1, column: 6 },
@ -1530,7 +1648,27 @@ describe('compiler: parse', () => {
source: 'a',
},
},
modifiers: ['prop'],
modifiers: [
{
constType: 0,
content: 'prop',
isStatic: false,
loc: {
end: {
column: 1,
line: 1,
offset: 0,
},
source: '',
start: {
column: 1,
line: 1,
offset: 0,
},
},
type: 4,
},
],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
@ -1569,7 +1707,27 @@ describe('compiler: parse', () => {
source: 'a',
},
},
modifiers: ['sync'],
modifiers: [
{
constType: 3,
content: 'sync',
isStatic: true,
loc: {
end: {
column: 13,
line: 1,
offset: 12,
},
source: 'sync',
start: {
column: 9,
line: 1,
offset: 8,
},
},
type: 4,
},
],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
@ -1649,7 +1807,27 @@ describe('compiler: parse', () => {
source: 'a',
},
},
modifiers: ['enter'],
modifiers: [
{
constType: 3,
content: 'enter',
isStatic: true,
loc: {
end: {
column: 14,
line: 1,
offset: 13,
},
source: 'enter',
start: {
column: 9,
line: 1,
offset: 8,
},
},
type: 4,
},
],
exp: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: 'b',
@ -1841,6 +2019,21 @@ describe('compiler: parse', () => {
children: [{ type: NodeTypes.TEXT, content: `{{ number ` }],
},
])
const ast3 = baseParse(`<div v-pre><textarea>{{ foo </textarea></div>`, {
parseMode: 'html',
})
expect((ast3.children[0] as ElementNode).children).toMatchObject([
{
type: NodeTypes.ELEMENT,
children: [
{
type: NodeTypes.TEXT,
content: `{{ foo `,
},
],
},
])
})
test('self-closing v-pre', () => {
@ -2176,6 +2369,7 @@ describe('compiler: parse', () => {
test('should remove leading newline character immediately following the pre element start tag', () => {
const ast = parse(`<pre>\n foo bar </pre>`, {
isPreTag: tag => tag === 'pre',
isIgnoreNewlineTag: tag => tag === 'pre',
})
expect(ast.children).toHaveLength(1)
const preElement = ast.children[0] as ElementNode

View File

@ -3,6 +3,8 @@ import {
ElementTypes,
Namespaces,
NodeTypes,
type Property,
type SimpleExpressionNode,
type VNodeCall,
locStub,
} from '../src'
@ -22,7 +24,10 @@ const bracketsRE = /^\[|\]$/g
// e.g.
// - createObjectMatcher({ 'foo': '[bar]' }) matches { foo: bar }
// - createObjectMatcher({ '[foo]': 'bar' }) matches { [foo]: "bar" }
export function createObjectMatcher(obj: Record<string, any>) {
export function createObjectMatcher(obj: Record<string, any>): {
type: NodeTypes
properties: Partial<Property>[]
} {
return {
type: NodeTypes.JS_OBJECT_EXPRESSION,
properties: Object.keys(obj).map(key => ({
@ -31,7 +36,7 @@ export function createObjectMatcher(obj: Record<string, any>) {
type: NodeTypes.SIMPLE_EXPRESSION,
content: key.replace(bracketsRE, ''),
isStatic: !leadingBracketRE.test(key),
},
} as SimpleExpressionNode,
value: isString(obj[key])
? {
type: NodeTypes.SIMPLE_EXPRESSION,
@ -78,7 +83,7 @@ type Flags = PatchFlags | ShapeFlags
export function genFlagText(
flag: Flags | Flags[],
names: { [k: number]: string } = PatchFlagNames,
) {
): string {
if (isArray(flag)) {
let f = 0
flag.forEach(ff => {

View File

@ -191,7 +191,7 @@ exports[`compiler: cacheStatic transform > prefixIdentifiers > hoist class with
const { createElementVNode: _createElementVNode } = _Vue
const _hoisted_1 = {
class: /*#__PURE__*/_normalizeClass({ foo: true })
class: /*@__PURE__*/_normalizeClass({ foo: true })
}
return function render(_ctx, _cache) {

View File

@ -13,6 +13,7 @@ import {
type ForNode,
type InterpolationNode,
NodeTypes,
type RootNode,
type SimpleExpressionNode,
} from '../../src/ast'
import { ErrorCodes } from '../../src/errors'
@ -24,7 +25,10 @@ import { createObjectMatcher } from '../testUtils'
export function parseWithForTransform(
template: string,
options: CompilerOptions = {},
) {
): {
root: RootNode
node: ForNode & { codegenNode: ForCodegenNode }
} {
const ast = parse(template, options)
transform(ast, {
nodeTransforms: [

View File

@ -285,6 +285,21 @@ describe('compiler: transform v-on', () => {
},
],
})
const { node: node2 } = parseWithVOn(
`<div @click="(e: (number | string)[]) => foo(e)"/>`,
)
expect((node2.codegenNode as VNodeCall).props).toMatchObject({
properties: [
{
key: { content: `onClick` },
value: {
type: NodeTypes.SIMPLE_EXPRESSION,
content: `(e: (number | string)[]) => foo(e)`,
},
},
],
})
})
test('should NOT wrap as function if expression is already function expression (async)', () => {

View File

@ -1,5 +1,5 @@
import type { TransformContext } from '../src'
import type { Position } from '../src/ast'
import type { ExpressionNode, TransformContext } from '../src'
import { type Position, createSimpleExpression } from '../src/ast'
import {
advancePositionWithClone,
isMemberExpressionBrowser,
@ -41,7 +41,8 @@ describe('advancePositionWithClone', () => {
})
describe('isMemberExpression', () => {
function commonAssertions(fn: (str: string) => boolean) {
function commonAssertions(raw: (exp: ExpressionNode) => boolean) {
const fn = (str: string) => raw(createSimpleExpression(str))
// should work
expect(fn('obj.foo')).toBe(true)
expect(fn('obj[foo]')).toBe(true)
@ -78,13 +79,16 @@ describe('isMemberExpression', () => {
test('browser', () => {
commonAssertions(isMemberExpressionBrowser)
expect(isMemberExpressionBrowser('123[a]')).toBe(false)
expect(isMemberExpressionBrowser(createSimpleExpression('123[a]'))).toBe(
false,
)
})
test('node', () => {
const ctx = { expressionPlugins: ['typescript'] } as any as TransformContext
const fn = (str: string) => isMemberExpressionNode(str, ctx)
commonAssertions(fn)
const fn = (str: string) =>
isMemberExpressionNode(createSimpleExpression(str), ctx)
commonAssertions(exp => isMemberExpressionNode(exp, ctx))
// TS-specific checks
expect(fn('foo as string')).toBe(true)

View File

@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
"version": "3.5.0-beta.1",
"version": "3.5.6",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
@ -48,7 +48,7 @@
"dependencies": {
"@babel/parser": "catalog:",
"@vue/shared": "workspace:*",
"entities": "^5.0.0",
"entities": "^4.5.0",
"estree-walker": "catalog:",
"source-map-js": "catalog:"
},

View File

@ -210,7 +210,7 @@ export interface DirectiveNode extends Node {
rawName?: string
exp: ExpressionNode | undefined
arg: ExpressionNode | undefined
modifiers: string[]
modifiers: SimpleExpressionNode[]
/**
* optional property to cache the expression parse result for v-for
*/

View File

@ -99,7 +99,7 @@ interface MappingItem {
name: string | null
}
const PURE_ANNOTATION = `/*#__PURE__*/`
const PURE_ANNOTATION = `/*@__PURE__*/`
const aliasHelper = (s: symbol) => `${helperNameMap[s]}: _${helperNameMap[s]}`
@ -742,7 +742,7 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
!__BROWSER__ && genReturnStatement(node, context)
break
/* istanbul ignore next */
/* v8 ignore start */
case NodeTypes.IF_BRANCH:
// noop
break
@ -753,6 +753,7 @@ function genNode(node: CodegenNode | symbol | string, context: CodegenContext) {
const exhaustiveCheck: never = node
return exhaustiveCheck
}
/* v8 ignore stop */
}
}

View File

@ -68,7 +68,7 @@ export function baseCompile(
): CodegenResult {
const onError = options.onError || defaultOnError
const isModuleMode = options.mode === 'module'
/* istanbul ignore if */
/* v8 ignore start */
if (__BROWSER__) {
if (options.prefixIdentifiers === true) {
onError(createCompilerError(ErrorCodes.X_PREFIX_ID_NOT_SUPPORTED))
@ -76,6 +76,7 @@ export function baseCompile(
onError(createCompilerError(ErrorCodes.X_MODULE_MODE_NOT_SUPPORTED))
}
}
/* v8 ignore stop */
const prefixIdentifiers =
!__BROWSER__ && (options.prefixIdentifiers === true || isModuleMode)

View File

@ -47,7 +47,7 @@ export * from './runtimeHelpers'
export { getBaseTransformPreset, type TransformPreset } from './compile'
export { transformModel } from './transforms/vModel'
export { transformOn, fnExpRE } from './transforms/vOn'
export { transformOn } from './transforms/vOn'
export { transformBind } from './transforms/vBind'
export { noopDirectiveTransform } from './transforms/noopDirectiveTransform'
export { processIf } from './transforms/vIf'

View File

@ -52,6 +52,11 @@ export interface ParserOptions
* e.g. elements that should preserve whitespace inside, e.g. `<pre>`
*/
isPreTag?: (tag: string) => boolean
/**
* Elements that should ignore the first newline token per parinsg spec
* e.g. `<textarea>` and `<pre>`
*/
isIgnoreNewlineTag?: (tag: string) => boolean
/**
* Platform-specific built-in components e.g. `<Transition>`
*/

View File

@ -44,7 +44,7 @@ import {
isSimpleIdentifier,
isStaticArgOf,
} from './utils'
import { decodeHTML } from 'entities/dist/decode.js'
import { decodeHTML } from 'entities/lib/decode.js'
import {
type ParserOptions as BabelOptions,
parse,
@ -72,6 +72,7 @@ export const defaultParserOptions: MergedParserOptions = {
getNamespace: () => Namespaces.HTML,
isVoidTag: NO,
isPreTag: NO,
isIgnoreNewlineTag: NO,
isCustomElement: NO,
onError: defaultOnError,
onWarn: defaultOnWarn,
@ -225,7 +226,7 @@ const tokenizer = new Tokenizer(stack, {
rawName: raw,
exp: undefined,
arg: undefined,
modifiers: raw === '.' ? ['prop'] : [],
modifiers: raw === '.' ? [createSimpleExpression('prop')] : [],
loc: getLoc(start),
}
if (name === 'pre') {
@ -273,7 +274,8 @@ const tokenizer = new Tokenizer(stack, {
setLocEnd(arg.loc, end)
}
} else {
;(currentProp as DirectiveNode).modifiers.push(mod)
const exp = createSimpleExpression(mod, true, getLoc(start, end))
;(currentProp as DirectiveNode).modifiers.push(exp)
}
},
@ -379,7 +381,9 @@ const tokenizer = new Tokenizer(stack, {
if (
__COMPAT__ &&
currentProp.name === 'bind' &&
(syncIndex = currentProp.modifiers.indexOf('sync')) > -1 &&
(syncIndex = currentProp.modifiers.findIndex(
mod => mod.content === 'sync',
)) > -1 &&
checkCompatEnabled(
CompilerDeprecationTypes.COMPILER_V_BIND_SYNC,
currentOptions,
@ -630,7 +634,7 @@ function onCloseTag(el: ElementNode, end: number, isImplied = false) {
}
// refine element type
const { tag, ns } = el
const { tag, ns, children } = el
if (!inVPre) {
if (tag === 'slot') {
el.tagType = ElementTypes.SLOT
@ -643,8 +647,18 @@ function onCloseTag(el: ElementNode, end: number, isImplied = false) {
// whitespace management
if (!tokenizer.inRCDATA) {
el.children = condenseWhitespace(el.children, el.tag)
el.children = condenseWhitespace(children, tag)
}
if (ns === Namespaces.HTML && currentOptions.isIgnoreNewlineTag(tag)) {
// remove leading newline for <textarea> and <pre> per html spec
// https://html.spec.whatwg.org/multipage/parsing.html#parsing-main-inbody
const first = children[0]
if (first && first.type === NodeTypes.TEXT) {
first.content = first.content.replace(/^\r?\n/, '')
}
}
if (ns === Namespaces.HTML && currentOptions.isPreTag(tag)) {
inPre--
}
@ -866,14 +880,6 @@ function condenseWhitespace(
}
}
}
if (inPre && tag && currentOptions.isPreTag(tag)) {
// remove leading newline per html spec
// https://html.spec.whatwg.org/multipage/grouping-content.html#the-pre-element
const first = nodes[0]
if (first && first.type === NodeTypes.TEXT) {
first.content = first.content.replace(/^\r?\n/, '')
}
}
return removedWhitespace ? nodes.filter(Boolean) : nodes
}

View File

@ -36,7 +36,7 @@ import {
EntityDecoder,
fromCodePoint,
htmlDecodeTree,
} from 'entities/dist/decode.js'
} from 'entities/lib/decode.js'
export enum ParseMode {
BASE,
@ -438,7 +438,7 @@ export default class Tokenizer {
// We have to parse entities in <title> and <textarea> tags.
if (!__BROWSER__ && c === CharCodes.Amp) {
this.startEntity()
} else if (c === this.delimiterOpen[0]) {
} else if (!this.inVPre && c === this.delimiterOpen[0]) {
// We also need to handle interpolation
this.state = State.InterpolationOpen
this.delimiterIndex = 0

Some files were not shown because too many files have changed in this diff Show More