diff --git a/.circleci/config.yml b/.circleci/config.yml deleted file mode 100644 index bb2a2df1752..00000000000 --- a/.circleci/config.yml +++ /dev/null @@ -1,53 +0,0 @@ -version: 2 - -defaults: &defaults - docker: - - image: vuejs/ci - -step_restore_cache: &restore_cache - restore_cache: - keys: - - v1-dependencies-{{ checksum "yarn.lock" }}-1 - - v1-dependencies- - -step_install_deps: &install_deps - run: - name: Install Dependencies - command: yarn --frozen-lockfile - -step_save_cache: &save_cache - save_cache: - paths: - - node_modules - - packages/compiler-core/node_modules - - packages/compiler-sfc/node_modules - - packages/vue/node_modules - - ~/.cache/yarn - key: v1-dependencies-{{ checksum "yarn.lock" }}-1 - -jobs: - test: - <<: *defaults - steps: - - checkout - - *restore_cache - - *install_deps - - *save_cache - - run: yarn ls-lint - - run: yarn test --ci - - test-dts: - <<: *defaults - steps: - - checkout - - *restore_cache - - *install_deps - - *save_cache - - run: yarn test-dts - -workflows: - version: 2 - ci: - jobs: - - test - - test-dts diff --git a/.eslintrc.cjs b/.eslintrc.cjs new file mode 100644 index 00000000000..4296d0f39b6 --- /dev/null +++ b/.eslintrc.cjs @@ -0,0 +1,88 @@ +/* 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/.eslintrc.js b/.eslintrc.js deleted file mode 100644 index 98f42a74b9a..00000000000 --- a/.eslintrc.js +++ /dev/null @@ -1,66 +0,0 @@ -const DOMGlobals = ['window', 'document'] -const NodeGlobals = ['module', 'require'] - -module.exports = { - parser: '@typescript-eslint/parser', - parserOptions: { - sourceType: 'module' - }, - rules: { - 'no-unused-vars': [ - 'error', - // we are only using this rule to check for unused arguments since TS - // catches unused variables but not args. - { varsIgnorePattern: '.*', args: 'none' } - ], - // most of the codebase are expected to be env agnostic - 'no-restricted-globals': ['error', ...DOMGlobals, ...NodeGlobals], - // since we target ES2015 for baseline support, we need to forbid object - // rest spread usage (both assign and destructure) - 'no-restricted-syntax': [ - 'error', - 'ObjectExpression > SpreadElement', - 'ObjectPattern > RestElement' - ] - }, - overrides: [ - // tests, no restrictions (runs in Node / jest with jsdom) - { - files: ['**/__tests__/**', 'test-dts/**'], - rules: { - 'no-restricted-globals': 'off', - 'no-restricted-syntax': 'off' - } - }, - // shared, may be used in any env - { - files: ['packages/shared/**'], - rules: { - 'no-restricted-globals': 'off' - } - }, - // Packages targeting DOM - { - files: ['packages/{vue,runtime-dom}/**'], - rules: { - 'no-restricted-globals': ['error', ...NodeGlobals] - } - }, - // Packages targeting Node - { - files: ['packages/{compiler-sfc,compiler-ssr,server-renderer}/**'], - rules: { - 'no-restricted-globals': ['error', ...DOMGlobals], - 'no-restricted-syntax': 'off' - } - }, - // Private package, browser only + no syntax restrictions - { - files: ['packages/template-explorer/**'], - rules: { - 'no-restricted-globals': ['error', ...NodeGlobals], - 'no-restricted-syntax': 'off' - } - } - ] -} diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml index 4a8f6fd424f..9288efdb9ac 100644 --- a/.github/FUNDING.yml +++ b/.github/FUNDING.yml @@ -1,3 +1,2 @@ -open_collective: vuejs -patreon: evanyou github: yyx990803 +open_collective: vuejs diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml new file mode 100644 index 00000000000..95e0ca79c07 --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug_report.yml @@ -0,0 +1,74 @@ +name: "\U0001F41E Bug report" +description: Create a report to help us improve +body: + - type: markdown + attributes: + value: | + **Before You Start...** + + This form is only for submitting bug reports. If you have a usage question + or are unsure if this is really a bug, make sure to: + + - Read the [docs](https://vuejs.org/) + - Ask on [Discord Chat](https://chat.vuejs.org/) + - Ask on [GitHub Discussions](https://github.com/vuejs/core/discussions) + - Look for / ask questions on [Stack Overflow](https://stackoverflow.com/questions/ask?tags=vue.js) + + Also try to search for your issue - it may have already been answered or even fixed in the development branch. + However, if you find that an old, closed issue still persists in the latest version, + you should open a new issue using the form below instead of commenting on the old issue. + - type: input + id: version + attributes: + label: Vue version + validations: + required: true + - type: input + id: reproduction-link + attributes: + label: Link to minimal reproduction + description: | + The easiest way to provide a reproduction is by showing the bug in [The SFC Playground](https://play.vuejs.org/). + If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue). + If neither of these are suitable, you can always provide a GitHub repository. + + The reproduction should be **minimal** - i.e. it should contain only the bare minimum amount of code needed + to show the bug. See [Bug Reproduction Guidelines](https://github.com/vuejs/core/blob/main/.github/bug-repro-guidelines.md) for more details. + + Please do not just fill in a random link. The issue will be closed if no valid reproduction is provided. + placeholder: Reproduction Link + validations: + required: true + - type: textarea + id: steps-to-reproduce + attributes: + label: Steps to reproduce + description: | + What do we need to do after opening your repro in order to make the bug happen? Clear and concise reproduction instructions are important for us to be able to triage your issue in a timely manner. Note that you can use [Markdown](https://guides.github.com/features/mastering-markdown/) to format lists and code. + placeholder: Steps to reproduce + validations: + required: true + - type: textarea + id: expected + attributes: + label: What is expected? + validations: + required: true + - type: textarea + id: actually-happening + attributes: + label: What is actually happening? + validations: + required: true + - type: textarea + id: system-info + attributes: + label: System Info + description: Output of `npx envinfo --system --npmPackages vue --binaries --browsers` + render: shell + placeholder: System, Binaries, Browsers + - type: textarea + id: additional-comments + attributes: + label: Any additional comments? + description: e.g. some background/context of how you ran into this bug. diff --git a/.github/ISSUE_TEMPLATE/config.yml b/.github/ISSUE_TEMPLATE/config.yml index ac8a00ef158..02f99c6bfbb 100644 --- a/.github/ISSUE_TEMPLATE/config.yml +++ b/.github/ISSUE_TEMPLATE/config.yml @@ -1,8 +1,14 @@ blank_issues_enabled: false contact_links: - - name: Create new issue - url: https://new-issue.vuejs.org/?repo=vuejs/vue-next - about: Please use the following link to create a new issue. + - name: Feature Request + url: https://github.com/vuejs/rfcs/discussions + about: Suggest new features for consideration + - name: Discord Chat + url: https://chat.vuejs.org + about: Ask questions and discuss with other Vue users in real time. + - name: Questions & Discussions + url: https://github.com/vuejs/core/discussions + about: Use GitHub discussions for message-board style questions and discussions. - name: Patreon url: https://www.patreon.com/evanyou about: Love Vue.js? Please consider supporting us via Patreon. diff --git a/.github/bug-repro-guidelines.md b/.github/bug-repro-guidelines.md new file mode 100644 index 00000000000..90458b30741 --- /dev/null +++ b/.github/bug-repro-guidelines.md @@ -0,0 +1,29 @@ +## About Bug Reproductions + +A bug reproduction is a piece of code that can run and demonstrate how a bug can happen. + +### Text is not enough + +It's impossible to fix a bug from mere text descriptions. First, it's very difficult to precisely describe a technical problem while keeping it easy to follow; Second, the real cause may very well be something that you forgot to even mention. A reproduction is the only way that can reliably help us understand what is going on, so please provide one. + +### A repro must be runnable + +Screenshots or videos are NOT reproductions! They only show that the bug exists, but do not provide enough information on why it happens. Only runnable code provides the most complete context and allows us to properly debug the scenario. That said, in some cases videos/gifs can help explain interaction issues that are hard to describe in text. + +### A repro should be minimal + +Some users would give us a link to a real project and hope we can help them figure out what is wrong. We generally do not accept such requests because: + +You are already familiar with your codebase, but we are not. It is extremely time-consuming to hunt a bug in a big and unfamiliar codebase. + +The problematic behavior may very well be caused by your code rather than by a bug in Vue. + +A minimal reproduction means it demonstrates the bug, and the bug only. It should only contain the bare minimum amount of code that can reliably cause the bug. Try your best to get rid of anything that aren't directly related to the problem. + +### How to create a repro + +For Vue 3 core reproductions, try reproducing it in [The SFC Playground](https://play.vuejs.org/). + +If it cannot be reproduced in the playground and requires a proper build setup, try [StackBlitz](https://vite.new/vue). + +If neither of these are suitable, you can always provide a GitHub repository. diff --git a/.github/contributing.md b/.github/contributing.md index a64b89a2fcb..9c385f1bcc9 100644 --- a/.github/contributing.md +++ b/.github/contributing.md @@ -2,10 +2,11 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before submitting your contribution, please make sure to take a moment and read through the following guidelines: -- [Code of Conduct](https://github.com/vuejs/vue/blob/dev/.github/CODE_OF_CONDUCT.md) +- [Code of Conduct](https://vuejs.org/about/coc.html) - [Issue Reporting Guidelines](#issue-reporting-guidelines) - [Pull Request Guidelines](#pull-request-guidelines) - [Development Setup](#development-setup) +- [Scripts](#scripts) - [Project Structure](#project-structure) - [Contributing Tests](#contributing-tests) - [Financial Contribution](#financial-contribution) @@ -16,7 +17,9 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before ## Pull Request Guidelines -- Checkout a topic branch from a base branch, e.g. `master`, and merge back against that branch. +- Checkout a topic branch from a base branch, e.g. `main`, and merge back against that branch. + +- [Make sure to tick the "Allow edits from maintainers" box](https://docs.github.com/en/pull-requests/collaborating-with-pull-requests/working-with-forks/allowing-changes-to-a-pull-request-branch-created-from-a-fork). This allows us to directly make minor edits / refactors and saves a lot of time. - If adding a new feature: @@ -27,36 +30,77 @@ Hi! I'm really excited that you are interested in contributing to Vue.js. Before - If you are resolving a special issue, add `(fix #xxxx[,#xxxx])` (#xxxx is the issue id) in your PR title for a better release log, e.g. `update entities encoding/decoding (fix #3899)`. - Provide a detailed description of the bug in the PR. Live demo preferred. - - Add appropriate test coverage if applicable. You can check the coverage of your code addition by running `yarn test --coverage`. + - Add appropriate test coverage if applicable. You can check the coverage of your code addition by running `nr test-coverage`. - It's OK to have multiple small commits as you work on the PR - GitHub can automatically squash them before merging. - Make sure tests pass! -- Commit messages must follow the [commit message convention](./commit-convention.md) so that changelogs can be automatically generated. Commit messages are automatically validated before commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)). +- Commit messages must follow the [commit message convention](./commit-convention.md) so that changelogs can be automatically generated. Commit messages are automatically validated before commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks)). + +- No need to worry about code style as long as you have installed the dev dependencies - modified files are automatically formatted with Prettier on commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks)). + +### Advanced Pull Request Tips + +- The PR should fix the intended bug **only** and not introduce unrelated changes. This includes unnecessary refactors - a PR should focus on the fix and not code style, this makes it easier to trace changes in the future. + +- Consider the performance / size impact of the changes, and whether the bug being fixes justifies the cost. If the bug being fixed is a very niche edge case, we should try to minimize the size / perf cost to make it worthwhile. -- No need to worry about code style as long as you have installed the dev dependencies - modified files are automatically formatted with Prettier on commit (by invoking [Git Hooks](https://git-scm.com/docs/githooks) via [yorkie](https://github.com/yyx990803/yorkie)). + - Is the code perf-sensitive (e.g. in "hot paths" like component updates or the vdom patch function?) + + - If the branch is dev-only, performance is less of a concern. + + - Check how much extra bundle size the change introduces. + - Make sure to put dev-only code in `__DEV__` branches so they are tree-shakable. + - Runtime code is more sensitive to size increase than compiler code. + - 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`. ## Development Setup -You will need [Node.js](http://nodejs.org) **version 10+**, and [Yarn 1.x](https://yarnpkg.com/en/docs/install). +You will need [Node.js](https://nodejs.org) **version 18.12+**, and [PNPM](https://pnpm.io) **version 8+**. + +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. After cloning the repo, run: ```bash -$ yarn # install the dependencies of the project +$ pnpm i # install the dependencies of the project ``` A high level overview of tools used: - [TypeScript](https://www.typescriptlang.org/) as the development language -- [Rollup](https://rollupjs.org) for bundling -- [Jest](https://jestjs.io/) for unit testing +- [Vite](https://vitejs.dev/) and [ESBuild](https://esbuild.github.io/) for development bundling +- [Rollup](https://rollupjs.org) for production bundling +- [Vitest](https://vitest.dev/) for unit testing - [Prettier](https://prettier.io/) for code formatting +- [ESLint](https://eslint.org/) for static error prevention (outside of types) + +## Git Hooks + +The project uses [simple-git-hooks](https://github.com/toplenboren/simple-git-hooks) to enforce the following on each commit: + +- Type check the entire project +- Automatically format changed files using Prettier +- Verify commit message format (logic in `scripts/verifyCommit.js`) ## Scripts -### `yarn build` +**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 `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". + +- [`nr build`](#nr-build) +- [`nr build-dts`](#nr-build-dts) +- [`nr check`](#nr-check) +- [`nr dev`](#nr-dev) +- [`nr dev-sfc`](#nr-dev-sfc) +- [`nr dev-esm`](#nr-dev-esm) +- [`nr dev-compiler`](#nr-dev-compiler) +- [`nr test`](#nr-test) +- [`nr test-dts`](#nr-test-dts) + +### `nr build` The `build` script builds all public packages (packages without `private: true` in their `package.json`). @@ -64,12 +108,14 @@ Packages to build can be specified with fuzzy matching: ```bash # build runtime-core only -yarn build runtime-core +nr build runtime-core # build all packages matching "runtime" -yarn build runtime --all +nr build runtime --all ``` +Note that `nr build` uses `rollup-plugin-esbuild` for transpiling typescript and **does not perform type checking**. To run type check on the entire codebase, run `nr check`. Type checks are also automatically run on each commit. + #### Build Formats By default, each package will be built in multiple distribution formats as specified in the `buildOptions.formats` field in its `package.json`. These can be overwritten via the `-f` flag. The following formats are supported: @@ -85,74 +131,89 @@ Additional formats that only apply to the main `vue` package: - **`esm-bundler-runtime`** - **`esm-browser-runtime`** -More details about each of these formats can be found in the [`vue` package README](https://github.com/vuejs/vue-next/blob/master/packages/vue/README.md#which-dist-file-to-use) and the [Rollup config file](https://github.com/vuejs/vue-next/blob/master/rollup.config.js). +More details about each of these formats can be found in the [`vue` package README](https://github.com/vuejs/core/blob/main/packages/vue/README.md#which-dist-file-to-use) and the [Rollup config file](https://github.com/vuejs/core/blob/main/rollup.config.js). For example, to build `runtime-core` with the global build only: ```bash -yarn build runtime-core -f global +nr build runtime-core -f global ``` Multiple formats can be specified as a comma-separated list: ```bash -yarn build runtime-core -f esm-browser,cjs +nr build runtime-core -f esm-browser,cjs ``` #### Build with Source Maps Use the `--sourcemap` or `-s` flag to build with source maps. Note this will make the build much slower. -#### Build with Type Declarations +### `nr build-dts` -The `--types` or `-t` flag will generate type declarations during the build and in addition: +This command builds the type declarations for all packages. It first generates the raw `.d.ts` files in the `temp` directory, then uses [rollup-plugin-dts](https://github.com/Swatinem/rollup-plugin-dts) to roll the types into a single `.d.ts` file for each package. -- Roll the declarations into a single `.d.ts` file for each package; -- Generate an API report in `/temp/.api.md`. This report contains potential warnings emitted by [api-extractor](https://api-extractor.com/). -- Generate an API model json in `/temp/.api.json`. This file can be used to generate a Markdown version of the exported APIs. +### `nr check` -### `yarn dev` +### `nr dev` The `dev` script bundles a target package (default: `vue`) in a specified format (default: `global`) in dev mode and watches for changes. This is useful when you want to load up a build in an HTML page for quick debugging: ```bash -$ yarn dev +$ nr dev -> rollup v1.19.4 -> bundles packages/vue/src/index.ts → packages/vue/dist/vue.global.js... +> built: packages/vue/dist/vue.global.js ``` -- The `dev` script also supports fuzzy match for the target package, but will only match the first package matched. +- **Important:** output of the `dev` script is for development and debugging only. While it has the same runtime behavior, the generated code should never be published to npm. + +- The `dev` script does not support fuzzy match - you must specify the full package name, e.g. `nr dev runtime-core`. - The `dev` script supports specifying build format via the `-f` flag just like the `build` script. - The `dev` script also supports the `-s` flag for generating source maps, but it will make rebuilds slower. -### `yarn dev-compiler` +- The `dev` script supports the `-i` flag for inlining all deps. This is useful when debugging `esm-bundler` builds which externalizes deps by default. + +### `nr dev-sfc` -The `dev-compiler` script builds, watches and serves the [Template Explorer](https://github.com/vuejs/vue-next/tree/master/packages/template-explorer) at `http://localhost:5000`. This is extremely useful when working on the compiler. +Shortcut for starting the SFC Playground in local dev mode. This provides the fastest feedback loop when debugging issues that can be reproduced in the SFC Playground. -### `yarn test` +### `nr dev-esm` -The `test` script simply calls the `jest` binary, so all [Jest CLI Options](https://jestjs.io/docs/en/cli) can be used. Some examples: +Builds and watches `vue/dist/vue-runtime.esm-bundler.js` with all deps inlined using esbuild. This is useful when debugging the ESM build in a reproductions that require real build setups: link `packages/vue` globally, then link it into the project being debugged. + +### `nr dev-compiler` + +The `dev-compiler` script builds, watches and serves the [Template Explorer](https://github.com/vuejs/core/tree/main/packages/template-explorer) at `http://localhost:3000`. This is useful when working on pure compiler issues. + +### `nr test` + +The `test` script simply calls the `vitest` binary, so all [Vitest CLI Options](https://vitest.dev/guide/cli.html#options) can be used. Some examples: ```bash -# run all tests -$ yarn test +# run all tests in watch mode +$ nr test -# run tests in watch mode -$ yarn test --watch +# run once and exit (equivalent to `vitest run`) +$ nr test run # run all tests under the runtime-core package -$ yarn test runtime-core +$ nr test runtime-core -# run tests in a specific file -$ yarn test fileName +# run tests in files matching the pattern +$ nr test -# run a specific test in a specific file -$ yarn test fileName -t 'test name' +# run a specific test in specific files +$ nr test -t 'test name' ``` +Tests that test against source code are grouped under `nr test-unit`, while tests that test against built files that run in real browsers are grouped under `nr test-e2e`. + +### `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. + ## Project Structure This repository employs a [monorepo](https://en.wikipedia.org/wiki/Monorepo) setup which hosts a number of associated packages under the `packages` directory: @@ -171,16 +232,22 @@ This repository employs a [monorepo](https://en.wikipedia.org/wiki/Monorepo) set - `compiler-dom`: Compiler with additional plugins specifically targeting the browser. -- `compiler-ssr`: Compiler that produces render functions optimized for server-side rendering. - -- `template-explorer`: A development tool for debugging compiler output. You can run `yarn dev template-explorer` and open its `index.html` to get a repl of template compilation based on current source code. +- `compiler-sfc`: Lower level utilities for compiling Vue Single File Components. - A [live version](https://vue-next-template-explorer.netlify.com) of the template explorer is also available, which can be used for providing reproductions for compiler bugs. You can also pick the deployment for a specific commit from the [deploy logs](https://app.netlify.com/sites/vue-next-template-explorer/deploys). +- `compiler-ssr`: Compiler that produces render functions optimized for server-side rendering. - `shared`: Internal utilities shared across multiple packages (especially environment-agnostic utils used by both runtime and compiler packages). - `vue`: The public facing "full build" which includes both the runtime AND the compiler. +- Private utility packages: + + - `dts-test`: Contains type-only tests against generated dts files. + + - `sfc-playground`: The playground continuously deployed at https://play.vuejs.org. To run the playground locally, use [`nr dev-sfc`](#nr-dev-sfc). + + - `template-explorer`: A development tool for debugging compiler output, continuously deployed at https://template-explorer.vuejs.org/. To run it locally, run [`nr dev-compiler`](#nr-dev-compiler). + ### Importing Packages The packages can import each other directly using their package names. Note that when importing a package, the name listed in its `package.json` should be used. Most of the time the `@vue/` prefix is needed: @@ -191,33 +258,35 @@ import { h } from '@vue/runtime-core' This is made possible via several configurations: -- For TypeScript, `compilerOptions.path` in `tsconfig.json` -- For Jest, `moduleNameMapper` in `jest.config.js` -- For plain Node.js, they are linked using [Yarn Workspaces](https://yarnpkg.com/blog/2017/08/02/introducing-workspaces/). +- For TypeScript, `compilerOptions.paths` in `tsconfig.json` +- Vitest and Rollup share the same set of aliases from `scripts/aliases.js` +- For plain Node.js, they are linked using [PNPM Workspaces](https://pnpm.io/workspaces). ### Package Dependencies -``` - +---------------------+ - | | - | @vue/compiler-sfc | - | | - +-----+--------+------+ - | | - v v - +---------------------+ +----------------------+ - | | | | - +------------>| @vue/compiler-dom +--->| @vue/compiler-core | - | | | | | - +----+----+ +---------------------+ +----------------------+ - | | - | vue | - | | - +----+----+ +---------------------+ +----------------------+ +-------------------+ - | | | | | | | - +------------>| @vue/runtime-dom +--->| @vue/runtime-core +--->| @vue/reactivity | - | | | | | | - +---------------------+ +----------------------+ +-------------------+ +```mermaid + flowchart LR + compiler-sfc["@vue/compiler-sfc"] + compiler-dom["@vue/compiler-dom"] + compiler-core["@vue/compiler-core"] + vue["vue"] + runtime-dom["@vue/runtime-dom"] + runtime-core["@vue/runtime-core"] + reactivity["@vue/reactivity"] + + subgraph "Runtime Packages" + runtime-dom --> runtime-core + runtime-core --> reactivity + end + + subgraph "Compiler Packages" + compiler-sfc --> compiler-core + compiler-sfc --> compiler-dom + compiler-dom --> compiler-core + end + + vue ---> compiler-dom + vue --> runtime-dom ``` There are some rules to follow when importing across package boundaries: @@ -230,7 +299,7 @@ There are some rules to follow when importing across package boundaries: ## Contributing Tests -Unit tests are collocated with the code being tested in each package, inside directories named `__tests__`. Consult the [Jest docs](https://jestjs.io/docs/en/using-matchers) and existing test cases for how to write new test specs. Here are some additional guidelines: +Unit tests are collocated with the code being tested in each package, inside directories named `__tests__`. Consult the [Vitest docs](https://vitest.dev/api/) and existing test cases for how to write new test specs. Here are some additional guidelines: - Use the minimal API needed for a test case. For example, if a test can be written without involving the reactivity system or a component, it should be written so. This limits the test's exposure to changes in unrelated parts and makes it more stable. @@ -238,13 +307,11 @@ Unit tests are collocated with the code being tested in each package, inside dir - Only use platform-specific runtimes if the test is asserting platform-specific behavior. -Test coverage is continuously deployed at https://vue-next-coverage.netlify.app/. PRs that improve test coverage are welcome, but in general the test coverage should be used as a guidance for finding API use cases that are not covered by tests. We don't recommend adding tests that only improve coverage but not actually test a meaning use case. +Test coverage is continuously deployed at https://coverage.vuejs.org. PRs that improve test coverage are welcome, but in general the test coverage should be used as a guidance for finding API use cases that are not covered by tests. We don't recommend adding tests that only improve coverage but not actually test a meaning use case. ### Testing Type Definition Correctness -This project uses [tsd](https://github.com/SamVerschueren/tsd) to test the built definition files (`*.d.ts`). - -Type tests are located in the `test-dts` directory. To run the dts tests, run `yarn 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 simply running `yarn test-dts`. +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`. ## Financial Contribution @@ -261,4 +328,4 @@ Funds donated via Patreon go directly to support Evan You's full-time work on Vu Thank you to all the people who have already contributed to Vue.js! - + diff --git a/.github/renovate.json5 b/.github/renovate.json5 new file mode 100644 index 00000000000..088913317c7 --- /dev/null +++ b/.github/renovate.json5 @@ -0,0 +1,50 @@ +{ + $schema: 'https://docs.renovatebot.com/renovate-schema.json', + extends: ['config:base', 'schedule:weekly', 'group:allNonMajor'], + labels: ['dependencies'], + ignorePaths: ['**/__tests__/**'], + rangeStrategy: 'bump', + packageRules: [ + { + depTypeList: ['peerDependencies'], + enabled: false + }, + { + groupName: 'test', + matchPackageNames: ['vitest', 'jsdom', 'puppeteer'], + matchPackagePrefixes: ['@vitest'] + }, + { + groupName: 'playground', + matchFileNames: [ + 'packages/sfc-playground/package.json', + 'packages/template-explorer/package.json' + ] + }, + { + groupName: 'compiler', + matchPackageNames: ['magic-string'], + matchPackagePrefixes: ['@babel', 'postcss'] + }, + { + groupName: 'build', + matchPackageNames: ['vite', 'terser'], + matchPackagePrefixes: ['rollup', 'esbuild', '@rollup', '@vitejs'] + }, + { + groupName: 'lint', + matchPackageNames: ['simple-git-hooks', 'lint-staged'], + matchPackagePrefixes: ['@typescript-eslint', 'eslint', 'prettier'] + } + ], + ignoreDeps: [ + 'vue', + + // manually bumping + 'node', + 'typescript', + + // ESM only + 'estree-walker' + ] +} diff --git a/.github/workflows/autofix.yml b/.github/workflows/autofix.yml new file mode 100644 index 00000000000..1c81ece394d --- /dev/null +++ b/.github/workflows/autofix.yml @@ -0,0 +1,33 @@ +name: autofix.ci + +on: + pull_request: +permissions: + contents: read + +jobs: + autofix: + runs-on: ubuntu-latest + env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + + - name: Set node version to 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + cache: pnpm + + - run: pnpm install + + - name: Run eslint + run: pnpm run lint --fix + + - name: Run prettier + run: pnpm run format + + - uses: autofix-ci/action@d3e591514b99d0fca6779455ff8338516663f7cc diff --git a/.github/workflows/canary-minor.yml b/.github/workflows/canary-minor.yml new file mode 100644 index 00000000000..2aa6db12b36 --- /dev/null +++ b/.github/workflows/canary-minor.yml @@ -0,0 +1,33 @@ +name: canary minor release +on: + # Runs every Monday at 1 AM UTC (9:00 AM in Singapore) + schedule: + - cron: 0 1 * * MON + workflow_dispatch: + +jobs: + canary: + # prevents this action from running on forks + if: github.repository == 'vuejs/core' + runs-on: ubuntu-latest + environment: Release + steps: + - uses: actions/checkout@v4 + with: + ref: minor + + - name: Install pnpm + uses: pnpm/action-setup@v2 + + - name: Set node version to 18 + uses: actions/setup-node@v3 + with: + node-version: 18 + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - run: pnpm release --canary --tag minor + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/canary.yml b/.github/workflows/canary.yml new file mode 100644 index 00000000000..61265c2d0e6 --- /dev/null +++ b/.github/workflows/canary.yml @@ -0,0 +1,31 @@ +name: canary release +on: + # Runs every Monday at 1 AM UTC (9:00 AM in Singapore) + schedule: + - cron: 0 1 * * MON + workflow_dispatch: + +jobs: + canary: + # prevents this action from running on forks + if: github.repository == 'vuejs/core' + runs-on: ubuntu-latest + environment: Release + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version-file: '.node-version' + registry-url: 'https://registry.npmjs.org' + cache: 'pnpm' + + - run: pnpm install + + - run: pnpm release --canary + env: + NODE_AUTH_TOKEN: ${{ secrets.NPM_TOKEN }} diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml new file mode 100644 index 00000000000..db874b1240e --- /dev/null +++ b/.github/workflows/ci.yml @@ -0,0 +1,114 @@ +name: 'ci' +on: + push: + branches: + - '**' + pull_request: + branches: + - main + +permissions: + contents: read # to fetch code (actions/checkout) + +jobs: + unit-test: + 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@v3 + 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 + 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@v3 + 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@v3 + with: + node-version-file: '.node-version' + cache: 'pnpm' + + - run: pnpm install + - run: node node_modules/puppeteer/install.js + + - 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@v3 + 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/.github/workflows/ecosystem-ci-trigger.yml b/.github/workflows/ecosystem-ci-trigger.yml new file mode 100644 index 00000000000..bd3a2749431 --- /dev/null +++ b/.github/workflows/ecosystem-ci-trigger.yml @@ -0,0 +1,85 @@ +name: ecosystem-ci trigger + +on: + issue_comment: + types: [created] + +jobs: + trigger: + 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@v6 + with: + script: | + const user = context.payload.sender.login + console.log(`Validate user: ${user}`) + + let isVuejsMember = false + try { + const { status } = await github.rest.orgs.checkMembershipForUser({ + org: 'vuejs', + username: user + }); + + isVuejsMember = (status === 204) + } catch (e) {} + + if (isVuejsMember) { + console.log('Allowed') + await github.rest.reactions.createForIssueComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: context.payload.comment.id, + content: '+1', + }) + } else { + console.log('Not allowed') + await github.rest.reactions.createForIssueComment({ + owner: context.repo.owner, + repo: context.repo.repo, + comment_id: context.payload.comment.id, + content: '-1', + }) + throw new Error('not allowed') + } + - uses: actions/github-script@v6 + id: get-pr-data + with: + script: | + console.log(`Get PR info: ${context.repo.owner}/${context.repo.repo}#${context.issue.number}`) + const { data: pr } = await github.rest.pulls.get({ + owner: context.repo.owner, + repo: context.repo.repo, + pull_number: context.issue.number + }) + return { + num: context.issue.number, + branchName: pr.head.ref, + repo: pr.head.repo.full_name + } + - uses: actions/github-script@v6 + id: trigger + env: + COMMENT: ${{ github.event.comment.body }} + with: + github-token: ${{ secrets.ECOSYSTEM_CI_ACCESS_TOKEN }} + result-encoding: string + script: | + const comment = process.env.COMMENT.trim() + const prData = ${{ steps.get-pr-data.outputs.result }} + + const suite = comment.replace(/^\/ecosystem-ci run/, '').trim() + + await github.rest.actions.createWorkflowDispatch({ + owner: context.repo.owner, + repo: 'ecosystem-ci', + workflow_id: 'ecosystem-ci-from-pr.yml', + ref: 'main', + inputs: { + prNumber: '' + prData.num, + branchName: prData.branchName, + repo: prData.repo, + suite: suite === '' ? '-' : suite + } + }) diff --git a/.github/workflows/lock-closed-issues.yml b/.github/workflows/lock-closed-issues.yml new file mode 100644 index 00000000000..cf01a5f6cdf --- /dev/null +++ b/.github/workflows/lock-closed-issues.yml @@ -0,0 +1,20 @@ +name: Lock Closed Issues + +on: + schedule: + - cron: '0 0 * * *' + +permissions: + issues: write + +jobs: + action: + if: github.repository == 'vuejs/core' + runs-on: ubuntu-latest + steps: + - uses: dessant/lock-threads@v4 + with: + github-token: ${{ secrets.GITHUB_TOKEN }} + issue-inactive-days: '14' + issue-lock-reason: '' + process-only: 'issues' diff --git a/.github/workflows/release-tag.yml b/.github/workflows/release-tag.yml index 8781b44c872..16c6c9c5c10 100644 --- a/.github/workflows/release-tag.yml +++ b/.github/workflows/release-tag.yml @@ -5,8 +5,12 @@ on: name: Create Release +permissions: {} jobs: build: + permissions: + contents: write # to create release (yyx990803/release-tag) + name: Create Release runs-on: ubuntu-latest steps: @@ -20,4 +24,4 @@ jobs: with: tag_name: ${{ github.ref }} body: | - Please refer to [CHANGELOG.md](https://github.com/vuejs/vue-next/blob/master/CHANGELOG.md) for details. + Please refer to [CHANGELOG.md](https://github.com/vuejs/core/blob/main/CHANGELOG.md) for details. diff --git a/.github/workflows/size-check.yml b/.github/workflows/size-check.yml deleted file mode 100644 index bf63447ecd3..00000000000 --- a/.github/workflows/size-check.yml +++ /dev/null @@ -1,19 +0,0 @@ -name: 'size' -on: - pull_request: - branches: - - master -jobs: - size: - runs-on: ubuntu-latest - env: - CI_JOB_NUMBER: 1 - steps: - - uses: actions/checkout@v1 - - uses: bahmutov/npm-install@v1 - - - uses: posva/size-check-action@v1.0.2 - with: - github_token: ${{ secrets.GITHUB_TOKEN }} - build_script: size - files: packages/vue/dist/vue.global.prod.js packages/runtime-dom/dist/runtime-dom.global.prod.js packages/size-check/dist/size-check.global.prod.js diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml new file mode 100644 index 00000000000..83141e242f8 --- /dev/null +++ b/.github/workflows/size-data.yml @@ -0,0 +1,52 @@ +name: size data + +on: + push: + branches: + - main + pull_request: + branches: + - main + +permissions: + contents: read + +env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + +jobs: + upload: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + + - name: Install pnpm + uses: pnpm/action-setup@v2 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version-file: '.node-version' + cache: pnpm + + - name: Install dependencies + run: pnpm install + + - run: pnpm run size + + - name: Upload Size Data + uses: actions/upload-artifact@v3 + 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 new file mode 100644 index 00000000000..cdfce9a979f --- /dev/null +++ b/.github/workflows/size-report.yml @@ -0,0 +1,84 @@ +name: size report + +on: + workflow_run: + workflows: ['size data'] + types: + - completed + +permissions: + contents: read + pull-requests: write + issues: write + +env: + PUPPETEER_SKIP_DOWNLOAD: 'true' + +jobs: + size-report: + runs-on: ubuntu-latest + if: > + 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 + + - name: Install Node.js + uses: actions/setup-node@v3 + with: + node-version-file: '.node-version' + cache: pnpm + + - 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 + 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 + with: + branch: main + 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: Read Size Report + id: size-report + uses: juliangruber/read-file-action@v1 + with: + path: ./size-report.md + + - name: Create Comment + uses: actions-cool/maintain-one-comment@v3 + with: + token: ${{ secrets.GITHUB_TOKEN }} + number: ${{ steps.pr-number.outputs.content }} + body: | + ${{ steps.size-report.outputs.content }} + + body-include: '' diff --git a/.gitignore b/.gitignore index 0a663edeb54..810f8852690 100644 --- a/.gitignore +++ b/.gitignore @@ -6,3 +6,7 @@ temp explorations TODOs.md *.log +.idea +.eslintcache +dts-build/packages +*.tsbuildinfo diff --git a/.ls-lint.yml b/.ls-lint.yml deleted file mode 100644 index cf5508db8a4..00000000000 --- a/.ls-lint.yml +++ /dev/null @@ -1,7 +0,0 @@ -ls: - packages/*/{src,__tests__}: - .js: kebab-case - .ts: camelCase | PascalCase - .d.ts: camelCase - .spec.ts: camelCase | PascalCase - .mock.ts: camelCase diff --git a/.node-version b/.node-version new file mode 100644 index 00000000000..209e3ef4b62 --- /dev/null +++ b/.node-version @@ -0,0 +1 @@ +20 diff --git a/.prettierignore b/.prettierignore new file mode 100644 index 00000000000..1521c8b7652 --- /dev/null +++ b/.prettierignore @@ -0,0 +1 @@ +dist diff --git a/.prettierrc b/.prettierrc index f5a1bdcdd2d..ef93d94821a 100644 --- a/.prettierrc +++ b/.prettierrc @@ -1,3 +1,5 @@ semi: false singleQuote: true printWidth: 80 +trailingComma: 'none' +arrowParens: 'avoid' diff --git a/BACKERS.md b/BACKERS.md new file mode 100644 index 00000000000..d8eb697f957 --- /dev/null +++ b/BACKERS.md @@ -0,0 +1,9 @@ +

