Skip to content

Commit b294a0c

Browse files
chore: only use extend at runtime
2 parents 839f271 + 2424013 commit b294a0c

40 files changed

+482
-127
lines changed

package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -65,8 +65,8 @@
6565
"@rollup/plugin-node-resolve": "^15.2.3",
6666
"@rollup/plugin-replace": "^5.0.4",
6767
"@rollup/plugin-terser": "^0.4.4",
68-
"@types/hash-sum": "^1.0.1",
69-
"@types/node": "^20.8.10",
68+
"@types/hash-sum": "^1.0.2",
69+
"@types/node": "^20.9.0",
7070
"@typescript-eslint/parser": "^6.9.1",
7171
"@vitest/coverage-istanbul": "^0.34.6",
7272
"@vue/consolidate": "0.17.3",
@@ -83,7 +83,7 @@
8383
"lodash": "^4.17.21",
8484
"magic-string": "^0.30.5",
8585
"markdown-table": "^3.0.3",
86-
"marked": "^9.1.4",
86+
"marked": "^9.1.5",
8787
"minimist": "^1.2.8",
8888
"npm-run-all": "^4.1.5",
8989
"picocolors": "^1.0.0",

packages/compiler-core/__tests__/transforms/__snapshots__/vModel.spec.ts.snap

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -85,7 +85,7 @@ return function render(_ctx, _cache) {
8585
return (_openBlock(), _createElementBlock(\\"input\\", {
8686
\\"foo-value\\": model,
8787
\\"onUpdate:fooValue\\": $event => ((model) = $event)
88-
}, null, 40 /* PROPS, HYDRATE_EVENTS */, [\\"foo-value\\", \\"onUpdate:fooValue\\"]))
88+
}, null, 40 /* PROPS, NEED_HYDRATION */, [\\"foo-value\\", \\"onUpdate:fooValue\\"]))
8989
}
9090
}"
9191
`;

packages/compiler-core/__tests__/transforms/transformElement.spec.ts

Lines changed: 16 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1089,7 +1089,7 @@ describe('compiler: element transform', () => {
10891089
})
10901090
})
10911091

1092-
test('HYDRATE_EVENTS', () => {
1092+
test('NEED_HYDRATION for v-on', () => {
10931093
// ignore click events (has dedicated fast path)
10941094
const { node } = parseWithElementTransform(`<div @click="foo" />`, {
10951095
directiveTransforms: {
@@ -1108,12 +1108,24 @@ describe('compiler: element transform', () => {
11081108
}
11091109
)
11101110
expect(node2.patchFlag).toBe(
1111-
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
1111+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
1112+
)
1113+
})
1114+
1115+
test('NEED_HYDRATION for v-bind.prop', () => {
1116+
const { node } = parseWithBind(`<div v-bind:id.prop="id" />`)
1117+
expect(node.patchFlag).toBe(
1118+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
1119+
)
1120+
1121+
const { node: node2 } = parseWithBind(`<div .id="id" />`)
1122+
expect(node2.patchFlag).toBe(
1123+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
11121124
)
11131125
})
11141126

11151127
// #5870
1116-
test('HYDRATE_EVENTS on dynamic component', () => {
1128+
test('NEED_HYDRATION on dynamic component', () => {
11171129
const { node } = parseWithElementTransform(
11181130
`<component :is="foo" @input="foo" />`,
11191131
{
@@ -1123,7 +1135,7 @@ describe('compiler: element transform', () => {
11231135
}
11241136
)
11251137
expect(node.patchFlag).toBe(
1126-
genFlagText([PatchFlags.PROPS, PatchFlags.HYDRATE_EVENTS])
1138+
genFlagText([PatchFlags.PROPS, PatchFlags.NEED_HYDRATION])
11271139
)
11281140
})
11291141
})

packages/compiler-core/src/parse.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1063,7 +1063,7 @@ function parseTextData(
10631063
) {
10641064
return rawText
10651065
} else {
1066-
// DATA or RCDATA containing "&"". Entity decoding required.
1066+
// DATA or RCDATA containing "&". Entity decoding is required.
10671067
return context.options.decodeEntities(
10681068
rawText,
10691069
mode === TextModes.ATTRIBUTE_VALUE

packages/compiler-core/src/transform.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -238,8 +238,8 @@ export function createTransformContext(
238238
const removalIndex = node
239239
? list.indexOf(node)
240240
: context.currentNode
241-
? context.childIndex
242-
: -1
241+
? context.childIndex
242+
: -1
243243
/* istanbul ignore if */
244244
if (__DEV__ && removalIndex < 0) {
245245
throw new Error(`node being removed is not a child of current parent`)

packages/compiler-core/src/transforms/transformElement.ts

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -550,7 +550,7 @@ export function buildProps(
550550
)
551551
} else {
552552
// directives
553-
const { name, arg, exp, loc } = prop
553+
const { name, arg, exp, loc, modifiers } = prop
554554
const isVBind = name === 'bind'
555555
const isVOn = name === 'on'
556556

@@ -678,6 +678,11 @@ export function buildProps(
678678
continue
679679
}
680680

681+
// force hydration for v-bind with .prop modifier
682+
if (isVBind && modifiers.includes('prop')) {
683+
patchFlag |= PatchFlags.NEED_HYDRATION
684+
}
685+
681686
const directiveTransform = context.directiveTransforms[name]
682687
if (directiveTransform) {
683688
// has built-in directive transform.
@@ -743,12 +748,12 @@ export function buildProps(
743748
patchFlag |= PatchFlags.PROPS
744749
}
745750
if (hasHydrationEventBinding) {
746-
patchFlag |= PatchFlags.HYDRATE_EVENTS
751+
patchFlag |= PatchFlags.NEED_HYDRATION
747752
}
748753
}
749754
if (
750755
!shouldUseBlock &&
751-
(patchFlag === 0 || patchFlag === PatchFlags.HYDRATE_EVENTS) &&
756+
(patchFlag === 0 || patchFlag === PatchFlags.NEED_HYDRATION) &&
752757
(hasRef || hasVnodeHook || runtimeDirectives.length > 0)
753758
) {
754759
patchFlag |= PatchFlags.NEED_PATCH

packages/compiler-core/src/transforms/vFor.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,8 @@ import {
3737
isTemplateNode,
3838
isSlotOutlet,
3939
injectProp,
40-
findDir
40+
findDir,
41+
forAliasRE
4142
} from '../utils'
4243
import {
4344
RENDER_LIST,
@@ -308,7 +309,6 @@ export function processFor(
308309
}
309310
}
310311

311-
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
312312
// This regex doesn't cover the case if key or index aliases have destructuring,
313313
// but those do not make sense in the first place, so this works in practice.
314314
const forIteratorRE = /,([^,\}\]]*)(?:,([^,\}\]]*))?$/

packages/compiler-core/src/utils.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -519,3 +519,5 @@ export function getMemoedVNodeCall(node: BlockCodegenNode | MemoExpression) {
519519
return node
520520
}
521521
}
522+
523+
export const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/

packages/compiler-dom/__tests__/transforms/stringifyStatic.spec.ts

Lines changed: 1 addition & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,10 +20,7 @@ describe('stringify static html', () => {
2020
}
2121

2222
function repeat(code: string, n: number): string {
23-
return new Array(n)
24-
.fill(0)
25-
.map(() => code)
26-
.join('')
23+
return code.repeat(n)
2724
}
2825

2926
test('should bail on non-eligible static trees', () => {

packages/compiler-dom/__tests__/transforms/vOn.spec.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -272,7 +272,7 @@ describe('compiler-dom: transform v-on', () => {
272272
// should not treat cached handler as dynamicProp, so it should have no
273273
// dynamicProps flags and only the hydration flag
274274
expect((root as any).children[0].codegenNode.patchFlag).toBe(
275-
genFlagText(PatchFlags.HYDRATE_EVENTS)
275+
genFlagText(PatchFlags.NEED_HYDRATION)
276276
)
277277
expect(prop).toMatchObject({
278278
key: {

packages/compiler-sfc/src/compileScript.ts

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@ import {
66
} from '@vue/compiler-dom'
77
import { DEFAULT_FILENAME, SFCDescriptor, SFCScriptBlock } from './parse'
88
import { ParserPlugin } from '@babel/parser'
9-
import { extend, generateCodeFrame } from '@vue/shared'
9+
import { generateCodeFrame } from '@vue/shared'
1010
import {
1111
Node,
1212
Declaration,
@@ -735,7 +735,7 @@ export function compileScript(
735735
// 7. analyze binding metadata
736736
// `defineProps` & `defineModel` also register props bindings
737737
if (scriptAst) {
738-
extend(ctx.bindingMetadata, analyzeScriptBindings(scriptAst.body))
738+
Object.assign(ctx.bindingMetadata, analyzeScriptBindings(scriptAst.body))
739739
}
740740
for (const [key, { isType, imported, source }] of Object.entries(
741741
ctx.userImports
@@ -1172,8 +1172,8 @@ function walkObjectPattern(
11721172
const type = isDefineCall
11731173
? BindingTypes.SETUP_CONST
11741174
: isConst
1175-
? BindingTypes.SETUP_MAYBE_REF
1176-
: BindingTypes.SETUP_LET
1175+
? BindingTypes.SETUP_MAYBE_REF
1176+
: BindingTypes.SETUP_LET
11771177
registerBinding(bindings, p.key, type)
11781178
} else {
11791179
walkPattern(p.value, bindings, isConst, isDefineCall)
@@ -1208,8 +1208,8 @@ function walkPattern(
12081208
const type = isDefineCall
12091209
? BindingTypes.SETUP_CONST
12101210
: isConst
1211-
? BindingTypes.SETUP_MAYBE_REF
1212-
: BindingTypes.SETUP_LET
1211+
? BindingTypes.SETUP_MAYBE_REF
1212+
: BindingTypes.SETUP_LET
12131213
registerBinding(bindings, node, type)
12141214
} else if (node.type === 'RestElement') {
12151215
// argument can only be identifier when destructuring
@@ -1224,8 +1224,8 @@ function walkPattern(
12241224
const type = isDefineCall
12251225
? BindingTypes.SETUP_CONST
12261226
: isConst
1227-
? BindingTypes.SETUP_MAYBE_REF
1228-
: BindingTypes.SETUP_LET
1227+
? BindingTypes.SETUP_MAYBE_REF
1228+
: BindingTypes.SETUP_LET
12291229
registerBinding(bindings, node.left, type)
12301230
} else {
12311231
walkPattern(node.left, bindings, isConst)

packages/compiler-sfc/src/script/importUsageCheck.ts

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@ import {
44
NodeTypes,
55
SimpleExpressionNode,
66
createRoot,
7+
forAliasRE,
78
parserOptions,
89
transform,
910
walkIdentifiers
@@ -87,8 +88,6 @@ function resolveTemplateUsageCheckString(sfc: SFCDescriptor) {
8788
return code
8889
}
8990

90-
const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/
91-
9291
function processExp(exp: string, dir?: string): string {
9392
if (/ as\s+\w|<.*>|:/.test(exp)) {
9493
if (dir === 'slot') {

packages/compiler-sfc/src/script/resolveType.ts

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,7 @@ import {
3434
} from './utils'
3535
import { ScriptCompileContext, resolveParserPlugins } from './context'
3636
import { ImportBinding, SFCScriptCompileOptions } from '../compileScript'
37-
import { capitalize, extend, hasOwn } from '@vue/shared'
37+
import { capitalize, hasOwn } from '@vue/shared'
3838
import { parse as babelParse } from '@babel/parser'
3939
import { parse } from '../parse'
4040
import { createCache } from '../cache'
@@ -631,8 +631,8 @@ function innerResolveTypeReference(
631631
? scope.exportedDeclares
632632
: scope.declares
633633
: onlyExported
634-
? scope.exportedTypes
635-
: scope.types
634+
? scope.exportedTypes
635+
: scope.types
636636
if (lookupSource[name]) {
637637
return lookupSource[name]
638638
} else {
@@ -675,10 +675,10 @@ function getReferenceName(node: ReferenceTypes): string | string[] {
675675
node.type === 'TSTypeReference'
676676
? node.typeName
677677
: node.type === 'TSExpressionWithTypeArguments'
678-
? node.expression
679-
: node.type === 'TSImportType'
680-
? node.qualifier
681-
: node.exprName
678+
? node.expression
679+
: node.type === 'TSImportType'
680+
? node.qualifier
681+
: node.exprName
682682
if (ref?.type === 'Identifier') {
683683
return ref.name
684684
} else if (ref?.type === 'TSQualifiedName') {
@@ -1047,8 +1047,8 @@ function ctxToScope(ctx: TypeResolveContext): TypeScope {
10471047
'ast' in ctx
10481048
? ctx.ast
10491049
: ctx.scriptAst
1050-
? [...ctx.scriptAst.body, ...ctx.scriptSetupAst!.body]
1051-
: ctx.scriptSetupAst!.body
1050+
? [...ctx.scriptAst.body, ...ctx.scriptSetupAst!.body]
1051+
: ctx.scriptSetupAst!.body
10521052

10531053
const scope = new TypeScope(
10541054
ctx.filename,
@@ -1158,7 +1158,7 @@ function recordTypes(
11581158
scope,
11591159
stmt.source.value
11601160
)
1161-
extend(scope.exportedTypes, sourceScope.exportedTypes)
1161+
Object.assign(scope.exportedTypes, sourceScope.exportedTypes)
11621162
} else if (stmt.type === 'ExportDefaultDeclaration' && stmt.declaration) {
11631163
if (stmt.declaration.type !== 'Identifier') {
11641164
recordType(stmt.declaration, types, declares, 'default')

packages/compiler-ssr/src/index.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ export function compile(
7272
// reusing core v-bind
7373
bind: transformBind,
7474
on: transformOn,
75-
// model and show has dedicated SSR handling
75+
// model and show have dedicated SSR handling
7676
model: ssrTransformModel,
7777
show: ssrTransformShow,
7878
// the following are ignored during SSR

packages/dts-test/defineCustomElement.test-d.ts

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,9 @@
1-
import { defineCustomElement } from 'vue'
2-
import { expectType, describe } from './utils'
1+
import {
2+
defineCustomElement,
3+
defineComponent,
4+
type VueElementConstructor
5+
} from 'vue'
6+
import { expectType, describe, test } from './utils'
37

48
describe('inject', () => {
59
// with object inject
@@ -62,3 +66,20 @@ describe('inject', () => {
6266
}
6367
})
6468
})
69+
70+
describe('defineCustomElement using defineComponent return type', () => {
71+
test('with emits', () => {
72+
const Comp1Vue = defineComponent({
73+
props: {
74+
a: String
75+
},
76+
emits: {
77+
click: () => true
78+
}
79+
})
80+
const Comp = defineCustomElement(Comp1Vue)
81+
expectType<VueElementConstructor>(Comp)
82+
83+
expectType<string | undefined>(new Comp().a)
84+
})
85+
})

packages/dts-test/ref.test-d.ts

Lines changed: 24 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -15,9 +15,10 @@ import {
1515
MaybeRef,
1616
MaybeRefOrGetter,
1717
ComputedRef,
18-
computed
18+
computed,
19+
ShallowRef
1920
} from 'vue'
20-
import { expectType, describe } from './utils'
21+
import { expectType, describe, IsUnion } from './utils'
2122

2223
function plainType(arg: number | Ref<number>) {
2324
// ref coercing
@@ -174,6 +175,27 @@ if (refStatus.value === 'initial') {
174175
refStatus.value = 'invalidating'
175176
}
176177

178+
{
179+
const shallow = shallowRef(1)
180+
expectType<Ref<number>>(shallow)
181+
expectType<ShallowRef<number>>(shallow)
182+
}
183+
184+
{
185+
//#7852
186+
type Steps = { step: '1' } | { step: '2' }
187+
const shallowUnionGenParam = shallowRef<Steps>({ step: '1' })
188+
const shallowUnionAsCast = shallowRef({ step: '1' } as Steps)
189+
190+
expectType<IsUnion<typeof shallowUnionGenParam>>(false)
191+
expectType<IsUnion<typeof shallowUnionAsCast>>(false)
192+
}
193+
194+
describe('shallowRef with generic', <T>() => {
195+
const r = ref({}) as MaybeRef<T>
196+
expectType<ShallowRef<T> | Ref<T>>(shallowRef(r))
197+
})
198+
177199
// proxyRefs: should return `reactive` directly
178200
const r1 = reactive({
179201
k: 'v'

packages/dts-test/setupHelpers.test-d.ts

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -110,6 +110,7 @@ describe('defineProps w/ generic type declaration + withDefaults', <T extends
110110
defineProps<{
111111
n?: number
112112
bool?: boolean
113+
s?: string
113114

114115
generic1?: T[] | { x: T }
115116
generic2?: { x: T }
@@ -128,6 +129,10 @@ describe('defineProps w/ generic type declaration + withDefaults', <T extends
128129
)
129130

130131
res.n + 1
132+
// @ts-expect-error should be readonly
133+
res.n++
134+
// @ts-expect-error should be readonly
135+
res.s = ''
131136

132137
expectType<T[] | { x: T }>(res.generic1)
133138
expectType<{ x: T }>(res.generic2)

0 commit comments

Comments
 (0)