diff --git a/.github/commit-convention.md b/.github/commit-convention.md index a8522fa21..d17a8bd4f 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}/ ``` diff --git a/.github/workflows/size-data.yml b/.github/workflows/size-data.yml index be57d2235..6ed570145 100644 --- a/.github/workflows/size-data.yml +++ b/.github/workflows/size-data.yml @@ -41,13 +41,3 @@ jobs: 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@v4 - 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 590237206..f84a93984 100644 --- a/.github/workflows/size-report.yml +++ b/.github/workflows/size-report.yml @@ -35,18 +35,6 @@ jobs: - name: Install dependencies run: pnpm install - - name: Download PR number - uses: dawidd6/action-download-artifact@v3 - 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@v3 with: @@ -77,7 +65,6 @@ jobs: uses: actions-cool/maintain-one-comment@v3 with: token: ${{ secrets.GITHUB_TOKEN }} - number: ${{ steps.pr-number.outputs.content }} body: | ${{ steps.size-report.outputs.content }} diff --git a/CHANGELOG.md b/CHANGELOG.md index 468407218..086da812a 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,3 +1,16 @@ +## [3.4.27](https://github.com/vuejs/core/compare/v3.4.26...v3.4.27) (2024-05-06) + + +### Bug Fixes + +* **compat:** include legacy scoped slots ([#10868](https://github.com/vuejs/core/issues/10868)) ([8366126](https://github.com/vuejs/core/commit/83661264a4ced3cb2ff6800904a86dd9e82bbfe2)), closes [#8869](https://github.com/vuejs/core/issues/8869) +* **compiler-core:** add support for arrow aysnc function with unbracketed ([#5789](https://github.com/vuejs/core/issues/5789)) ([ca7d421](https://github.com/vuejs/core/commit/ca7d421e8775f6813f8943d32ab485e0c542f98b)), closes [#5788](https://github.com/vuejs/core/issues/5788) +* **compiler-dom:** restrict createStaticVNode usage with option elements ([#10846](https://github.com/vuejs/core/issues/10846)) ([0e3d617](https://github.com/vuejs/core/commit/0e3d6178b02d0386d779720ae2cc4eac1d1ec990)), closes [#6568](https://github.com/vuejs/core/issues/6568) [#7434](https://github.com/vuejs/core/issues/7434) +* **compiler-sfc:** handle keyof operator ([#10874](https://github.com/vuejs/core/issues/10874)) ([10d34a5](https://github.com/vuejs/core/commit/10d34a5624775f20437ccad074a97270ef74c3fb)), closes [#10871](https://github.com/vuejs/core/issues/10871) +* **hydration:** handle edge case of style mismatch without style attribute ([f2c1412](https://github.com/vuejs/core/commit/f2c1412e46a8fad3e13403bfa78335c4f704f21c)), closes [#10786](https://github.com/vuejs/core/issues/10786) + + + # [3.5.0-alpha.2](https://github.com/vuejs/core/compare/v3.4.26...v3.5.0-alpha.2) (2024-05-04) diff --git a/eslint.config.js b/eslint.config.js index 3587a8150..334787fd9 100644 --- a/eslint.config.js +++ b/eslint.config.js @@ -45,6 +45,12 @@ export default tseslint.config( message: 'Our output target is ES2016, so async/await syntax should be avoided.', }, + { + selector: 'ChainExpression', + message: + 'Our output target is ES2016, and optional chaining results in ' + + 'verbose helpers and should be avoided.', + }, ], 'sort-imports': ['error', { ignoreDeclarationSort: true }], @@ -134,7 +140,7 @@ export default tseslint.config( { files: [ 'eslint.config.js', - 'rollup.config.js', + 'rollup*.config.js', 'scripts/**', './*.{js,ts}', 'packages/*/*.js', diff --git a/package.json b/package.json index 23282e991..d454391c7 100644 --- a/package.json +++ b/package.json @@ -1,7 +1,7 @@ { "private": true, "version": "3.5.0-alpha.2", - "packageManager": "pnpm@9.0.6", + "packageManager": "pnpm@9.1.2", "type": "module", "scripts": { "dev": "node scripts/dev.js", @@ -59,58 +59,58 @@ "node": ">=18.12.0" }, "devDependencies": { - "@babel/parser": "^7.24.4", - "@babel/types": "^7.24.0", + "@babel/parser": "^7.24.6", + "@babel/types": "^7.24.6", "@codspeed/vitest-plugin": "^3.1.0", "@rollup/plugin-alias": "^5.1.0", - "@rollup/plugin-commonjs": "^25.0.7", + "@rollup/plugin-commonjs": "^25.0.8", "@rollup/plugin-json": "^6.1.0", "@rollup/plugin-node-resolve": "^15.2.3", "@rollup/plugin-replace": "5.0.4", "@rollup/plugin-terser": "^0.4.4", "@types/hash-sum": "^1.0.2", "@types/minimist": "^1.2.5", - "@types/node": "^20.12.7", + "@types/node": "^20.12.12", "@types/semver": "^7.5.8", "@vitest/coverage-istanbul": "^1.5.2", "@vue/consolidate": "1.0.0", "conventional-changelog-cli": "^4.1.0", "enquirer": "^2.4.1", - "esbuild": "^0.20.2", + "esbuild": "^0.21.4", "esbuild-plugin-polyfill-node": "^0.3.0", - "eslint": "^9.1.1", - "eslint-plugin-import-x": "^0.5.0", + "eslint": "^9.3.0", + "eslint-plugin-import-x": "^0.5.1", "eslint-plugin-vitest": "^0.5.4", "estree-walker": "^2.0.2", "execa": "^8.0.1", "jsdom": "^24.0.0", - "lint-staged": "^15.2.2", + "lint-staged": "^15.2.5", "lodash": "^4.17.21", "magic-string": "^0.30.10", "markdown-table": "^3.0.3", "marked": "^12.0.2", "minimist": "^1.2.8", - "npm-run-all2": "^6.1.2", - "picocolors": "^1.0.0", + "npm-run-all2": "^6.2.0", + "picocolors": "^1.0.1", "prettier": "^3.2.5", "pretty-bytes": "^6.1.1", - "pug": "^3.0.2", + "pug": "^3.0.3", "puppeteer": "~22.7.1", - "rimraf": "^5.0.5", - "rollup": "^4.17.1", - "rollup-plugin-dts": "^6.1.0", + "rimraf": "^5.0.7", + "rollup": "^4.18.0", + "rollup-plugin-dts": "^6.1.1", "rollup-plugin-esbuild": "^6.1.1", "rollup-plugin-polyfill-node": "^0.13.0", - "semver": "^7.6.0", + "semver": "^7.6.2", "serve": "^14.2.3", "simple-git-hooks": "^2.11.1", - "terser": "^5.30.4", + "terser": "^5.31.0", "todomvc-app-css": "^2.4.3", "tslib": "^2.6.2", - "tsx": "^4.7.3", + "tsx": "^4.11.0", "typescript": "~5.4.5", - "typescript-eslint": "^7.7.1", - "vite": "^5.2.10", + "typescript-eslint": "^7.10.0", + "vite": "^5.2.11", "vitest": "^1.5.2" }, "pnpm": { diff --git a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts index 6c2dab962..10b9747d1 100644 --- a/packages/compiler-core/__tests__/transforms/transformElement.spec.ts +++ b/packages/compiler-core/__tests__/transforms/transformElement.spec.ts @@ -1284,6 +1284,18 @@ describe('compiler: element transform', () => { }) }) + test(' should be forced into blocks', () => { + const ast = parse(`
`) + transform(ast, { + nodeTransforms: [transformElement], + }) + expect((ast as any).children[0].children[0].codegenNode).toMatchObject({ + type: NodeTypes.VNODE_CALL, + tag: `"math"`, + isBlock: true, + }) + }) + test('force block for runtime custom directive w/ children', () => { const { node } = parseWithElementTransform(`
hello
`) expect(node.isBlock).toBe(true) diff --git a/packages/compiler-core/__tests__/transforms/vOn.spec.ts b/packages/compiler-core/__tests__/transforms/vOn.spec.ts index 568fa0b5a..b1c37e3f7 100644 --- a/packages/compiler-core/__tests__/transforms/vOn.spec.ts +++ b/packages/compiler-core/__tests__/transforms/vOn.spec.ts @@ -286,6 +286,23 @@ describe('compiler: transform v-on', () => { }) }) + test('should NOT wrap as function if expression is already function expression (async)', () => { + const { node } = parseWithVOn( + `
`, + ) + expect((node.codegenNode as VNodeCall).props).toMatchObject({ + properties: [ + { + key: { content: `onClick` }, + value: { + type: NodeTypes.SIMPLE_EXPRESSION, + content: `async $event => await foo($event)`, + }, + }, + ], + }) + }) + test('should NOT wrap as function if expression is already function expression (with newlines)', () => { const { node } = parseWithVOn( `
await foo(e)" />`, + { + prefixIdentifiers: true, + cacheHandlers: true, + }, + ) + + expect(root.cached).toBe(1) + const vnodeCall = node.codegenNode as VNodeCall + // should not treat cached handler as dynamicProp, so no flags + expect(vnodeCall.patchFlag).toBeUndefined() + expect( + (vnodeCall.props as ObjectExpression).properties[0].value, + ).toMatchObject({ + type: NodeTypes.JS_CACHE_EXPRESSION, + index: 0, + value: { + type: NodeTypes.COMPOUND_EXPRESSION, + children: [ + `async `, + { content: `e` }, + ` => await `, + { content: `_ctx.foo` }, + `(`, + { content: `e` }, + `)`, + ], + }, + }) + }) + test('inline async function expression handler', () => { const { root, node } = parseWithVOn( `
`, diff --git a/packages/compiler-core/package.json b/packages/compiler-core/package.json index d139d92c3..79f1b17eb 100644 --- a/packages/compiler-core/package.json +++ b/packages/compiler-core/package.json @@ -46,13 +46,13 @@ }, "homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme", "dependencies": { - "@babel/parser": "^7.24.4", + "@babel/parser": "^7.24.6", "@vue/shared": "workspace:*", "entities": "^4.5.0", "estree-walker": "^2.0.2", "source-map-js": "^1.2.0" }, "devDependencies": { - "@babel/types": "^7.24.0" + "@babel/types": "^7.24.6" } } diff --git a/packages/compiler-core/src/ast.ts b/packages/compiler-core/src/ast.ts index 3f92a99fc..91354b1b4 100644 --- a/packages/compiler-core/src/ast.ts +++ b/packages/compiler-core/src/ast.ts @@ -571,7 +571,7 @@ export interface ForRenderListExpression extends CallExpression { } export interface ForIteratorExpression extends FunctionExpression { - returns: BlockCodegenNode + returns?: BlockCodegenNode } // AST Utilities --------------------------------------------------------------- diff --git a/packages/compiler-core/src/babelUtils.ts b/packages/compiler-core/src/babelUtils.ts index d3812f84c..7482494e1 100644 --- a/packages/compiler-core/src/babelUtils.ts +++ b/packages/compiler-core/src/babelUtils.ts @@ -53,6 +53,7 @@ export function walkIdentifiers( } } else if ( node.type === 'ObjectProperty' && + // eslint-disable-next-line no-restricted-syntax parent?.type === 'ObjectPattern' ) { // mark property in destructure pattern @@ -407,6 +408,7 @@ function isReferenced(node: Node, parent: Node, grandparent?: Node): boolean { // no: export { NODE as foo } from "foo"; case 'ExportSpecifier': // @ts-expect-error + // eslint-disable-next-line no-restricted-syntax if (grandparent?.source) { return false } diff --git a/packages/compiler-core/src/compat/transformFilter.ts b/packages/compiler-core/src/compat/transformFilter.ts index 86d11f52a..52b381567 100644 --- a/packages/compiler-core/src/compat/transformFilter.ts +++ b/packages/compiler-core/src/compat/transformFilter.ts @@ -168,6 +168,8 @@ function parseFilter(node: SimpleExpressionNode, context: TransformContext) { expression = wrapFilter(expression, filters[i], context) } node.content = expression + // reset ast since the content is replaced + node.ast = undefined } } diff --git a/packages/compiler-core/src/transforms/hoistStatic.ts b/packages/compiler-core/src/transforms/hoistStatic.ts index 70a0468e5..67bdaa887 100644 --- a/packages/compiler-core/src/transforms/hoistStatic.ts +++ b/packages/compiler-core/src/transforms/hoistStatic.ts @@ -174,7 +174,8 @@ export function getConstantType( if ( codegenNode.isBlock && node.tag !== 'svg' && - node.tag !== 'foreignObject' + node.tag !== 'foreignObject' && + node.tag !== 'math' ) { return ConstantTypes.NOT_CONSTANT } diff --git a/packages/compiler-core/src/transforms/transformElement.ts b/packages/compiler-core/src/transforms/transformElement.ts index 5c431f9d4..b1be06db7 100644 --- a/packages/compiler-core/src/transforms/transformElement.ts +++ b/packages/compiler-core/src/transforms/transformElement.ts @@ -117,7 +117,7 @@ export const transformElement: NodeTransform = (node, context) => { // updates inside get proper isSVG flag at runtime. (#639, #643) // This is technically web-specific, but splitting the logic out of core // leads to too much unnecessary complexity. - (tag === 'svg' || tag === 'foreignObject')) + (tag === 'svg' || tag === 'foreignObject' || tag === 'math')) // props if (props.length > 0) { diff --git a/packages/compiler-core/src/transforms/vOn.ts b/packages/compiler-core/src/transforms/vOn.ts index 8c13bdae5..a1631e10d 100644 --- a/packages/compiler-core/src/transforms/vOn.ts +++ b/packages/compiler-core/src/transforms/vOn.ts @@ -17,7 +17,7 @@ import { hasScopeRef, isMemberExpression } from '../utils' import { TO_HANDLER_KEY } from '../runtimeHelpers' const fnExpRE = - /^\s*([\w$_]+|(async\s*)?\([^)]*?\))\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ + /^\s*(async\s*)?(\([^)]*?\)|[\w$_]+)\s*(:[^=]+)?=>|^\s*(async\s+)?function(?:\s+[\w$]+)?\s*\(/ export interface VOnDirectiveNode extends DirectiveNode { // v-on without arg is handled directly in ./transformElements.ts due to it affecting diff --git a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap index 33fb37a58..57d880a03 100644 --- a/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap +++ b/packages/compiler-dom/__tests__/transforms/__snapshots__/stringifyStatic.spec.ts.snap @@ -1,5 +1,24 @@ // Vitest Snapshot v1, https://vitest.dev/guide/snapshot.html +exports[`stringify static html > should bail for