Sponsors & Backers

+ +Vue.js is an MIT-licensed open source project with its ongoing development made possible entirely by the support of the awesome sponsors and backers listed in this file. If you'd like to join them, please consider [ sponsoring Vue's development](https://vuejs.org/sponsor/). + +

+ + sponsors + +

diff --git a/CHANGELOG.md b/CHANGELOG.md index 1b19e869acd..12be7dc8a3a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,1592 +1,472 @@ -## [3.0.1](https://github.com/vuejs/vue-next/compare/v3.0.0...v3.0.1) (2020-10-15) +## [3.3.6](https://github.com/vuejs/core/compare/v3.3.5...v3.3.6) (2023-10-20) ### Bug Fixes -* **compiler-core:** allow spaces between if-else branches ([#2305](https://github.com/vuejs/vue-next/issues/2305)) ([89c5909](https://github.com/vuejs/vue-next/commit/89c5909a6f063dddcdf61650a6ed08f8be138521)), closes [#2299](https://github.com/vuejs/vue-next/issues/2299) -* **compiler-core:** consistently remove comment nodes for pre tags in production ([f411924](https://github.com/vuejs/vue-next/commit/f4119249f2d3f394469028ad9664f61830540ff9)), closes [#2217](https://github.com/vuejs/vue-next/issues/2217) -* **compiler-core:** fix v-if key injection with v-on object syntax ([#2368](https://github.com/vuejs/vue-next/issues/2368)) ([692197b](https://github.com/vuejs/vue-next/commit/692197be33de8f73a605e3a7f71389be42613ee3)), closes [#2366](https://github.com/vuejs/vue-next/issues/2366) -* **compiler-core:** make v-once work with v-if/else-if/else ([#2182](https://github.com/vuejs/vue-next/issues/2182)) ([9499871](https://github.com/vuejs/vue-next/commit/94998715822589f6f10443b6dba75f193467845d)), closes [#2035](https://github.com/vuejs/vue-next/issues/2035) -* **compiler-ssr:** fix SSR issue when dynamic and static class co-exist ([#2354](https://github.com/vuejs/vue-next/issues/2354)) ([8539c0b](https://github.com/vuejs/vue-next/commit/8539c0bf32e86fb16349a210f878681579fb7976)) -* **hmr:** full diff props for non-sfc component ([#2359](https://github.com/vuejs/vue-next/issues/2359)) ([e78915a](https://github.com/vuejs/vue-next/commit/e78915a74045ebcf34e8e99064fff48cd044632c)) -* **reactivity:** should add allowRecurse to the effect ([#2213](https://github.com/vuejs/vue-next/issues/2213)) ([ea1f87e](https://github.com/vuejs/vue-next/commit/ea1f87eabf2deab2e586af7ebd2d74bb58f72b87)), closes [#2200](https://github.com/vuejs/vue-next/issues/2200) -* **reactivity:** should not trigger watch on computed ref when value is unchanged ([390589e](https://github.com/vuejs/vue-next/commit/390589ec6d977675c5cef2807fbf3e930a25eef0)), closes [#2231](https://github.com/vuejs/vue-next/issues/2231) -* **reactivity:** use resetTracking instead of enableTracking ([#2174](https://github.com/vuejs/vue-next/issues/2174)) ([7cc09ca](https://github.com/vuejs/vue-next/commit/7cc09ca8a581783c2391824885206348e5e99934)) -* **runtime-core:** ensure this context for $nextTick callback ([5c3e8e9](https://github.com/vuejs/vue-next/commit/5c3e8e984029711c97ca671fa098cf66483dd571)), closes [#2282](https://github.com/vuejs/vue-next/issues/2282) -* **runtime-core:** error handling for created/beforeCreate hooks ([b392fe4](https://github.com/vuejs/vue-next/commit/b392fe419c7486de62fac8f25640fe0836bef02e)), closes [#2268](https://github.com/vuejs/vue-next/issues/2268) -* **runtime-core:** fix directive merging on component root ([4d1ebb5](https://github.com/vuejs/vue-next/commit/4d1ebb5deb4c1cb2a02e8482bf8f9cc87197b088)), closes [#2298](https://github.com/vuejs/vue-next/issues/2298) -* **runtime-core:** fix duplicated unmount traversal in optimized mode ([376883d](https://github.com/vuejs/vue-next/commit/376883d1cfea6ed92807cce1f1209f943a04b625)), closes [#2169](https://github.com/vuejs/vue-next/issues/2169) -* **runtime-core:** fix provide function data access in extends/mixins ([f06518a](https://github.com/vuejs/vue-next/commit/f06518a8c9201b4fa2a956595aa9d89a192fcd20)), closes [#2300](https://github.com/vuejs/vue-next/issues/2300) -* **runtime-core:** fix SSR memoery leak due to props normalization cache ([a66e53a](https://github.com/vuejs/vue-next/commit/a66e53a24f445b688eef6812ecb872dc53cf2702)), closes [#2225](https://github.com/vuejs/vue-next/issues/2225) -* **runtime-core:** make errorCaptured return value handling consistent with Vue 2 ([#2289](https://github.com/vuejs/vue-next/issues/2289)) ([4d20ac8](https://github.com/vuejs/vue-next/commit/4d20ac8173f84c87288255dcc03c62a6ee862a23)), closes [#2267](https://github.com/vuejs/vue-next/issues/2267) -* **runtime-core:** use consistent camelCase event casing for render functions ([#2278](https://github.com/vuejs/vue-next/issues/2278)) ([62f2617](https://github.com/vuejs/vue-next/commit/62f26173ba715fd8bf2b131e19d94275106e830d)), closes [#2249](https://github.com/vuejs/vue-next/issues/2249) -* **runtime-core:** vnode.el is null in watcher after rerendering ([#2295](https://github.com/vuejs/vue-next/issues/2295)) ([28d5fd7](https://github.com/vuejs/vue-next/commit/28d5fd7a2871c10df3427dfbbe0e203c2a976cb4)), closes [#2170](https://github.com/vuejs/vue-next/issues/2170) -* **runtime-core/template-refs:** do not reset refs object before updates ([25d53f0](https://github.com/vuejs/vue-next/commit/25d53f09bbf55412a003eabb7a390dc8434f8987)), closes [#2283](https://github.com/vuejs/vue-next/issues/2283) -* **runtime-dom:** v-model should support number modifier with select tag ([#2308](https://github.com/vuejs/vue-next/issues/2308)) ([d744b8a](https://github.com/vuejs/vue-next/commit/d744b8a2dc7653c3e5e43e5379dbf72cf4c9ff2c)), closes [#2252](https://github.com/vuejs/vue-next/issues/2252) -* **sfc/style-vars:** should attach css vars while `subtree` changed ([#2178](https://github.com/vuejs/vue-next/issues/2178)) ([408a8ca](https://github.com/vuejs/vue-next/commit/408a8cad48f5fe0854c83a979ff98f03738fbfba)), closes [#2177](https://github.com/vuejs/vue-next/issues/2177) -* **teleport:** proper children traversal when teleport is block root ([2ae3b26](https://github.com/vuejs/vue-next/commit/2ae3b26679faf2d5393998ba806b99748679195a)), closes [#2324](https://github.com/vuejs/vue-next/issues/2324) -* **teleport:** should only force remove teleport when not disabled ([b0931dc](https://github.com/vuejs/vue-next/commit/b0931dcabaa2858ba76102f49878771ec14fb2e8)), closes [#2323](https://github.com/vuejs/vue-next/issues/2323) -* **types:** avoid DefineComponent defaulting to any ([6aa2256](https://github.com/vuejs/vue-next/commit/6aa2256913bfd097500aba83b78482b87107c101)), closes [#2192](https://github.com/vuejs/vue-next/issues/2192) -* **types:** fix using tuple type as EmitsOptions ([#2160](https://github.com/vuejs/vue-next/issues/2160)) ([5dbd6b3](https://github.com/vuejs/vue-next/commit/5dbd6b36a0666fc6c993115ee5281ef253ba8a68)), closes [#2159](https://github.com/vuejs/vue-next/issues/2159) -* **v-for:** handle and warn when `v-for` receives non-integer range number ([#2247](https://github.com/vuejs/vue-next/issues/2247)) ([02f355e](https://github.com/vuejs/vue-next/commit/02f355eb69df32a03e942e01ac1de654d26916a1)), closes [#2245](https://github.com/vuejs/vue-next/issues/2245) -* **v-model:** avoid clearing IME compose state on updates ([#2304](https://github.com/vuejs/vue-next/issues/2304)) ([fbd198f](https://github.com/vuejs/vue-next/commit/fbd198fbfe2f87c3c15a63d9770d00bf3fc9c142)), closes [#2302](https://github.com/vuejs/vue-next/issues/2302) -* **v-model:** ensure initial value is set after other attributes ([54ed759](https://github.com/vuejs/vue-next/commit/54ed7592e416fc411196e9b767aebcc4f2ca20d8)), closes [#2325](https://github.com/vuejs/vue-next/issues/2325) - - -### Features - -* custom formatters ([6ba7ba4](https://github.com/vuejs/vue-next/commit/6ba7ba47d59288b8cd39c985a2163ebd220607bc)) +* **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)) ### Performance Improvements -* **runtime-dom/vModel:** remove looseHas if model is Set ([#2236](https://github.com/vuejs/vue-next/issues/2236)) ([6a554fe](https://github.com/vuejs/vue-next/commit/6a554feb13487132ed7631f80a1efe8c41991346)) -* do not enable hmr in non-browser envs ([cf2c9f6](https://github.com/vuejs/vue-next/commit/cf2c9f6faa95add4c23b20c4b8a6e477d05ff0ed)) - - - -# [3.0.0](https://github.com/vuejs/vue-next/compare/v3.0.0-rc.13...v3.0.0) (2020-09-18) - - - -# [3.0.0-rc.13](https://github.com/vuejs/vue-next/compare/v3.0.0-rc.12...v3.0.0-rc.13) (2020-09-18) - - -### Bug Fixes - -* **hmr:** make hmr working with class components ([#2144](https://github.com/vuejs/vue-next/issues/2144)) ([422f05e](https://github.com/vuejs/vue-next/commit/422f05e085036e23ea3632c2ce75d86181a087b8)) -* **reactivity:** avoid length mutating array methods causing infinite updates ([#2138](https://github.com/vuejs/vue-next/issues/2138)) ([f316a33](https://github.com/vuejs/vue-next/commit/f316a332b055d3f448dc735365551d89041f1098)), closes [#2137](https://github.com/vuejs/vue-next/issues/2137) -* **suspense:** should discard unmount effects of invalidated pending branch ([5bfcad1](https://github.com/vuejs/vue-next/commit/5bfcad155b444b2f7ffaac171c1f61bc23909287)) -* **types:** component instance inference without props ([#2145](https://github.com/vuejs/vue-next/issues/2145)) ([57bdaa2](https://github.com/vuejs/vue-next/commit/57bdaa2220afefbde21118659c1ce2377d6b86d6)) - - -### Code Refactoring +* replace Map/Set with WeakMap/WeakSet ([#8549](https://github.com/vuejs/core/issues/8549)) ([712f96d](https://github.com/vuejs/core/commit/712f96d6ac4d3d984732cba448cb84624daba850)) -* watch APIs default to trigger pre-flush ([49bb447](https://github.com/vuejs/vue-next/commit/49bb44756fda0a7019c69f2fa6b880d9e41125aa)), closes [/github.com/vuejs/vue-next/issues/1706#issuecomment-666258948](https://github.com//github.com/vuejs/vue-next/issues/1706/issues/issuecomment-666258948) -### Features - -* **runtime-core:** support using inject() inside props default functions ([58c31e3](https://github.com/vuejs/vue-next/commit/58c31e36992d2647e5247de4904246fb2d6112ed)) -* **watch:** support dot-delimited path in watch option ([1c9a0b3](https://github.com/vuejs/vue-next/commit/1c9a0b3e195d144ac90d22d2cc2cef6a3fd8276d)) - - -### BREAKING CHANGES - -* watch APIs now default to use `flush: 'pre'` instead of -`flush: 'post'`. This change affects `watch`, `watchEffect`, the `watch` component option, and `this.$watch`. See ([49bb447](https://github.com/vuejs/vue-next/commit/49bb44756fda0a7019c69f2fa6b880d9e41125aa)) for more details. - -# [3.0.0-rc.12](https://github.com/vuejs/vue-next/compare/v3.0.0-rc.11...v3.0.0-rc.12) (2020-09-16) +## [3.3.5](https://github.com/vuejs/core/compare/v3.3.4...v3.3.5) (2023-10-20) ### Bug Fixes -* **reactivity:** effect should only recursively self trigger with explicit options ([3810de7](https://github.com/vuejs/vue-next/commit/3810de7d6bd0044177f043285228c2e988093883)), closes [#2125](https://github.com/vuejs/vue-next/issues/2125) -* **runtime-core:** ensure root stable fragments inherit elements for moving ([bebd44f](https://github.com/vuejs/vue-next/commit/bebd44f793ccd13bfdf90c7e45eac320a340650c)), closes [#2134](https://github.com/vuejs/vue-next/issues/2134) -* **runtime-core:** should still do full traverse of stable fragment children in dev + hmr ([dd40ad8](https://github.com/vuejs/vue-next/commit/dd40ad8fca47af0e1f0a963be2f48c23f7457952)) -* **runtime-core/async-component:** fix error component when there are no error handlers ([c7b4a37](https://github.com/vuejs/vue-next/commit/c7b4a379cf8627c79a01d61039d3e3b283477dc1)), closes [#2129](https://github.com/vuejs/vue-next/issues/2129) -* **types/tsx:** optional props from Mixin/Extends are treated as required ([#2048](https://github.com/vuejs/vue-next/issues/2048)) ([89e9ab8](https://github.com/vuejs/vue-next/commit/89e9ab8a2a387f26a370848db0b1ffb1d0ab9549)) - - -### Features - -* **compiler-sfc:** `additionalData` support for css preprocessors ([#2126](https://github.com/vuejs/vue-next/issues/2126)) ([066d514](https://github.com/vuejs/vue-next/commit/066d514d757fb7e8844104210d7d04cc11598fef)) - - - -# [3.0.0-rc.11](https://github.com/vuejs/vue-next/compare/v3.0.0-rc.10...v3.0.0-rc.11) (2020-09-15) - - -### Bug Fixes - -* **compiler-core:** fix prefixing for `