diff --git a/.eslintrc.cjs b/.eslintrc.cjs deleted file mode 100644 index 4296d0f39..000000000 --- a/.eslintrc.cjs +++ /dev/null @@ -1,88 +0,0 @@ -/* eslint-disable no-restricted-globals */ - -const DOMGlobals = ['window', 'document'] -const NodeGlobals = ['module', 'require'] - -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module' - }, - plugins: ['jest'], - rules: { - 'no-debugger': 'error', - // most of the codebase are expected to be env agnostic - 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals], - - 'no-restricted-syntax': [ - 'error', - // since we target ES2015 for baseline support, we need to forbid object - // rest spread usage in destructure as it compiles into a verbose helper. - 'ObjectPattern > RestElement', - // tsc compiles assignment spread into Object.assign() calls, but esbuild - // still generates verbose helpers, so spread assignment is also prohiboted - 'ObjectExpression > SpreadElement', - 'AwaitExpression' - ] - }, - overrides: [ - // tests, no restrictions (runs in Node / jest with jsdom) - { - files: ['**/__tests__/**', 'packages/dts-test/**'], - rules: { - 'no-restricted-globals': 'off', - 'no-restricted-syntax': 'off', - 'jest/no-disabled-tests': 'error', - 'jest/no-focused-tests': 'error' - } - }, - // shared, may be used in any env - { - files: ['packages/shared/**'], - rules: { - 'no-restricted-globals': 'off' - } - }, - // Packages targeting DOM - { - files: ['packages/{vue,vue-compat,runtime-dom}/**'], - rules: { - 'no-restricted-globals': ['error', ...NodeGlobals] - } - }, - // Packages targeting Node - { - files: [ - 'packages/{compiler-sfc,compiler-ssr,server-renderer,reactivity-transform}/**' - ], - rules: { - 'no-restricted-globals': ['error', ...DOMGlobals], - 'no-restricted-syntax': 'off' - } - }, - // Private package, browser only + no syntax restrictions - { - files: ['packages/template-explorer/**', 'packages/sfc-playground/**'], - rules: { - 'no-restricted-globals': ['error', ...NodeGlobals], - 'no-restricted-syntax': 'off' - } - }, - // JavaScript files - { - files: ['*.js', '*.cjs'], - rules: { - // We only do `no-unused-vars` checks for js files, TS files are checked by TypeScript itself. - 'no-unused-vars': ['error', { vars: 'all', args: 'none' }] - } - }, - // Node scripts - { - files: ['scripts/**', '*.{js,ts}', 'packages/**/index.js'], - rules: { - 'no-restricted-globals': 'off', - 'no-restricted-syntax': 'off' - } - } - ] -} diff --git a/.git-blame-ignore-revs b/.git-blame-ignore-revs new file mode 100644 index 000000000..d06b03a3f --- /dev/null +++ b/.git-blame-ignore-revs @@ -0,0 +1,2 @@ +# update prettier & eslint config (#9162) +bfe6b459d3a0ce6168611ee1ac7e6e789709df9d diff --git a/.github/commit-convention.md b/.github/commit-convention.md index a8522fa21..11a64576a 100644 --- a/.github/commit-convention.md +++ b/.github/commit-convention.md @@ -6,7 +6,7 @@ Messages must be matched by the following regex: -``` js +```regexp /^(revert: )?(feat|fix|docs|dx|style|refactor|perf|test|workflow|build|ci|chore|types|wip)(\(.+\))?: .{1,50}/ ``` @@ -44,7 +44,7 @@ This reverts commit 667ecc1654a317a13331b17617d973392f415f02. ### Full Message Format -A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**: +A commit message consists of a **header**, **body** and **footer**. The header has a **type**, **scope** and **subject**: ``` (): @@ -74,9 +74,9 @@ The scope could be anything specifying the place of the commit change. For examp The subject contains a succinct description of the change: -* use the imperative, present tense: "change" not "changed" nor "changes" -* don't capitalize the first letter -* no dot (.) at the end +- use the imperative, present tense: "change" not "changed" nor "changes" +- don't capitalize the first letter +- no dot (.) at the end ### Body diff --git a/.github/contributing.md b/.github/contributing.md index afdae6711..2554582b8 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -17,6 +17,26 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before ## Pull Request Guidelines +### What kinds of Pull Requests are accepted? + +- Bug fix that addresses a clearly identified bug. **"Clearly identified bug"** means the bug has a proper reproduction either from a related open issue, or is included in the PR itself. Avoid submitting PRs that claim to fix something but do not sufficiently explain what is being fixed. + +- New feature that addresses a clearly explained and widely applicable use case. **"Widely applicable"** means the new feature should provide non-trivial improvements to the majority of the user base. Vue already has a large API surface so we are quite cautious about adding new features - if the use case is niche and can be addressed via userland implementations, it likely isn't suitable to go into core. + + The feature implementation should also consider the trade-off between the added complexity vs. the benefits gained. For example, if a small feature requires significant changes that spreads across the codebase, it is likely not worth it, or the approach should be reconsidered. + + If the feature has a non-trivial API surface addition, or significantly affects the way a common use case is approached by the users, it should go through a discussion first in the [RFC repo](https://github.com/vuejs/rfcs/discussions). PRs of such features without prior discussion make it really difficult to steer / adjust the API design due to coupling with concrete implementations, and can lead to wasted work. + +- Chore: typos, comment improvements, build config, CI config, etc. For typos and comment changes, try to combine multiple of them into a single PR. + +- **It should be noted that we discourage contributors from submitting code refactors that are largely stylistic.** Code refactors are only accepted if it improves performance, or comes with sufficient explanations on why it objectively improves the code quality (e.g. makes a related feature implementation easier). + + The reason is that code readability is subjective. The maintainers of this project have chosen to write the code in its current style based on our preferences, and we do not want to spend time explaining our stylistic preferences. Contributors should just respect the established conventions when contributing code. + + Another aspect of it is that large scale stylistic changes result in massive diffs that touch multiple files, adding noise to the git history and makes tracing behavior changes across commits more cumbersome. + +### Pull Request Checklist + - Vue core has two primary work branches: `main` and `minor`. - If your pull request is a feature that adds new API surface, it should be submitted against the `minor` branch. @@ -61,9 +81,9 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before ## Development Setup -You will need [Node.js](https://nodejs.org) **version 18.12+**, and [PNPM](https://pnpm.io) **version 8+**. +You will need [Node.js](https://nodejs.org) with minimum version as specified in the [`.node-version`](https://github.com/vuejs/core/blob/main/.node-version) file, and [PNPM](https://pnpm.io) with minimum version as specified in the [`"packageManager"` field in `package.json`](https://github.com/vuejs/core/blob/main/package.json#L4). -We also recommend installing [ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier. +We also recommend installing [@antfu/ni](https://github.com/antfu/ni) to help switching between repos using different package managers. `ni` also provides the handy `nr` command which running npm scripts easier. After cloning the repo, run: @@ -86,11 +106,11 @@ The project uses [simple-git-hooks](https://github.com/toplenboren/simple-git-ho - Type check the entire project - Automatically format changed files using Prettier -- Verify commit message format (logic in `scripts/verifyCommit.js`) +- Verify commit message format (logic in `scripts/verify-commit.js`) ## Scripts -**The examples below will be using the `nr` command from the [ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`. +**The examples below will be using the `nr` command from the [@antfu/ni](https://github.com/antfu/ni) package.** You can also use plain `npm run`, but you will need to pass all additional arguments after the command after an extra `--`. For example, `nr build runtime --all` is equivalent to `npm run build -- runtime --all`. The `run-s` and `run-p` commands found in some scripts are from [npm-run-all](https://github.com/mysticatea/npm-run-all) for orchestrating multiple scripts. `run-s` means "run in sequence" while `run-p` means "run in parallel". @@ -216,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 @@ -315,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 diff --git a/.github/maintenance.md b/.github/maintenance.md index 8d4317c6b..b1fb550dd 100644 --- a/.github/maintenance.md +++ b/.github/maintenance.md @@ -80,6 +80,7 @@ Depending on the type of the PR, different considerations need to be taken into - Make sure it doesn't accidentally cause dev-only or compiler-only code branches to be included in the runtime build. Notable case is that some functions in @vue/shared are compiler-only and should not be used in runtime code, e.g. `isHTMLTag` and `isSVGTag`. - Performance + - Be careful about code changes in "hot paths", in particular the Virtual DOM renderer (`runtime-core/src/renderer.ts`) and component instantiation code. - Potential Breakage diff --git a/.github/renovate.json5 b/.github/renovate.json5 index 088913317..8808b599e 100644 --- a/.github/renovate.json5 +++ b/.github/renovate.json5 @@ -7,35 +7,35 @@ packageRules: [ { depTypeList: ['peerDependencies'], - enabled: false + enabled: false, }, { groupName: 'test', matchPackageNames: ['vitest', 'jsdom', 'puppeteer'], - matchPackagePrefixes: ['@vitest'] + matchPackagePrefixes: ['@vitest'], }, { 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', + ], }, { groupName: 'compiler', matchPackageNames: ['magic-string'], - matchPackagePrefixes: ['@babel', 'postcss'] + matchPackagePrefixes: ['@babel', 'postcss'], }, { groupName: 'build', - matchPackageNames: ['vite', 'terser'], - matchPackagePrefixes: ['rollup', 'esbuild', '@rollup', '@vitejs'] + matchPackageNames: ['vite', '@swc/core'], + matchPackagePrefixes: ['rollup', 'esbuild', '@rollup', '@vitejs'], }, { groupName: 'lint', matchPackageNames: ['simple-git-hooks', 'lint-staged'], - matchPackagePrefixes: ['@typescript-eslint', 'eslint', 'prettier'] - } + matchPackagePrefixes: ['typescript-eslint', 'eslint', 'prettier'], + }, ], ignoreDeps: [ 'vue', @@ -45,6 +45,22 @@ 'typescript', // ESM only - 'estree-walker' - ] + 'estree-walker', + + // pinned + // https://github.com/vuejs/core/issues/10300#issuecomment-1940855364 + 'lru-cache', + + // 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', + ], } diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml index 5e7bb63c2..d5c31beff 100644 --- a/.github/workflows/autofix.yml +++ b/.github/workflows/autofix.yml @@ -14,13 +14,14 @@ jobs: - uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4.0.0 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 18 - cache: pnpm + node-version-file: '.node-version' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' - run: pnpm install @@ -30,4 +31,4 @@ jobs: - name: Run prettier run: pnpm run format - - uses: autofix-ci/action@bee19d72e71787c12ca0f29de72f2833e437e4c9 + - uses: autofix-ci/action@ff86a557419858bb967097bfc916833f5647fa8c diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml index 27fbd42c9..b5d75b9ce 100644 --- a/.github/workflows/canary-minor.yml +++ b/.github/workflows/canary-minor.yml @@ -17,17 +17,17 @@ jobs: ref: minor - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4.0.0 - - name: Set node version to 18 + - name: Install Node.js uses: actions/setup-node@v4 with: - node-version: 18 + node-version-file: '.node-version' registry-url: 'https://registry.npmjs.org' cache: 'pnpm' - run: pnpm install - - run: pnpm release --canary --tag minor + - run: pnpm release --canary --publish --tag minor env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml index 61490232f..bb622725a 100644 --- a/.github/workflows/canary.yml +++ b/.github/workflows/canary.yml @@ -15,7 +15,7 @@ jobs: - uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4.0.0 - name: Install Node.js uses: actions/setup-node@v4 @@ -26,6 +26,6 @@ jobs: - run: pnpm install - - run: pnpm release --canary + - run: pnpm release --canary --publish env: NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml index 493ab2950..c8c217f62 100644 --- a/.github/workflows/ci.yml +++ b/.github/workflows/ci.yml @@ -3,112 +3,40 @@ on: push: branches: - '**' + tags: + - '!**' pull_request: branches: - main - -permissions: - contents: read # to fetch code (actions/checkout) + - minor jobs: - unit-test: + 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 - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' steps: - - uses: actions/checkout@v4 + - name: Checkout + uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + 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' - - run: pnpm install + - name: Install deps + run: pnpm install - - name: Run unit tests - run: pnpm run test-unit + - name: Build + run: pnpm build --withTypes - unit-test-windows: - runs-on: windows-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v2 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install - - - name: Run compiler unit tests - run: pnpm run test-unit compiler - - - name: Run ssr unit tests - run: pnpm run test-unit server-renderer - - e2e-test: - runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - steps: - - uses: actions/checkout@v4 - - - name: Setup cache for Chromium binary - uses: actions/cache@v3 - with: - path: ~/.cache/puppeteer - key: chromium-${{ hashFiles('pnpm-lock.yaml') }} - - - name: Install pnpm - uses: pnpm/action-setup@v2 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install - - run: node node_modules/puppeteer/install.mjs - - - name: Run e2e tests - run: pnpm run test-e2e - - lint-and-test-dts: - runs-on: ubuntu-latest - if: github.event_name == 'push' || github.event.pull_request.head.repo.full_name != github.repository - env: - PUPPETEER_SKIP_DOWNLOAD: 'true' - steps: - - uses: actions/checkout@v4 - - - name: Install pnpm - uses: pnpm/action-setup@v2 - - - name: Install Node.js - uses: actions/setup-node@v4 - with: - node-version-file: '.node-version' - cache: 'pnpm' - - - run: pnpm install - - - name: Run eslint - run: pnpm run lint - - - name: Run prettier - run: pnpm run format-check - - - name: Run type declaration tests - run: pnpm run test-dts + - name: Release + run: pnpx pkg-pr-new publish --compact --pnpm './packages/*' diff --git a/.github/workflows/close-cant-reproduce-issues.yml b/.github/workflows/close-cant-reproduce-issues.yml new file mode 100644 index 000000000..8fb48f842 --- /dev/null +++ b/.github/workflows/close-cant-reproduce-issues.yml @@ -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 diff --git a/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml index 25adf7c85..b3e963ece 100644 --- a/.github/workflows/ecosystem-ci-trigger.yml +++ b/.github/workflows/ecosystem-ci-trigger.yml @@ -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 } }) diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml deleted file mode 100644 index 16c6c9c5c..000000000 --- a/.github/workflows/release-tag.yml +++ /dev/null @@ -1,27 +0,0 @@ -on: - push: - tags: - - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 - -name: Create Release - -permissions: {} -jobs: - build: - permissions: - contents: write # to create release (yyx990803/release-tag) - - name: Create Release - runs-on: ubuntu-latest - steps: - - name: Checkout code - uses: actions/checkout@master - - name: Create Release for Tag - id: release_tag - uses: yyx990803/release-tag@master - env: - GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} - with: - tag_name: ${{ github.ref }} - body: | - Please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml new file mode 100644 index 000000000..c260a728e --- /dev/null +++ b/.github/workflows/release.yml @@ -0,0 +1,55 @@ +name: Release + +on: + push: + tags: + - 'v*' # Push events to matching v*, i.e. v1.0, v20.15.10 + +jobs: + test: + uses: ./.github/workflows/test.yml + + release: + # prevents this action from running on forks + if: github.repository == 'vuejs/core' + needs: [test] + runs-on: ubuntu-latest + permissions: + contents: write + id-token: write + # Use Release environment for deployment protection + environment: Release + 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 and publish + id: publish + run: | + pnpm release --publishOnly + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} + + - name: Create GitHub release + id: release_tag + uses: yyx990803/release-tag@master + env: + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + tag_name: ${{ github.ref }} + body: | + For stable releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. + For pre-releases, please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/minor/CHANGELOG.md) of the `minor` branch. diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml index bb82aa18d..7f8bf7b08 100644 --- a/.github/workflows/size-data.yml +++ b/.github/workflows/size-data.yml @@ -4,9 +4,11 @@ on: push: branches: - main + - minor pull_request: branches: - main + - minor permissions: contents: read @@ -16,13 +18,14 @@ env: jobs: upload: + if: github.repository == 'vuejs/core' runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4.0.0 - name: Install Node.js uses: actions/setup-node@v4 @@ -35,18 +38,14 @@ jobs: - run: pnpm run size + - 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@v3 + uses: actions/upload-artifact@v4 with: name: size-data path: temp/size - - - name: Save PR number - if: ${{github.event_name == 'pull_request'}} - run: echo ${{ github.event.number }} > ./pr.txt - - - uses: actions/upload-artifact@v3 - if: ${{github.event_name == 'pull_request'}} - with: - name: pr-number - path: pr.txt diff --git a/.github/workflows/size-report.yml b/.github/workflows/size-report.yml index 78ae44bb7..f9d2052b6 100644 --- a/.github/workflows/size-report.yml +++ b/.github/workflows/size-report.yml @@ -18,13 +18,14 @@ 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: - uses: actions/checkout@v4 - name: Install pnpm - uses: pnpm/action-setup@v2 + uses: pnpm/action-setup@v4.0.0 - name: Install Node.js uses: actions/setup-node@v4 @@ -35,37 +36,37 @@ jobs: - name: Install dependencies run: pnpm install - - name: Download PR number - uses: dawidd6/action-download-artifact@v2 - with: - name: pr-number - run_id: ${{ github.event.workflow_run.id }} - - - name: Read PR Number - id: pr-number - uses: juliangruber/read-file-action@v1 - with: - path: ./pr.txt - - name: Download Size Data - uses: dawidd6/action-download-artifact@v2 + uses: dawidd6/action-download-artifact@v6 with: name: size-data run_id: ${{ github.event.workflow_run.id }} path: temp/size - - name: Download Previous Size Data - uses: dawidd6/action-download-artifact@v2 + - name: Read PR Number + id: pr-number + uses: juliangruber/read-file-action@v1 with: - branch: main + 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: + branch: ${{ steps.pr-base.outputs.content }} workflow: size-data.yml event: push name: size-data path: temp/size-prev if_no_artifact_found: warn - - name: Compare size - run: pnpm tsx scripts/size-report.ts > size-report.md + - name: Prepare report + run: node scripts/size-report.js > size-report.md - name: Read Size Report id: size-report diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml new file mode 100644 index 000000000..70dc82248 --- /dev/null +++ b/.github/workflows/test.yml @@ -0,0 +1,108 @@ +name: 'test' + +on: workflow_call + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + unit-test: + runs-on: ubuntu-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run unit tests + run: pnpm run test-unit + + unit-test-windows: + runs-on: windows-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run compiler unit tests + run: pnpm run test-unit compiler + + - name: Run ssr unit tests + run: pnpm run test-unit server-renderer + + e2e-test: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + + - name: Setup cache for Chromium binary + uses: actions/cache@v4 + with: + path: ~/.cache/puppeteer + key: chromium-${{ hashFiles('pnpm-lock.yaml') }} + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + - run: node node_modules/puppeteer/install.mjs + + - name: Run e2e tests + run: pnpm run test-e2e + + - name: verify treeshaking + run: node scripts/verify-treeshaking.js + + lint-and-test-dts: + runs-on: ubuntu-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v4.0.0 + + - name: Install Node.js + uses: actions/setup-node@v4 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + + - name: Run eslint + run: pnpm run lint + + - name: Run prettier + run: pnpm run format-check + + - name: Run type declaration tests + run: pnpm run test-dts diff --git a/.gitignore b/.gitignore index 810f88526..9dd21f59b 100644 --- a/.gitignore +++ b/.gitignore @@ -10,3 +10,4 @@ TODOs.md .eslintcache dts-build/packages *.tsbuildinfo +*.tgz diff --git a/.prettierignore b/.prettierignore index 1521c8b76..ca3c40849 100644 --- a/.prettierignore +++ b/.prettierignore @@ -1 +1,3 @@ dist +pnpm-lock.yaml +CHANGELOG*.md diff --git a/.prettierrc b/.prettierrc index ef93d9482..759232e7c 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,5 +1,5 @@ -semi: false -singleQuote: true -printWidth: 80 -trailingComma: 'none' -arrowParens: 'avoid' +{ + "semi": false, + "singleQuote": true, + "arrowParens": "avoid" +} diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 000000000..91ebd5692 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,3 @@ +{ + "recommendations": ["vitest.explorer"] +} diff --git a/.vscode/launch.json b/.vscode/launch.json index b63ffc79b..9fc03aa9b 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -5,24 +5,15 @@ "version": "0.2.0", "configurations": [ { - "name": "Jest", "type": "node", "request": "launch", - "program": "${workspaceFolder}/node_modules/.bin/jest", - "stopOnEntry": false, - "args": ["${fileBasename}", "--runInBand", "--detectOpenHandles"], - "cwd": "${workspaceFolder}", - "preLaunchTask": null, - "runtimeExecutable": null, - "runtimeArgs": ["--nolazy"], - "env": { - "NODE_ENV": "development" - }, - "console": "integratedTerminal", - "sourceMaps": true, - "windows": { - "program": "${workspaceFolder}/node_modules/jest/bin/jest", - } + "name": "Vitest - Debug Current Test File", + "autoAttachChildProcesses": true, + "skipFiles": ["/**", "**/node_modules/**"], + "program": "${workspaceRoot}/node_modules/vitest/vitest.mjs", + "args": ["run", "${relativeFile}"], + "smartStep": true, + "console": "integratedTerminal" } ] } diff --git a/CHANGELOG.md b/CHANGELOG.md index 062c61032..6a176ee1c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,532 +1,447 @@ -## [3.3.9](https://github.com/vuejs/core/compare/v3.3.8...v3.3.9) (2023-11-25) +## [3.5.11](https://github.com/vuejs/core/compare/v3.5.10...v3.5.11) (2024-10-03) ### Bug Fixes -* **compiler-core:** avoid rewriting scope variables in inline for loops ([#7245](https://github.com/vuejs/core/issues/7245)) ([a2d810e](https://github.com/vuejs/core/commit/a2d810eb40cef631f61991ca68b426ee9546aba0)), closes [#7238](https://github.com/vuejs/core/issues/7238) -* **compiler-core:** fix `resolveParserPlugins` decorators check ([#9566](https://github.com/vuejs/core/issues/9566)) ([9d0eba9](https://github.com/vuejs/core/commit/9d0eba916f3bf6fb5c03222400edae1a2db7444f)), closes [#9560](https://github.com/vuejs/core/issues/9560) -* **compiler-sfc:** consistently escape type-only prop names ([#8654](https://github.com/vuejs/core/issues/8654)) ([3e08d24](https://github.com/vuejs/core/commit/3e08d246dfd8523c54fb8e7a4a6fd5506ffb1bcc)), closes [#8635](https://github.com/vuejs/core/issues/8635) [#8910](https://github.com/vuejs/core/issues/8910) [vitejs/vite-plugin-vue#184](https://github.com/vitejs/vite-plugin-vue/issues/184) -* **compiler-sfc:** malformed filename on windows using path.posix.join() ([#9478](https://github.com/vuejs/core/issues/9478)) ([f18a174](https://github.com/vuejs/core/commit/f18a174979626b3429db93c5d5b7ae5448917c70)), closes [#8671](https://github.com/vuejs/core/issues/8671) [#9583](https://github.com/vuejs/core/issues/9583) [#9446](https://github.com/vuejs/core/issues/9446) [#9473](https://github.com/vuejs/core/issues/9473) -* **compiler-sfc:** support `:is` and `:where` selector in scoped css rewrite ([#8929](https://github.com/vuejs/core/issues/8929)) ([3227e50](https://github.com/vuejs/core/commit/3227e50b32105f8893f7dff2f29278c5b3a9f621)) -* **compiler-sfc:** support resolve extends interface for defineEmits ([#8470](https://github.com/vuejs/core/issues/8470)) ([9e1b74b](https://github.com/vuejs/core/commit/9e1b74bcd5fa4151f5d1bc02c69fbbfa4762f577)), closes [#8465](https://github.com/vuejs/core/issues/8465) -* **hmr/transition:** fix kept-alive component inside transition disappearing after hmr ([#7126](https://github.com/vuejs/core/issues/7126)) ([d11e978](https://github.com/vuejs/core/commit/d11e978fc98dcc83526c167e603b8308f317f786)), closes [#7121](https://github.com/vuejs/core/issues/7121) -* **hydration:** force hydration for v-bind with .prop modifier ([364f319](https://github.com/vuejs/core/commit/364f319d214226770d97c98d8fcada80c9e8dde3)), closes [#7490](https://github.com/vuejs/core/issues/7490) -* **hydration:** properly hydrate indeterminate prop ([34b5a5d](https://github.com/vuejs/core/commit/34b5a5da4ae9c9faccac237acd7acc8e7e017571)), closes [#7476](https://github.com/vuejs/core/issues/7476) -* **reactivity:** clear method on readonly collections should return undefined ([#7316](https://github.com/vuejs/core/issues/7316)) ([657476d](https://github.com/vuejs/core/commit/657476dcdb964be4fbb1277c215c073f3275728e)) -* **reactivity:** onCleanup also needs to be cleaned ([#8655](https://github.com/vuejs/core/issues/8655)) ([73fd810](https://github.com/vuejs/core/commit/73fd810eebdd383a2b4629f67736c4db1f428abd)), closes [#5151](https://github.com/vuejs/core/issues/5151) [#7695](https://github.com/vuejs/core/issues/7695) -* **ssr:** hydration `__vnode` missing for devtools ([#9328](https://github.com/vuejs/core/issues/9328)) ([5156ac5](https://github.com/vuejs/core/commit/5156ac5b38cfa80d3db26f2c9bf40cb22a7521cb)) -* **types:** allow falsy value types in `StyleValue` ([#7954](https://github.com/vuejs/core/issues/7954)) ([17aa92b](https://github.com/vuejs/core/commit/17aa92b79b31d8bb8b5873ddc599420cb9806db8)), closes [#7955](https://github.com/vuejs/core/issues/7955) -* **types:** defineCustomElement using defineComponent return type with emits ([#7937](https://github.com/vuejs/core/issues/7937)) ([5d932a8](https://github.com/vuejs/core/commit/5d932a8e6d14343c9d7fc7c2ecb58ac618b2f938)), closes [#7782](https://github.com/vuejs/core/issues/7782) -* **types:** fix `unref` and `toValue` when input union type contains ComputedRef ([#8748](https://github.com/vuejs/core/issues/8748)) ([176d476](https://github.com/vuejs/core/commit/176d47671271b1abc21b1508e9a493c7efca6451)), closes [#8747](https://github.com/vuejs/core/issues/8747) [#8857](https://github.com/vuejs/core/issues/8857) -* **types:** fix instance type when props type is incompatible with setup returned type ([#7338](https://github.com/vuejs/core/issues/7338)) ([0e1e8f9](https://github.com/vuejs/core/commit/0e1e8f919e5a74cdaadf9c80ee135088b25e7fa3)), closes [#5885](https://github.com/vuejs/core/issues/5885) -* **types:** fix shallowRef return type with union value type ([#7853](https://github.com/vuejs/core/issues/7853)) ([7c44800](https://github.com/vuejs/core/commit/7c448000b0def910c2cfabfdf7ff20a3d6bc844f)), closes [#7852](https://github.com/vuejs/core/issues/7852) -* **types:** more precise types for class bindings ([#8012](https://github.com/vuejs/core/issues/8012)) ([46e3374](https://github.com/vuejs/core/commit/46e33744c890bd49482c5e5c5cdea44e00ec84d5)) -* **types:** remove optional properties from defineProps return type ([#6421](https://github.com/vuejs/core/issues/6421)) ([94c049d](https://github.com/vuejs/core/commit/94c049d930d922069e38ea8700d7ff0970f71e61)), closes [#6420](https://github.com/vuejs/core/issues/6420) -* **types:** return type of withDefaults should be readonly ([#8601](https://github.com/vuejs/core/issues/8601)) ([f15debc](https://github.com/vuejs/core/commit/f15debc01acb22d23f5acee97e6f02db88cef11a)) -* **types:** revert class type restrictions ([5d077c8](https://github.com/vuejs/core/commit/5d077c8754cc14f85d2d6d386df70cf8c0d93842)), closes [#8012](https://github.com/vuejs/core/issues/8012) -* **types:** update jsx type definitions ([#8607](https://github.com/vuejs/core/issues/8607)) ([58e2a94](https://github.com/vuejs/core/commit/58e2a94871ae06a909c5f8bad07fb401193e6a38)) -* **types:** widen ClassValue type ([2424013](https://github.com/vuejs/core/commit/242401305944422d0c361b16101a4d18908927af)) -* **v-model:** avoid overwriting number input with same value ([#7004](https://github.com/vuejs/core/issues/7004)) ([40f4b77](https://github.com/vuejs/core/commit/40f4b77bb570868cb6e47791078767797e465989)), closes [#7003](https://github.com/vuejs/core/issues/7003) -* **v-model:** unnecessary value binding error should apply to dynamic instead of static binding ([2859b65](https://github.com/vuejs/core/commit/2859b653c9a22460e60233cac10fe139e359b046)), closes [#3596](https://github.com/vuejs/core/issues/3596) +* **compiler-sfc:** do not skip `TSSatisfiesExpression` when transforming props destructure ([#12062](https://github.com/vuejs/core/issues/12062)) ([2328b05](https://github.com/vuejs/core/commit/2328b051f4efa1f1394b7d4e73b7c3f76e430e7c)), closes [#12061](https://github.com/vuejs/core/issues/12061) +* **reactivity:** prevent overwriting `next` property during batch processing ([#12075](https://github.com/vuejs/core/issues/12075)) ([d3f5e6e](https://github.com/vuejs/core/commit/d3f5e6e5319b4ffaa55ca9a2ea3d95d78e76fa58)), closes [#12072](https://github.com/vuejs/core/issues/12072) +* **scheduler:** job ordering when the post queue is flushing ([#12090](https://github.com/vuejs/core/issues/12090)) ([577edca](https://github.com/vuejs/core/commit/577edca8e7795436efd710d1c289ea8ea2642b0e)) +* **types:** correctly infer `TypeProps` when it is `any` ([#12073](https://github.com/vuejs/core/issues/12073)) ([57315ab](https://github.com/vuejs/core/commit/57315ab9688c9741a271d1075bbd28cbe5f71e2f)), closes [#12058](https://github.com/vuejs/core/issues/12058) +* **types:** should not intersect `PublicProps` with `Props` ([#12077](https://github.com/vuejs/core/issues/12077)) ([6f85894](https://github.com/vuejs/core/commit/6f8589437635706f825ccec51800effba1d2bf5f)) +* **types:** infer the first generic type of `Ref` correctly ([#12094](https://github.com/vuejs/core/issues/12094)) ([c97bb84](https://github.com/vuejs/core/commit/c97bb84d0b0a16b012f886b6498e924415ed63e5)) -## [3.3.8](https://github.com/vuejs/core/compare/v3.3.7...v3.3.8) (2023-11-06) +## [3.5.10](https://github.com/vuejs/core/compare/v3.5.9...v3.5.10) (2024-09-27) ### Bug Fixes -* **compile-sfc:** support `Error` type in `defineProps` ([#5955](https://github.com/vuejs/core/issues/5955)) ([a989345](https://github.com/vuejs/core/commit/a9893458ec519aae442e1b99e64e6d74685cd22c)) -* **compiler-core:** known global should be shadowed by local variables in expression rewrite ([#9492](https://github.com/vuejs/core/issues/9492)) ([a75d1c5](https://github.com/vuejs/core/commit/a75d1c5c6242e91a73cc5ba01e6da620dea0b3d9)), closes [#9482](https://github.com/vuejs/core/issues/9482) -* **compiler-sfc:** fix dynamic directive arguments usage check for slots ([#9495](https://github.com/vuejs/core/issues/9495)) ([b39fa1f](https://github.com/vuejs/core/commit/b39fa1f8157647859331ce439c42ae016a49b415)), closes [#9493](https://github.com/vuejs/core/issues/9493) -* **deps:** update dependency @vue/repl to ^2.6.2 ([#9536](https://github.com/vuejs/core/issues/9536)) ([5cef325](https://github.com/vuejs/core/commit/5cef325f41e3b38657c72fa1a38dedeee1c7a60a)) -* **deps:** update dependency @vue/repl to ^2.6.3 ([#9540](https://github.com/vuejs/core/issues/9540)) ([176d590](https://github.com/vuejs/core/commit/176d59058c9aecffe9da4d4311e98496684f06d4)) -* **hydration:** fix tagName access eeror on comment/text node hydration mismatch ([dd8a0cf](https://github.com/vuejs/core/commit/dd8a0cf5dcde13d2cbd899262a0e07f16e14e489)), closes [#9531](https://github.com/vuejs/core/issues/9531) -* **types:** avoid exposing lru-cache types in generated dts ([462aeb3](https://github.com/vuejs/core/commit/462aeb3b600765e219ded2ee9a0ed1e74df61de0)), closes [#9521](https://github.com/vuejs/core/issues/9521) -* **warn:** avoid warning on empty children with Suspense ([#3962](https://github.com/vuejs/core/issues/3962)) ([405f345](https://github.com/vuejs/core/commit/405f34587a63a5f1e3d147b9848219ea98acc22d)) +* **custom-element:** properly set kebab-case props on Vue custom elements ([ea3efa0](https://github.com/vuejs/core/commit/ea3efa09e008918c1d9ba7226833a8b1a7a57244)), closes [#12030](https://github.com/vuejs/core/issues/12030) [#12032](https://github.com/vuejs/core/issues/12032) +* **reactivity:** fix nested batch edge case ([93c95dd](https://github.com/vuejs/core/commit/93c95dd4cd416503f43a98a1455f62658d22b0b2)) +* **reactivity:** only clear notified flags for computed in first batch iteration ([aa9ef23](https://github.com/vuejs/core/commit/aa9ef2386a0cd39a174e5a887ec2b1a3525034fc)), closes [#12045](https://github.com/vuejs/core/issues/12045) +* **types/ref:** handle nested refs in UnwrapRef ([#12049](https://github.com/vuejs/core/issues/12049)) ([e2c19c2](https://github.com/vuejs/core/commit/e2c19c20cfee9788519a80c0e53e216b78505994)), closes [#12044](https://github.com/vuejs/core/issues/12044) -## [3.3.7](https://github.com/vuejs/core/compare/v3.3.6...v3.3.7) (2023-10-24) +## [3.5.9](https://github.com/vuejs/core/compare/v3.5.8...v3.5.9) (2024-09-26) ### Bug Fixes -* **compiler-sfc:** avoid gen useCssVars when targeting SSR ([#6979](https://github.com/vuejs/core/issues/6979)) ([c568778](https://github.com/vuejs/core/commit/c568778ea3265d8e57f788b00864c9509bf88a4e)), closes [#6926](https://github.com/vuejs/core/issues/6926) -* **compiler-ssr:** proper scope analysis for ssr vnode slot fallback ([#7184](https://github.com/vuejs/core/issues/7184)) ([e09c26b](https://github.com/vuejs/core/commit/e09c26bc9bc4394c2c2d928806d382515c2676f3)), closes [#7095](https://github.com/vuejs/core/issues/7095) -* correctly resolve types from relative paths on Windows ([#9446](https://github.com/vuejs/core/issues/9446)) ([089d36d](https://github.com/vuejs/core/commit/089d36d167dc7834065b03ca689f9b6a44eead8a)), closes [#8671](https://github.com/vuejs/core/issues/8671) -* **hmr:** fix hmr error for hoisted children array in v-for ([7334376](https://github.com/vuejs/core/commit/733437691f70ebca8dd6cc3bc8356f5b57d4d5d8)), closes [#6978](https://github.com/vuejs/core/issues/6978) [#7114](https://github.com/vuejs/core/issues/7114) -* **reactivity:** assigning array.length while observing a symbol property ([#7568](https://github.com/vuejs/core/issues/7568)) ([e9e2778](https://github.com/vuejs/core/commit/e9e2778e9ec5cca07c1df5f0c9b7b3595a1a3244)) -* **scheduler:** ensure jobs are in the correct order ([#7748](https://github.com/vuejs/core/issues/7748)) ([a8f6638](https://github.com/vuejs/core/commit/a8f663867b8cd2736b82204bc58756ef02441276)), closes [#7576](https://github.com/vuejs/core/issues/7576) -* **ssr:** fix hydration mismatch for disabled teleport at component root ([#9399](https://github.com/vuejs/core/issues/9399)) ([d8990fc](https://github.com/vuejs/core/commit/d8990fc6182d1c2cf0a8eab7b35a9d04df668507)), closes [#6152](https://github.com/vuejs/core/issues/6152) -* **Suspense:** calling hooks before the transition finishes ([#9388](https://github.com/vuejs/core/issues/9388)) ([00de3e6](https://github.com/vuejs/core/commit/00de3e61ed7a55e7d6c2e1987551d66ad0f909ff)), closes [#5844](https://github.com/vuejs/core/issues/5844) [#5952](https://github.com/vuejs/core/issues/5952) -* **transition/ssr:** make transition appear work with SSR ([#8859](https://github.com/vuejs/core/issues/8859)) ([5ea8a8a](https://github.com/vuejs/core/commit/5ea8a8a4fab4e19a71e123e4d27d051f5e927172)), closes [#6951](https://github.com/vuejs/core/issues/6951) -* **types:** fix ComponentCustomProps augmentation ([#9468](https://github.com/vuejs/core/issues/9468)) ([7374e93](https://github.com/vuejs/core/commit/7374e93f0281f273b90ab5a6724cc47332a01d6c)), closes [#8376](https://github.com/vuejs/core/issues/8376) -* **types:** improve `h` overload to support union of string and component ([#5432](https://github.com/vuejs/core/issues/5432)) ([16ecb44](https://github.com/vuejs/core/commit/16ecb44c89cd8299a3b8de33cccc2e2cc36f065b)), closes [#5431](https://github.com/vuejs/core/issues/5431) +* **reactivity:** fix property dep removal regression ([6001e5c](https://github.com/vuejs/core/commit/6001e5c81a05c894586f9287fbd991677bdd0455)), closes [#12020](https://github.com/vuejs/core/issues/12020) [#12021](https://github.com/vuejs/core/issues/12021) +* **reactivity:** fix recursive sync watcher on computed edge case ([10ff159](https://github.com/vuejs/core/commit/10ff15924053d9bd95ad706f78ce09e288213fcf)), closes [#12033](https://github.com/vuejs/core/issues/12033) [#12037](https://github.com/vuejs/core/issues/12037) +* **runtime-core:** avoid rendering plain object as VNode ([#12038](https://github.com/vuejs/core/issues/12038)) ([cb34b28](https://github.com/vuejs/core/commit/cb34b28a4a9bf868be4785b001c526163eda342e)), closes [#12035](https://github.com/vuejs/core/issues/12035) [vitejs/vite-plugin-vue#353](https://github.com/vitejs/vite-plugin-vue/issues/353) +* **runtime-core:** make useId() always return a string ([a177092](https://github.com/vuejs/core/commit/a177092754642af2f98c33a4feffe8f198c3c950)) +* **types:** correct type inference of union event names ([#12022](https://github.com/vuejs/core/issues/12022)) ([4da6881](https://github.com/vuejs/core/commit/4da688141d9e7c15b622c289deaa81b11845b2c7)) +* **vue:** properly cache runtime compilation ([#12019](https://github.com/vuejs/core/issues/12019)) ([fa0ba24](https://github.com/vuejs/core/commit/fa0ba24b3ace02d7ecab65e57c2bea89a2550dcb)) -## [3.3.6](https://github.com/vuejs/core/compare/v3.3.5...v3.3.6) (2023-10-20) +## [3.5.8](https://github.com/vuejs/core/compare/v3.5.7...v3.5.8) (2024-09-22) ### Bug Fixes -* **compiler-sfc:** model name conflict ([#8798](https://github.com/vuejs/core/issues/8798)) ([df81da8](https://github.com/vuejs/core/commit/df81da8be97c8a1366563c7e3e01076ef02eb8f7)) -* **compiler-sfc:** support asset paths containing spaces ([#8752](https://github.com/vuejs/core/issues/8752)) ([36c99a9](https://github.com/vuejs/core/commit/36c99a9c6bb6bc306be054c3c8a85ff8ce50605a)) -* **compiler-ssr:** fix missing scopeId on server-rendered TransitionGroup ([#7557](https://github.com/vuejs/core/issues/7557)) ([61c1357](https://github.com/vuejs/core/commit/61c135742795aa5e3189a79c7dec6afa21bbc8d9)), closes [#7554](https://github.com/vuejs/core/issues/7554) -* **compiler-ssr:** fix ssr compile error for select with non-option children ([#9442](https://github.com/vuejs/core/issues/9442)) ([cdb2e72](https://github.com/vuejs/core/commit/cdb2e725e7ea297f1f4180fb04889a3b757bc84e)), closes [#9440](https://github.com/vuejs/core/issues/9440) -* **runtime-core:** delete stale slots which are present but undefined ([#6484](https://github.com/vuejs/core/issues/6484)) ([75b8722](https://github.com/vuejs/core/commit/75b872213574cb37e2c9e8a15f65613f867ca9a6)), closes [#9109](https://github.com/vuejs/core/issues/9109) -* **runtime-core:** fix error when using cssvars with disabled teleport ([#7341](https://github.com/vuejs/core/issues/7341)) ([8f0472c](https://github.com/vuejs/core/commit/8f0472c9abedb337dc256143b69d8ab8759dbf5c)), closes [#7342](https://github.com/vuejs/core/issues/7342) -* **teleport:** ensure descendent component would be unmounted correctly ([#6529](https://github.com/vuejs/core/issues/6529)) ([4162311](https://github.com/vuejs/core/commit/4162311efdb0db5ca458542e1604b19efa2fae0e)), closes [#6347](https://github.com/vuejs/core/issues/6347) -* **types:** support contenteditable="plaintext-only" ([#8796](https://github.com/vuejs/core/issues/8796)) ([26ca89e](https://github.com/vuejs/core/commit/26ca89e5cf734fbef81e182050d2a215ec8a437b)) +* **reactivity:** do not remove dep from depsMap when cleaning up deps of computed ([#11995](https://github.com/vuejs/core/issues/11995)) ([0267a58](https://github.com/vuejs/core/commit/0267a588017eee4951ac2a877fe1ccae84cad905)) + + + +## [3.5.7](https://github.com/vuejs/core/compare/v3.5.6...v3.5.7) (2024-09-20) + + +### Bug Fixes + +* **compile-core:** fix v-model with newlines edge case ([#11960](https://github.com/vuejs/core/issues/11960)) ([6224288](https://github.com/vuejs/core/commit/62242886d705ece88dbcad45bb78072ecccad0ca)), closes [#8306](https://github.com/vuejs/core/issues/8306) +* **compiler-sfc:** initialize scope with null prototype object ([#11963](https://github.com/vuejs/core/issues/11963)) ([215e154](https://github.com/vuejs/core/commit/215e15407294bf667261360218f975b88c99c2e5)) +* **hydration:** avoid observing non-Element node ([#11954](https://github.com/vuejs/core/issues/11954)) ([7257e6a](https://github.com/vuejs/core/commit/7257e6a34200409b3fc347d3bb807e11e2785974)), closes [#11952](https://github.com/vuejs/core/issues/11952) +* **reactivity:** do not remove dep from depsMap when unsubbed by computed ([960706e](https://github.com/vuejs/core/commit/960706eebf73f08ebc9d5dd853a05def05e2c153)) +* **reactivity:** fix dev-only memory leak by updating dep.subsHead on sub removal ([5c8b76e](https://github.com/vuejs/core/commit/5c8b76ed6cfbbcee4cbaac0b72beab7291044e4f)), closes [#11956](https://github.com/vuejs/core/issues/11956) +* **reactivity:** fix memory leak from dep instances of garbage collected objects ([235ea47](https://github.com/vuejs/core/commit/235ea4772ed2972914cf142da8b7ac1fb04f7585)), closes [#11979](https://github.com/vuejs/core/issues/11979) [#11971](https://github.com/vuejs/core/issues/11971) +* **reactivity:** fix triggerRef call on ObjectRefImpl returned by toRef ([#11986](https://github.com/vuejs/core/issues/11986)) ([b030c8b](https://github.com/vuejs/core/commit/b030c8bc7327877efb98aa3d9a58eb287a6ff07a)), closes [#11982](https://github.com/vuejs/core/issues/11982) +* **scheduler:** ensure recursive jobs can't be queued twice ([#11955](https://github.com/vuejs/core/issues/11955)) ([d18d6aa](https://github.com/vuejs/core/commit/d18d6aa1b20dc57a8103c51ec4d61e8e53ed936d)) +* **ssr:** don't render comments in TransitionGroup ([#11961](https://github.com/vuejs/core/issues/11961)) ([a2f6ede](https://github.com/vuejs/core/commit/a2f6edeb02faedbb673c4bc5c6a59d9a79a37d07)), closes [#11958](https://github.com/vuejs/core/issues/11958) +* **transition:** respect `duration` setting even when it is `0` ([#11967](https://github.com/vuejs/core/issues/11967)) ([f927a4a](https://github.com/vuejs/core/commit/f927a4ae6f7c453f70ba89498ee0c737dc9866fd)) +* **types:** correct type inference of all-optional props ([#11644](https://github.com/vuejs/core/issues/11644)) ([9eca65e](https://github.com/vuejs/core/commit/9eca65ee9871d1ac878755afa9a3eb1b02030350)), closes [#11733](https://github.com/vuejs/core/issues/11733) [vuejs/language-tools#4704](https://github.com/vuejs/language-tools/issues/4704) ### Performance Improvements -* replace Map/Set with WeakMap/WeakSet ([#8549](https://github.com/vuejs/core/issues/8549)) ([712f96d](https://github.com/vuejs/core/commit/712f96d6ac4d3d984732cba448cb84624daba850)) +* **hydration:** avoid observer if element is in viewport ([#11639](https://github.com/vuejs/core/issues/11639)) ([e075dfa](https://github.com/vuejs/core/commit/e075dfad5c7649c6045e3711687ec888e7aa1a39)) -## [3.3.5](https://github.com/vuejs/core/compare/v3.3.4...v3.3.5) (2023-10-20) +## [3.5.6](https://github.com/vuejs/core/compare/v3.5.5...v3.5.6) (2024-09-16) ### Bug Fixes -* add isGloballyWhitelisted back, but deprecated ([#8556](https://github.com/vuejs/core/issues/8556)) ([63dfe8e](https://github.com/vuejs/core/commit/63dfe8eab499979bcc2f7829e82464e13899c895)), closes [#8416](https://github.com/vuejs/core/issues/8416) -* **build:** disable useDefineForClassFields in esbuild ([#9252](https://github.com/vuejs/core/issues/9252)) ([6d14fa8](https://github.com/vuejs/core/commit/6d14fa88e85d4c9e264be394ddb37a54ca6738a8)) -* **compat:** return value of vue compat set() ([#9377](https://github.com/vuejs/core/issues/9377)) ([e3c2d69](https://github.com/vuejs/core/commit/e3c2d699f694d9500ddee78571172a24f0e3b17a)) -* **compiler-sfc:** don't hoist props and emit ([#8535](https://github.com/vuejs/core/issues/8535)) ([24db951](https://github.com/vuejs/core/commit/24db9516d8b4857182ec1a3af86cb7346691679b)), closes [#7805](https://github.com/vuejs/core/issues/7805) [#7812](https://github.com/vuejs/core/issues/7812) -* **compiler-sfc:** don't registerTS when bundling for browsers ([#8582](https://github.com/vuejs/core/issues/8582)) ([6f45f76](https://github.com/vuejs/core/commit/6f45f76df2c43796b35067ef8f8b9a7bca454040)) -* **compiler-sfc:** fix using imported ref as template ref during dev ([#7593](https://github.com/vuejs/core/issues/7593)) ([776ebf2](https://github.com/vuejs/core/commit/776ebf25b2e7570e78ac1c148fc45c823c21a542)), closes [#7567](https://github.com/vuejs/core/issues/7567) -* **compiler-sfc:** handle dynamic directive arguments in template usage check ([#8538](https://github.com/vuejs/core/issues/8538)) ([e404a69](https://github.com/vuejs/core/commit/e404a699f48ae5c5a5da947f42679343192158c7)), closes [#8537](https://github.com/vuejs/core/issues/8537) -* **compiler-sfc:** ignore style v-bind in double slash comments ([#5409](https://github.com/vuejs/core/issues/5409)) ([381b497](https://github.com/vuejs/core/commit/381b4977af25ba5392704f72ec6b3f2394d87ae7)) -* **compiler-sfc:** pass options directly to stylus ([#3848](https://github.com/vuejs/core/issues/3848)) ([d6446a6](https://github.com/vuejs/core/commit/d6446a6d40774b79045a9ddba7b5fd5201d51450)) -* **compiler-sfc:** support resolve multiple re-export /w same source type name ([#8365](https://github.com/vuejs/core/issues/8365)) ([4fa8da8](https://github.com/vuejs/core/commit/4fa8da8576717c619e1e8c04d19038488c75fbea)), closes [#8364](https://github.com/vuejs/core/issues/8364) -* **compiler-sfc:** typo in experimental feature warnings ([#8513](https://github.com/vuejs/core/issues/8513)) ([fd1a3f9](https://github.com/vuejs/core/commit/fd1a3f95990d7c372fa1c0c40c55caca761a33a4)) -* **deps:** update dependency monaco-editor to ^0.44.0 ([#9237](https://github.com/vuejs/core/issues/9237)) ([8611874](https://github.com/vuejs/core/commit/8611874e09a827b6491173836c8942284d5de22c)) -* **deps:** update playground ([#9154](https://github.com/vuejs/core/issues/9154)) ([c8566a2](https://github.com/vuejs/core/commit/c8566a22b7cf37e6aefab7bad7b97ce2db9fae4c)) -* **playground:** fix github button style ([#7722](https://github.com/vuejs/core/issues/7722)) ([5ee992c](https://github.com/vuejs/core/commit/5ee992cfeabc6c4b871980c6057d0ac7140ad2fa)) -* **runtime-core:** swap client/server debug labels ([#9089](https://github.com/vuejs/core/issues/9089)) ([8f311c6](https://github.com/vuejs/core/commit/8f311c6f823f6776ca1c49bfbbbf8c7d9dea9cf1)) -* **ssr:** render correct initial selected state for select with v-model ([#7432](https://github.com/vuejs/core/issues/7432)) ([201c46d](https://github.com/vuejs/core/commit/201c46df07a38f3c2b73f384e8e6846dc62f224e)), closes [#7392](https://github.com/vuejs/core/issues/7392) -* **ssr:** reset current instance if setting up options component errors ([#7743](https://github.com/vuejs/core/issues/7743)) ([020851e](https://github.com/vuejs/core/commit/020851e57d9a9f727c6ea07e9c1575430af02b73)), closes [#7733](https://github.com/vuejs/core/issues/7733) -* **teleport:** handle target change while disabled ([#7837](https://github.com/vuejs/core/issues/7837)) ([140a89b](https://github.com/vuejs/core/commit/140a89b833bceed60838182b875d2953c70af114)), closes [#7835](https://github.com/vuejs/core/issues/7835) -* **transition:** handle possible auto value for transition/animation durations ([96c76fa](https://github.com/vuejs/core/commit/96c76facb7de37fc241ccd55e121fd60a49a1452)), closes [#8409](https://github.com/vuejs/core/issues/8409) -* **types/jsx:** add `inert` attribute and missing `hidden` values ([#8090](https://github.com/vuejs/core/issues/8090)) ([ceb0732](https://github.com/vuejs/core/commit/ceb0732e0b1bb4c8c505d80e97ff6fc89035fa90)) -* **types/jsx:** add missing loading attr for img element ([#6160](https://github.com/vuejs/core/issues/6160)) ([68d6b43](https://github.com/vuejs/core/commit/68d6b43f7e29b76aab2c6c1882885380a43fa3e3)) -* **types:** correct withDefaults return type for boolean prop with undefined default value ([#8602](https://github.com/vuejs/core/issues/8602)) ([f07cb18](https://github.com/vuejs/core/commit/f07cb18fedf9a446545aadf76bcdfb957c7ebcbd)) -* **types:** ensure nextTick return type reflect correct Promise value ([#8406](https://github.com/vuejs/core/issues/8406)) ([6a22b1f](https://github.com/vuejs/core/commit/6a22b1f6c287b60eda385df8a514335af8e040ea)) -* **types:** support correct types for style on svg elements ([#6322](https://github.com/vuejs/core/issues/6322)) ([364dc53](https://github.com/vuejs/core/commit/364dc53c7cc6f97d812ad175199c698faa92538e)) +* **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 1`] = ` { - "cached": 0, + "cached": [], "children": [ { "children": [ @@ -6189,7 +4275,6 @@ exports[`compiler: parse > Errors > X_INVALID_END_TAG > ", "temps": 0, "type": 0, } @@ -6236,7 +4322,7 @@ exports[`compiler: parse > Errors > X_INVALID_END_TAG > `, { + parseMode: 'html', + }) + expect((ast3.children[0] as ElementNode).children).toMatchObject([ + { + type: NodeTypes.ELEMENT, + children: [ + { + type: NodeTypes.TEXT, + content: `{{ foo `, + }, + ], + }, + ]) + }) + test('self-closing v-pre', () => { const ast = baseParse( - `
\n
{{ bar }}
` + `
\n
{{ bar }}
`, ) // should not affect siblings after it const divWithoutPre = ast.children[1] as ElementNode @@ -1772,38 +2049,37 @@ describe('compiler: parse', () => { arg: { type: NodeTypes.SIMPLE_EXPRESSION, isStatic: true, - content: `id` + content: `id`, }, exp: { type: NodeTypes.SIMPLE_EXPRESSION, isStatic: false, - content: `foo` + content: `foo`, }, loc: { - source: `:id="foo"`, start: { line: 2, - column: 6 + column: 6, }, end: { line: 2, - column: 15 - } - } - } + column: 15, + }, + }, + }, ]) expect(divWithoutPre.children[0]).toMatchObject({ type: NodeTypes.ELEMENT, tagType: ElementTypes.COMPONENT, - tag: `Comp` + tag: `Comp`, }) expect(divWithoutPre.children[1]).toMatchObject({ type: NodeTypes.INTERPOLATION, content: { type: NodeTypes.SIMPLE_EXPRESSION, content: `bar`, - isStatic: false - } + isStatic: false, + }, }) }) @@ -1818,133 +2094,187 @@ describe('compiler: parse', () => { loc: { start: { offset: 5, line: 1, column: 6 }, end: { offset: 10, line: 1, column: 11 }, - source: 'hello' - } + source: 'hello', + }, }) }) }) - test('self closing single tag', () => { - const ast = baseParse('
') + describe('Edge Cases', () => { + test('self closing single tag', () => { + const ast = baseParse('
') - expect(ast.children).toHaveLength(1) - expect(ast.children[0]).toMatchObject({ tag: 'div' }) - }) - - test('self closing multiple tag', () => { - const ast = baseParse( - `
\n` + - `

` - ) - - expect(ast).toMatchSnapshot() - - expect(ast.children).toHaveLength(2) - expect(ast.children[0]).toMatchObject({ tag: 'div' }) - expect(ast.children[1]).toMatchObject({ tag: 'p' }) - }) - - test('valid html', () => { - const ast = baseParse( - `

\n` + - `

\n` + - ` \n` + - `

` - ) - - expect(ast).toMatchSnapshot() - - expect(ast.children).toHaveLength(1) - const el = ast.children[0] as any - expect(el).toMatchObject({ - tag: 'div' - }) - expect(el.children).toHaveLength(2) - expect(el.children[0]).toMatchObject({ - tag: 'p' - }) - expect(el.children[1]).toMatchObject({ - type: NodeTypes.COMMENT - }) - }) - - test('invalid html', () => { - expect(() => { - baseParse(`
\n\n
\n`) - }).toThrow('Element is missing end tag.') - - const spy = vi.fn() - const ast = baseParse(`
\n\n
\n`, { - onError: spy + expect(ast.children).toHaveLength(1) + expect(ast.children[0]).toMatchObject({ tag: 'div' }) }) - expect(spy.mock.calls).toMatchObject([ - [ + test('self closing multiple tag', () => { + const ast = baseParse( + `
\n` + + `

`, + ) + + expect(ast).toMatchSnapshot() + + expect(ast.children).toHaveLength(2) + expect(ast.children[0]).toMatchObject({ tag: 'div' }) + expect(ast.children[1]).toMatchObject({ tag: 'p' }) + }) + + test('valid html', () => { + const ast = baseParse( + `

\n` + + `

\n` + + ` \n` + + `

`, + ) + + expect(ast).toMatchSnapshot() + + expect(ast.children).toHaveLength(1) + const el = ast.children[0] as any + expect(el).toMatchObject({ + tag: 'div', + }) + expect(el.children).toHaveLength(2) + expect(el.children[0]).toMatchObject({ + tag: 'p', + }) + expect(el.children[1]).toMatchObject({ + type: NodeTypes.COMMENT, + }) + }) + + test('invalid html', () => { + expect(() => { + baseParse(`
\n\n
\n`) + }).toThrow('Element is missing end tag.') + + const spy = vi.fn() + const ast = baseParse(`
\n\n
\n`, { + onError: spy, + }) + + expect(spy.mock.calls).toMatchObject([ + [ + { + code: ErrorCodes.X_MISSING_END_TAG, + loc: { + start: { + offset: 6, + line: 2, + column: 1, + }, + }, + }, + ], + [ + { + code: ErrorCodes.X_INVALID_END_TAG, + loc: { + start: { + offset: 20, + line: 4, + column: 1, + }, + }, + }, + ], + ]) + + expect(ast).toMatchSnapshot() + }) + + test('parse with correct location info', () => { + const fooSrc = `foo\n is ` + const barSrc = `{{ bar }}` + const butSrc = ` but ` + const bazSrc = `{{ baz }}` + const [foo, bar, but, baz] = baseParse( + fooSrc + barSrc + butSrc + bazSrc, + ).children + + let offset = 0 + expect(foo.loc.start).toEqual({ line: 1, column: 1, offset }) + offset += fooSrc.length + expect(foo.loc.end).toEqual({ line: 2, column: 5, offset }) + + expect(bar.loc.start).toEqual({ line: 2, column: 5, offset }) + const barInner = (bar as InterpolationNode).content + offset += 3 + expect(barInner.loc.start).toEqual({ line: 2, column: 8, offset }) + offset += 3 + expect(barInner.loc.end).toEqual({ line: 2, column: 11, offset }) + offset += 3 + expect(bar.loc.end).toEqual({ line: 2, column: 14, offset }) + + expect(but.loc.start).toEqual({ line: 2, column: 14, offset }) + offset += butSrc.length + expect(but.loc.end).toEqual({ line: 2, column: 19, offset }) + + expect(baz.loc.start).toEqual({ line: 2, column: 19, offset }) + const bazInner = (baz as InterpolationNode).content + offset += 3 + expect(bazInner.loc.start).toEqual({ line: 2, column: 22, offset }) + offset += 3 + expect(bazInner.loc.end).toEqual({ line: 2, column: 25, offset }) + offset += 3 + expect(baz.loc.end).toEqual({ line: 2, column: 28, offset }) + }) + + // With standard HTML parsing, the following input would ignore the slash + // and treat "<" and "template" as attributes on the open tag of "Hello", + // causing `