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)


Expand Down
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": "pnpm@8.9.2",
"type": "module",
"scripts": {
Expand Down
120 changes: 117 additions & 3 deletions packages/compiler-core/__tests__/transforms/vBind.spec.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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,
Expand All @@ -111,7 +165,7 @@ describe('compiler: transform v-bind', () => {
},
end: {
line: 1,
column: 16
column: 19
}
}
})
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -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
Expand All @@ -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",
Expand Down Expand Up @@ -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"
},
Expand Down
1 change: 1 addition & 0 deletions packages/compiler-core/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@ export {
export { generate, type CodegenContext, type CodegenResult } from './codegen'
export {
ErrorCodes,
errorMessages,
createCompilerError,
type CoreCompilerError,
type CompilerError
Expand Down
16 changes: 15 additions & 1 deletion packages/compiler-core/src/transforms/vBind.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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) {
Expand Down Expand Up @@ -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())
Expand Down
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",
Expand Down Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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
Expand Up @@ -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()
Expand Down
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",
Expand Down Expand Up @@ -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",
Expand Down
3 changes: 3 additions & 0 deletions packages/compiler-sfc/src/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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 {
Expand All @@ -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 {
Expand Down
10 changes: 7 additions & 3 deletions packages/compiler-sfc/src/script/defineEmits.ts
Original file line number Diff line number Diff line change
Expand Up @@ -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'

Expand Down Expand Up @@ -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!

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

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