Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Vue 3.4 Release #9139

Closed
wants to merge 9 commits into from
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# [3.4.0-alpha.1](https://github.com/vuejs/core/compare/v3.3.7...v3.4.0-alpha.1) (2023-10-28)


### Features

* **compiler-core:** export error message ([#8729](https://github.com/vuejs/core/issues/8729)) ([f7e80ee](https://github.com/vuejs/core/commit/f7e80ee4a065a9eaba98720abf415d9e87756cbd))
* **compiler-sfc:** expose resolve type-based props and emits ([#8874](https://github.com/vuejs/core/issues/8874)) ([9e77580](https://github.com/vuejs/core/commit/9e77580c0c2f0d977bd0031a1d43cc334769d433))
* export runtime error strings ([#9301](https://github.com/vuejs/core/issues/9301)) ([feb2f2e](https://github.com/vuejs/core/commit/feb2f2edce2d91218a5e9a52c81e322e4033296b))
* **reactivity:** more efficient reactivity system ([#5912](https://github.com/vuejs/core/issues/5912)) ([16e06ca](https://github.com/vuejs/core/commit/16e06ca08f5a1e2af3fc7fb35de153dbe0c3087d)), closes [#311](https://github.com/vuejs/core/issues/311) [#1811](https://github.com/vuejs/core/issues/1811) [#6018](https://github.com/vuejs/core/issues/6018) [#7160](https://github.com/vuejs/core/issues/7160) [#8714](https://github.com/vuejs/core/issues/8714) [#9149](https://github.com/vuejs/core/issues/9149) [#9419](https://github.com/vuejs/core/issues/9419) [#9464](https://github.com/vuejs/core/issues/9464)
* **runtime-core:** add `once` option to watch ([#9034](https://github.com/vuejs/core/issues/9034)) ([a645e7a](https://github.com/vuejs/core/commit/a645e7aa51006516ba668b3a4365d296eb92ee7d))



## [3.3.7](https://github.com/vuejs/core/compare/v3.3.6...v3.3.7) (2023-10-24)


2 changes: 1 addition & 1 deletion package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"private": true,
"version": "3.3.7",
"version": "3.4.0-alpha.1",
"packageManager": "[email protected]",
"type": "module",
"scripts": {
120 changes: 117 additions & 3 deletions packages/compiler-core/__tests__/transforms/vBind.spec.ts
Original file line number Diff line number Diff line change
@@ -72,6 +72,60 @@ describe('compiler: transform v-bind', () => {
})
})

test('no expression', () => {
const node = parseWithVBind(`<div v-bind:id />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `id`,
isStatic: true,
loc: {
start: {
line: 1,
column: 13,
offset: 12
},
end: {
line: 1,
column: 15,
offset: 14
}
}
},
value: {
content: `id`,
isStatic: false,
loc: {
start: {
line: 1,
column: 1,
offset: 0
},
end: {
line: 1,
column: 1,
offset: 0
}
}
}
})
})

test('no expression (shorthand)', () => {
const node = parseWithVBind(`<div :id />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `id`,
isStatic: true
},
value: {
content: `id`,
isStatic: false
}
})
})

test('dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[id]="id"/>`)
const props = (node.codegenNode as VNodeCall).props as CallExpression
@@ -98,9 +152,9 @@ describe('compiler: transform v-bind', () => {
})
})

test('should error if no expression', () => {
test('should error if empty expression', () => {
const onError = vi.fn()
const node = parseWithVBind(`<div v-bind:arg />`, { onError })
const node = parseWithVBind(`<div v-bind:arg="" />`, { onError })
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(onError.mock.calls[0][0]).toMatchObject({
code: ErrorCodes.X_V_BIND_NO_EXPRESSION,
@@ -111,7 +165,7 @@ describe('compiler: transform v-bind', () => {
},
end: {
line: 1,
column: 16
column: 19
}
}
})
@@ -142,6 +196,21 @@ describe('compiler: transform v-bind', () => {
})
})

test('.camel modifier w/ no expression', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.camel />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `fooBar`,
isStatic: true
},
value: {
content: `fooBar`,
isStatic: false
}
})
})

test('.camel modifier w/ dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[foo].camel="id"/>`)
const props = (node.codegenNode as VNodeCall).props as CallExpression
@@ -219,6 +288,21 @@ describe('compiler: transform v-bind', () => {
})
})

test('.prop modifier w/ no expression', () => {
const node = parseWithVBind(`<div v-bind:fooBar.prop />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `.fooBar`,
isStatic: true
},
value: {
content: `fooBar`,
isStatic: false
}
})
})

test('.prop modifier w/ dynamic arg', () => {
const node = parseWithVBind(`<div v-bind:[fooBar].prop="id"/>`)
const props = (node.codegenNode as VNodeCall).props as CallExpression
@@ -296,6 +380,21 @@ describe('compiler: transform v-bind', () => {
})
})

test('.prop modifier (shortband) w/ no expression', () => {
const node = parseWithVBind(`<div .fooBar />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `.fooBar`,
isStatic: true
},
value: {
content: `fooBar`,
isStatic: false
}
})
})

test('.attr modifier', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.attr="id"/>`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
@@ -310,4 +409,19 @@ describe('compiler: transform v-bind', () => {
}
})
})

test('.attr modifier w/ no expression', () => {
const node = parseWithVBind(`<div v-bind:foo-bar.attr />`)
const props = (node.codegenNode as VNodeCall).props as ObjectExpression
expect(props.properties[0]).toMatchObject({
key: {
content: `^foo-bar`,
isStatic: true
},
value: {
content: `fooBar`,
isStatic: false
}
})
})
})
4 changes: 2 additions & 2 deletions packages/compiler-core/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-core",
"version": "3.3.7",
"version": "3.4.0-alpha.1",
"description": "@vue/compiler-core",
"main": "index.js",
"module": "dist/compiler-core.esm-bundler.js",
@@ -33,7 +33,7 @@
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-core#readme",
"dependencies": {
"@babel/parser": "^7.23.0",
"@vue/shared": "3.3.7",
"@vue/shared": "3.4.0-alpha.1",
"estree-walker": "^2.0.2",
"source-map-js": "^1.0.2"
},
1 change: 1 addition & 0 deletions packages/compiler-core/src/index.ts
Original file line number Diff line number Diff line change
@@ -24,6 +24,7 @@ export {
export { generate, type CodegenContext, type CodegenResult } from './codegen'
export {
ErrorCodes,
errorMessages,
createCompilerError,
type CoreCompilerError,
type CompilerError
16 changes: 15 additions & 1 deletion packages/compiler-core/src/transforms/vBind.ts
Original file line number Diff line number Diff line change
@@ -3,17 +3,19 @@ import {
createObjectProperty,
createSimpleExpression,
ExpressionNode,
locStub,
NodeTypes
} from '../ast'
import { createCompilerError, ErrorCodes } from '../errors'
import { camelize } from '@vue/shared'
import { CAMELIZE } from '../runtimeHelpers'
import { processExpression } from './transformExpression'

// v-bind without arg is handled directly in ./transformElements.ts due to it affecting
// codegen for the entire props object. This transform here is only for v-bind
// *with* args.
export const transformBind: DirectiveTransform = (dir, _node, context) => {
const { exp, modifiers, loc } = dir
const { modifiers, loc } = dir
const arg = dir.arg!

if (arg.type !== NodeTypes.SIMPLE_EXPRESSION) {
@@ -46,6 +48,18 @@ export const transformBind: DirectiveTransform = (dir, _node, context) => {
}
}

// :arg is replaced by :arg="arg"
let { exp } = dir
if (!exp && arg.type === NodeTypes.SIMPLE_EXPRESSION) {
const propName = camelize(arg.loc.source)
const simpleExpression = createSimpleExpression(propName, false, {
...locStub,
source: propName
})

exp = dir.exp = processExpression(simpleExpression, context)
}

if (
!exp ||
(exp.type === NodeTypes.SIMPLE_EXPRESSION && !exp.content.trim())
6 changes: 3 additions & 3 deletions packages/compiler-dom/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-dom",
"version": "3.3.7",
"version": "3.4.0-alpha.1",
"description": "@vue/compiler-dom",
"main": "index.js",
"module": "dist/compiler-dom.esm-bundler.js",
@@ -37,7 +37,7 @@
},
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-dom#readme",
"dependencies": {
"@vue/shared": "3.3.7",
"@vue/compiler-core": "3.3.7"
"@vue/shared": "3.4.0-alpha.1",
"@vue/compiler-core": "3.4.0-alpha.1"
}
}
6 changes: 5 additions & 1 deletion packages/compiler-dom/src/index.ts
Original file line number Diff line number Diff line change
@@ -68,5 +68,9 @@ export function parse(template: string, options: ParserOptions = {}): RootNode {

export * from './runtimeHelpers'
export { transformStyle } from './transforms/transformStyle'
export { createDOMCompilerError, DOMErrorCodes } from './errors'
export {
createDOMCompilerError,
DOMErrorCodes,
DOMErrorMessages
} from './errors'
export * from '@vue/compiler-core'
Original file line number Diff line number Diff line change
@@ -79,7 +79,6 @@ exports[`source map 1`] = `
exports[`template errors 1`] = `
[
[SyntaxError: Error parsing JavaScript expression: Unexpected token (1:3)],
[SyntaxError: v-bind is missing expression.],
[SyntaxError: v-model can only be used on <input>, <textarea> and <select> elements.],
]
`;
2 changes: 1 addition & 1 deletion packages/compiler-sfc/__tests__/compileTemplate.spec.ts
Original file line number Diff line number Diff line change
@@ -124,7 +124,7 @@ test('source map', () => {
test('template errors', () => {
const result = compile({
filename: 'example.vue',
source: `<div :foo
source: `<div
:bar="a[" v-model="baz"/>`
})
expect(result.errors).toMatchSnapshot()
12 changes: 6 additions & 6 deletions packages/compiler-sfc/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "@vue/compiler-sfc",
"version": "3.3.7",
"version": "3.4.0-alpha.1",
"description": "@vue/compiler-sfc",
"main": "dist/compiler-sfc.cjs.js",
"module": "dist/compiler-sfc.esm-browser.js",
@@ -33,11 +33,11 @@
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme",
"dependencies": {
"@babel/parser": "^7.23.0",
"@vue/compiler-core": "3.3.7",
"@vue/compiler-dom": "3.3.7",
"@vue/compiler-ssr": "3.3.7",
"@vue/reactivity-transform": "3.3.7",
"@vue/shared": "3.3.7",
"@vue/compiler-core": "3.4.0-alpha.1",
"@vue/compiler-dom": "3.4.0-alpha.1",
"@vue/compiler-ssr": "3.4.0-alpha.1",
"@vue/reactivity-transform": "3.4.0-alpha.1",
"@vue/shared": "3.4.0-alpha.1",
"estree-walker": "^2.0.2",
"magic-string": "^0.30.5",
"postcss": "^8.4.31",
3 changes: 3 additions & 0 deletions packages/compiler-sfc/src/index.ts
Original file line number Diff line number Diff line change
@@ -33,6 +33,8 @@ export {

// Internals for type resolution
export { invalidateTypeCache, registerTS } from './script/resolveType'
export { extractRuntimeProps } from './script/defineProps'
export { extractRuntimeEmits } from './script/defineEmits'

// Types
export type {
@@ -58,6 +60,7 @@ export type { SFCScriptCompileOptions } from './compileScript'
export type { ScriptCompileContext } from './script/context'
export type {
TypeResolveContext,
SimpleTypeResolveOptions,
SimpleTypeResolveContext
} from './script/resolveType'
export type {
10 changes: 7 additions & 3 deletions packages/compiler-sfc/src/script/defineEmits.ts
Original file line number Diff line number Diff line change
@@ -8,7 +8,11 @@ import {
} from '@babel/types'
import { isCallOf } from './utils'
import { ScriptCompileContext } from './context'
import { resolveTypeElements, resolveUnionType } from './resolveType'
import {
TypeResolveContext,
resolveTypeElements,
resolveUnionType
} from './resolveType'

export const DEFINE_EMITS = 'defineEmits'

@@ -64,7 +68,7 @@ export function genRuntimeEmits(ctx: ScriptCompileContext): string | undefined {
return emitsDecl
}

function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
export function extractRuntimeEmits(ctx: TypeResolveContext): Set<string> {
const emits = new Set<string>()
const node = ctx.emitsTypeDecl!

@@ -97,7 +101,7 @@ function extractRuntimeEmits(ctx: ScriptCompileContext): Set<string> {
}

function extractEventNames(
ctx: ScriptCompileContext,
ctx: TypeResolveContext,
eventName: ArrayPattern | Identifier | ObjectPattern | RestElement,
emits: Set<string>
) {
Loading