@vue/compiler-sfc 3.2.27 → 3.2.31
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/compiler-sfc.cjs.js +24 -12
- package/dist/compiler-sfc.esm-browser.js +343 -271
- package/package.json +9 -9
package/dist/compiler-sfc.cjs.js
CHANGED
|
@@ -109,7 +109,8 @@ function sum (o) {
|
|
|
109
109
|
var hashSum = sum;
|
|
110
110
|
|
|
111
111
|
const CSS_VARS_HELPER = `useCssVars`;
|
|
112
|
-
|
|
112
|
+
// match v-bind() with max 2-levels of nested parens.
|
|
113
|
+
const cssVarRE = /v-bind\s*\(((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*)\)/g;
|
|
113
114
|
function genCssVarsFromList(vars, id, isProd) {
|
|
114
115
|
return `{\n ${vars
|
|
115
116
|
.map(key => `"${genVarName(id, key, isProd)}": (${key})`)
|
|
@@ -123,6 +124,14 @@ function genVarName(id, raw, isProd) {
|
|
|
123
124
|
return `${id}-${raw.replace(/([^\w-])/g, '_')}`;
|
|
124
125
|
}
|
|
125
126
|
}
|
|
127
|
+
function noramlizeExpression(exp) {
|
|
128
|
+
exp = exp.trim();
|
|
129
|
+
if ((exp[0] === `'` && exp[exp.length - 1] === `'`) ||
|
|
130
|
+
(exp[0] === `"` && exp[exp.length - 1] === `"`)) {
|
|
131
|
+
return exp.slice(1, -1);
|
|
132
|
+
}
|
|
133
|
+
return exp;
|
|
134
|
+
}
|
|
126
135
|
function parseCssVars(sfc) {
|
|
127
136
|
const vars = [];
|
|
128
137
|
sfc.styles.forEach(style => {
|
|
@@ -130,7 +139,7 @@ function parseCssVars(sfc) {
|
|
|
130
139
|
// ignore v-bind() in comments /* ... */
|
|
131
140
|
const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '');
|
|
132
141
|
while ((match = cssVarRE.exec(content))) {
|
|
133
|
-
const variable = match[1]
|
|
142
|
+
const variable = noramlizeExpression(match[1]);
|
|
134
143
|
if (!vars.includes(variable)) {
|
|
135
144
|
vars.push(variable);
|
|
136
145
|
}
|
|
@@ -145,8 +154,8 @@ const cssVarsPlugin = opts => {
|
|
|
145
154
|
Declaration(decl) {
|
|
146
155
|
// rewrite CSS variables
|
|
147
156
|
if (cssVarRE.test(decl.value)) {
|
|
148
|
-
decl.value = decl.value.replace(cssVarRE, (_, $1
|
|
149
|
-
return `var(--${genVarName(id, $1
|
|
157
|
+
decl.value = decl.value.replace(cssVarRE, (_, $1) => {
|
|
158
|
+
return `var(--${genVarName(id, noramlizeExpression($1), isProd)})`;
|
|
150
159
|
});
|
|
151
160
|
}
|
|
152
161
|
}
|
|
@@ -3288,7 +3297,7 @@ function compileScript(sfc, options) {
|
|
|
3288
3297
|
let { script, scriptSetup, source, filename } = sfc;
|
|
3289
3298
|
// feature flags
|
|
3290
3299
|
// TODO remove support for deprecated options when out of experimental
|
|
3291
|
-
const
|
|
3300
|
+
const enableReactivityTransform = !!options.reactivityTransform ||
|
|
3292
3301
|
!!options.refSugar ||
|
|
3293
3302
|
!!options.refTransform;
|
|
3294
3303
|
const enablePropsTransform = !!options.reactivityTransform || !!options.propsDestructureTransform;
|
|
@@ -3308,6 +3317,7 @@ function compileScript(sfc, options) {
|
|
|
3308
3317
|
scriptLang === 'tsx' ||
|
|
3309
3318
|
scriptSetupLang === 'ts' ||
|
|
3310
3319
|
scriptSetupLang === 'tsx';
|
|
3320
|
+
// resolve parser plugins
|
|
3311
3321
|
const plugins = [];
|
|
3312
3322
|
if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
|
|
3313
3323
|
plugins.push('jsx');
|
|
@@ -3332,7 +3342,7 @@ function compileScript(sfc, options) {
|
|
|
3332
3342
|
sourceType: 'module'
|
|
3333
3343
|
}).program;
|
|
3334
3344
|
const bindings = analyzeScriptBindings(scriptAst.body);
|
|
3335
|
-
if (
|
|
3345
|
+
if (enableReactivityTransform && reactivityTransform.shouldTransform(content)) {
|
|
3336
3346
|
const s = new MagicString__default(source);
|
|
3337
3347
|
const startOffset = script.loc.start.offset;
|
|
3338
3348
|
const endOffset = script.loc.end.offset;
|
|
@@ -3799,10 +3809,10 @@ function compileScript(sfc, options) {
|
|
|
3799
3809
|
walkDeclaration(node, scriptBindings, userImportAlias);
|
|
3800
3810
|
}
|
|
3801
3811
|
}
|
|
3802
|
-
// apply
|
|
3803
|
-
if (
|
|
3804
|
-
const { rootRefs
|
|
3805
|
-
refBindings =
|
|
3812
|
+
// apply reactivity transform
|
|
3813
|
+
if (enableReactivityTransform && reactivityTransform.shouldTransform(script.content)) {
|
|
3814
|
+
const { rootRefs, importedHelpers } = reactivityTransform.transformAST(scriptAst, s, scriptStartOffset);
|
|
3815
|
+
refBindings = rootRefs;
|
|
3806
3816
|
for (const h of importedHelpers) {
|
|
3807
3817
|
helperImports.add(h);
|
|
3808
3818
|
}
|
|
@@ -3987,8 +3997,10 @@ function compileScript(sfc, options) {
|
|
|
3987
3997
|
}
|
|
3988
3998
|
}
|
|
3989
3999
|
}
|
|
3990
|
-
// 3. Apply
|
|
3991
|
-
if ((
|
|
4000
|
+
// 3. Apply reactivity transform
|
|
4001
|
+
if ((enableReactivityTransform &&
|
|
4002
|
+
// normal <script> had ref bindings that maybe used in <script setup>
|
|
4003
|
+
(refBindings || reactivityTransform.shouldTransform(scriptSetup.content))) ||
|
|
3992
4004
|
propsDestructureDecl) {
|
|
3993
4005
|
const { rootRefs, importedHelpers } = reactivityTransform.transformAST(scriptSetupAst, s, startOffset, refBindings, propsDestructuredBindings);
|
|
3994
4006
|
refBindings = refBindings ? [...refBindings, ...rootRefs] : rootRefs;
|
|
@@ -302,8 +302,20 @@ const SVG_TAGS = 'svg,animate,animateMotion,animateTransform,circle,clipPath,col
|
|
|
302
302
|
'polygon,polyline,radialGradient,rect,set,solidcolor,stop,switch,symbol,' +
|
|
303
303
|
'text,textPath,title,tspan,unknown,use,view';
|
|
304
304
|
const VOID_TAGS = 'area,base,br,col,embed,hr,img,input,link,meta,param,source,track,wbr';
|
|
305
|
+
/**
|
|
306
|
+
* Compiler only.
|
|
307
|
+
* Do NOT use in runtime code paths unless behind `true` flag.
|
|
308
|
+
*/
|
|
305
309
|
const isHTMLTag = /*#__PURE__*/ makeMap(HTML_TAGS);
|
|
310
|
+
/**
|
|
311
|
+
* Compiler only.
|
|
312
|
+
* Do NOT use in runtime code paths unless behind `true` flag.
|
|
313
|
+
*/
|
|
306
314
|
const isSVGTag = /*#__PURE__*/ makeMap(SVG_TAGS);
|
|
315
|
+
/**
|
|
316
|
+
* Compiler only.
|
|
317
|
+
* Do NOT use in runtime code paths unless behind `true` flag.
|
|
318
|
+
*/
|
|
307
319
|
const isVoidTag = /*#__PURE__*/ makeMap(VOID_TAGS);
|
|
308
320
|
|
|
309
321
|
const escapeRE = /["'&<>]/;
|
|
@@ -351,13 +363,15 @@ function escapeHtml(string) {
|
|
|
351
363
|
* @private
|
|
352
364
|
*/
|
|
353
365
|
const toDisplayString = (val) => {
|
|
354
|
-
return val
|
|
355
|
-
?
|
|
356
|
-
:
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
366
|
+
return isString(val)
|
|
367
|
+
? val
|
|
368
|
+
: val == null
|
|
369
|
+
? ''
|
|
370
|
+
: isArray(val) ||
|
|
371
|
+
(isObject(val) &&
|
|
372
|
+
(val.toString === objectToString || !isFunction(val.toString)))
|
|
373
|
+
? JSON.stringify(val, replacer, 2)
|
|
374
|
+
: String(val);
|
|
361
375
|
};
|
|
362
376
|
const replacer = (_key, val) => {
|
|
363
377
|
// can't use isRef here since @vue/shared has no deps
|
|
@@ -412,6 +426,7 @@ const isReservedProp = /*#__PURE__*/ makeMap(
|
|
|
412
426
|
'onVnodeBeforeMount,onVnodeMounted,' +
|
|
413
427
|
'onVnodeBeforeUpdate,onVnodeUpdated,' +
|
|
414
428
|
'onVnodeBeforeUnmount,onVnodeUnmounted');
|
|
429
|
+
const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
|
|
415
430
|
const cacheStringFunction = (fn) => {
|
|
416
431
|
const cache = Object.create(null);
|
|
417
432
|
return ((str) => {
|
|
@@ -16320,13 +16335,13 @@ const deprecationData = {
|
|
|
16320
16335
|
message: `Platform-native elements with "is" prop will no longer be ` +
|
|
16321
16336
|
`treated as components in Vue 3 unless the "is" value is explicitly ` +
|
|
16322
16337
|
`prefixed with "vue:".`,
|
|
16323
|
-
link: `https://v3.vuejs.org/
|
|
16338
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
|
|
16324
16339
|
},
|
|
16325
16340
|
["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
|
|
16326
16341
|
message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
|
|
16327
16342
|
`argument instead. \`v-bind:${key}.sync\` should be changed to ` +
|
|
16328
16343
|
`\`v-model:${key}\`.`,
|
|
16329
|
-
link: `https://v3.vuejs.org/
|
|
16344
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
|
|
16330
16345
|
},
|
|
16331
16346
|
["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
|
|
16332
16347
|
message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
|
|
@@ -16338,11 +16353,11 @@ const deprecationData = {
|
|
|
16338
16353
|
`that appears before v-bind in the case of conflict. ` +
|
|
16339
16354
|
`To retain 2.x behavior, move v-bind to make it the first attribute. ` +
|
|
16340
16355
|
`You can also suppress this warning if the usage is intended.`,
|
|
16341
|
-
link: `https://v3.vuejs.org/
|
|
16356
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
|
|
16342
16357
|
},
|
|
16343
16358
|
["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
|
|
16344
16359
|
message: `.native modifier for v-on has been removed as is no longer necessary.`,
|
|
16345
|
-
link: `https://v3.vuejs.org/
|
|
16360
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/v-on-native-modifier-removed.html`
|
|
16346
16361
|
},
|
|
16347
16362
|
["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
|
|
16348
16363
|
message: `v-if / v-for precedence when used on the same element has changed ` +
|
|
@@ -16350,7 +16365,7 @@ const deprecationData = {
|
|
|
16350
16365
|
`access to v-for scope variables. It is best to avoid the ambiguity ` +
|
|
16351
16366
|
`with <template> tags or use a computed property that filters v-for ` +
|
|
16352
16367
|
`data source.`,
|
|
16353
|
-
link: `https://v3.vuejs.org/
|
|
16368
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/v-if-v-for.html`
|
|
16354
16369
|
},
|
|
16355
16370
|
["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
|
|
16356
16371
|
message: `<template> with no special directives will render as a native template ` +
|
|
@@ -16358,13 +16373,13 @@ const deprecationData = {
|
|
|
16358
16373
|
},
|
|
16359
16374
|
["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
|
|
16360
16375
|
message: `"inline-template" has been removed in Vue 3.`,
|
|
16361
|
-
link: `https://v3.vuejs.org/
|
|
16376
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
|
|
16362
16377
|
},
|
|
16363
16378
|
["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
|
|
16364
16379
|
message: `filters have been removed in Vue 3. ` +
|
|
16365
16380
|
`The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
|
|
16366
16381
|
`Use method calls or computed properties instead.`,
|
|
16367
|
-
link: `https://v3.vuejs.org/
|
|
16382
|
+
link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
|
|
16368
16383
|
}
|
|
16369
16384
|
};
|
|
16370
16385
|
function getCompatValue(key, context) {
|
|
@@ -16849,7 +16864,7 @@ function parseAttributes(context, type) {
|
|
|
16849
16864
|
}
|
|
16850
16865
|
const attr = parseAttribute(context, attributeNames);
|
|
16851
16866
|
// Trim whitespace between class
|
|
16852
|
-
// https://github.com/vuejs/
|
|
16867
|
+
// https://github.com/vuejs/core/issues/4251
|
|
16853
16868
|
if (attr.type === 6 /* ATTRIBUTE */ &&
|
|
16854
16869
|
attr.value &&
|
|
16855
16870
|
attr.name === 'class') {
|
|
@@ -17074,7 +17089,7 @@ function parseTextData(context, length, mode) {
|
|
|
17074
17089
|
advanceBy(context, length);
|
|
17075
17090
|
if (mode === 2 /* RAWTEXT */ ||
|
|
17076
17091
|
mode === 3 /* CDATA */ ||
|
|
17077
|
-
rawText.
|
|
17092
|
+
!rawText.includes('&')) {
|
|
17078
17093
|
return rawText;
|
|
17079
17094
|
}
|
|
17080
17095
|
else {
|
|
@@ -22201,7 +22216,7 @@ function isReferenced(node, parent, grandparent) {
|
|
|
22201
22216
|
// no: NODE.target
|
|
22202
22217
|
case 'MetaProperty':
|
|
22203
22218
|
return false;
|
|
22204
|
-
// yes: type X = {
|
|
22219
|
+
// yes: type X = { someProperty: NODE }
|
|
22205
22220
|
// no: type X = { NODE: OtherType }
|
|
22206
22221
|
case 'ObjectTypeProperty':
|
|
22207
22222
|
return parent.key !== node;
|
|
@@ -22708,6 +22723,7 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
|
|
|
22708
22723
|
const renderExp = createCallExpression(helper(RENDER_LIST), [
|
|
22709
22724
|
forNode.source
|
|
22710
22725
|
]);
|
|
22726
|
+
const isTemplate = isTemplateNode(node);
|
|
22711
22727
|
const memo = findDir(node, 'memo');
|
|
22712
22728
|
const keyProp = findProp(node, `key`);
|
|
22713
22729
|
const keyExp = keyProp &&
|
|
@@ -22715,15 +22731,17 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
|
|
|
22715
22731
|
? createSimpleExpression(keyProp.value.content, true)
|
|
22716
22732
|
: keyProp.exp);
|
|
22717
22733
|
const keyProperty = keyProp ? createObjectProperty(`key`, keyExp) : null;
|
|
22718
|
-
if (
|
|
22719
|
-
|
|
22720
|
-
|
|
22721
|
-
//
|
|
22722
|
-
//
|
|
22723
|
-
|
|
22724
|
-
|
|
22725
|
-
|
|
22726
|
-
keyProperty
|
|
22734
|
+
if (isTemplate) {
|
|
22735
|
+
// #2085 / #5288 process :key and v-memo expressions need to be
|
|
22736
|
+
// processed on `<template v-for>`. In this case the node is discarded
|
|
22737
|
+
// and never traversed so its binding expressions won't be processed
|
|
22738
|
+
// by the normal transforms.
|
|
22739
|
+
if (memo) {
|
|
22740
|
+
memo.exp = processExpression(memo.exp, context);
|
|
22741
|
+
}
|
|
22742
|
+
if (keyProperty && keyProp.type !== 6 /* ATTRIBUTE */) {
|
|
22743
|
+
keyProperty.value = processExpression(keyProperty.value, context);
|
|
22744
|
+
}
|
|
22727
22745
|
}
|
|
22728
22746
|
const isStableFragment = forNode.source.type === 4 /* SIMPLE_EXPRESSION */ &&
|
|
22729
22747
|
forNode.source.constType > 0 /* NOT_CONSTANT */;
|
|
@@ -22737,7 +22755,6 @@ const transformFor = createStructuralDirectiveTransform('for', (node, dir, conte
|
|
|
22737
22755
|
return () => {
|
|
22738
22756
|
// finish the codegen now that all children have been traversed
|
|
22739
22757
|
let childBlock;
|
|
22740
|
-
const isTemplate = isTemplateNode(node);
|
|
22741
22758
|
const { children } = forNode;
|
|
22742
22759
|
// check <template v-for> key placement
|
|
22743
22760
|
if (isTemplate) {
|
|
@@ -23622,7 +23639,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
|
|
|
23622
23639
|
}
|
|
23623
23640
|
}
|
|
23624
23641
|
}
|
|
23625
|
-
else {
|
|
23642
|
+
else if (!isBuiltInDirective(name)) {
|
|
23626
23643
|
// no built-in transform, this is a user custom directive.
|
|
23627
23644
|
runtimeDirectives.push(prop);
|
|
23628
23645
|
// custom dirs may use beforeUpdate so they need to force blocks
|
|
@@ -27478,6 +27495,7 @@ var CompilerDOM = /*#__PURE__*/Object.freeze({
|
|
|
27478
27495
|
transformElement: transformElement,
|
|
27479
27496
|
resolveComponentType: resolveComponentType,
|
|
27480
27497
|
buildProps: buildProps,
|
|
27498
|
+
buildDirectiveArgs: buildDirectiveArgs,
|
|
27481
27499
|
processSlotOutlet: processSlotOutlet,
|
|
27482
27500
|
generateCodeFrame: generateCodeFrame,
|
|
27483
27501
|
checkCompatEnabled: checkCompatEnabled,
|
|
@@ -27648,7 +27666,8 @@ function sum (o) {
|
|
|
27648
27666
|
var hashSum = sum;
|
|
27649
27667
|
|
|
27650
27668
|
const CSS_VARS_HELPER = `useCssVars`;
|
|
27651
|
-
|
|
27669
|
+
// match v-bind() with max 2-levels of nested parens.
|
|
27670
|
+
const cssVarRE = /v-bind\s*\(((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*)\)/g;
|
|
27652
27671
|
function genCssVarsFromList(vars, id, isProd) {
|
|
27653
27672
|
return `{\n ${vars
|
|
27654
27673
|
.map(key => `"${genVarName(id, key, isProd)}": (${key})`)
|
|
@@ -27662,6 +27681,14 @@ function genVarName(id, raw, isProd) {
|
|
|
27662
27681
|
return `${id}-${raw.replace(/([^\w-])/g, '_')}`;
|
|
27663
27682
|
}
|
|
27664
27683
|
}
|
|
27684
|
+
function noramlizeExpression(exp) {
|
|
27685
|
+
exp = exp.trim();
|
|
27686
|
+
if ((exp[0] === `'` && exp[exp.length - 1] === `'`) ||
|
|
27687
|
+
(exp[0] === `"` && exp[exp.length - 1] === `"`)) {
|
|
27688
|
+
return exp.slice(1, -1);
|
|
27689
|
+
}
|
|
27690
|
+
return exp;
|
|
27691
|
+
}
|
|
27665
27692
|
function parseCssVars(sfc) {
|
|
27666
27693
|
const vars = [];
|
|
27667
27694
|
sfc.styles.forEach(style => {
|
|
@@ -27669,7 +27696,7 @@ function parseCssVars(sfc) {
|
|
|
27669
27696
|
// ignore v-bind() in comments /* ... */
|
|
27670
27697
|
const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '');
|
|
27671
27698
|
while ((match = cssVarRE.exec(content))) {
|
|
27672
|
-
const variable = match[1]
|
|
27699
|
+
const variable = noramlizeExpression(match[1]);
|
|
27673
27700
|
if (!vars.includes(variable)) {
|
|
27674
27701
|
vars.push(variable);
|
|
27675
27702
|
}
|
|
@@ -27684,8 +27711,8 @@ const cssVarsPlugin = opts => {
|
|
|
27684
27711
|
Declaration(decl) {
|
|
27685
27712
|
// rewrite CSS variables
|
|
27686
27713
|
if (cssVarRE.test(decl.value)) {
|
|
27687
|
-
decl.value = decl.value.replace(cssVarRE, (_, $1
|
|
27688
|
-
return `var(--${genVarName(id, $1
|
|
27714
|
+
decl.value = decl.value.replace(cssVarRE, (_, $1) => {
|
|
27715
|
+
return `var(--${genVarName(id, noramlizeExpression($1), isProd)})`;
|
|
27689
27716
|
});
|
|
27690
27717
|
}
|
|
27691
27718
|
}
|
|
@@ -33281,6 +33308,7 @@ const SSR_RENDER_DYNAMIC_MODEL = Symbol(`ssrRenderDynamicModel`);
|
|
|
33281
33308
|
const SSR_GET_DYNAMIC_MODEL_PROPS = Symbol(`ssrGetDynamicModelProps`);
|
|
33282
33309
|
const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
|
|
33283
33310
|
const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
|
|
33311
|
+
const SSR_GET_DIRECTIVE_PROPS = Symbol(`ssrGetDirectiveProps`);
|
|
33284
33312
|
const ssrHelpers = {
|
|
33285
33313
|
[SSR_INTERPOLATE]: `ssrInterpolate`,
|
|
33286
33314
|
[SSR_RENDER_VNODE]: `ssrRenderVNode`,
|
|
@@ -33298,7 +33326,8 @@ const ssrHelpers = {
|
|
|
33298
33326
|
[SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
|
|
33299
33327
|
[SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
|
|
33300
33328
|
[SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
|
|
33301
|
-
[SSR_RENDER_SUSPENSE]: `ssrRenderSuspense
|
|
33329
|
+
[SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
|
|
33330
|
+
[SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
|
|
33302
33331
|
};
|
|
33303
33332
|
// Note: these are helpers imported from @vue/server-renderer
|
|
33304
33333
|
// make sure the names match!
|
|
@@ -33524,224 +33553,6 @@ function ssrProcessTransitionGroup(node, context) {
|
|
|
33524
33553
|
}
|
|
33525
33554
|
}
|
|
33526
33555
|
|
|
33527
|
-
// We need to construct the slot functions in the 1st pass to ensure proper
|
|
33528
|
-
// scope tracking, but the children of each slot cannot be processed until
|
|
33529
|
-
// the 2nd pass, so we store the WIP slot functions in a weakmap during the 1st
|
|
33530
|
-
// pass and complete them in the 2nd pass.
|
|
33531
|
-
const wipMap$1 = new WeakMap();
|
|
33532
|
-
const componentTypeMap = new WeakMap();
|
|
33533
|
-
// ssr component transform is done in two phases:
|
|
33534
|
-
// In phase 1. we use `buildSlot` to analyze the children of the component into
|
|
33535
|
-
// WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
|
|
33536
|
-
// the core transform context).
|
|
33537
|
-
// In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
|
|
33538
|
-
// nodes.
|
|
33539
|
-
const ssrTransformComponent = (node, context) => {
|
|
33540
|
-
if (node.type !== 1 /* ELEMENT */ ||
|
|
33541
|
-
node.tagType !== 1 /* COMPONENT */) {
|
|
33542
|
-
return;
|
|
33543
|
-
}
|
|
33544
|
-
const component = resolveComponentType(node, context, true /* ssr */);
|
|
33545
|
-
componentTypeMap.set(node, component);
|
|
33546
|
-
if (isSymbol(component)) {
|
|
33547
|
-
if (component === SUSPENSE) {
|
|
33548
|
-
return ssrTransformSuspense(node, context);
|
|
33549
|
-
}
|
|
33550
|
-
return; // built-in component: fallthrough
|
|
33551
|
-
}
|
|
33552
|
-
// Build the fallback vnode-based branch for the component's slots.
|
|
33553
|
-
// We need to clone the node into a fresh copy and use the buildSlots' logic
|
|
33554
|
-
// to get access to the children of each slot. We then compile them with
|
|
33555
|
-
// a child transform pipeline using vnode-based transforms (instead of ssr-
|
|
33556
|
-
// based ones), and save the result branch (a ReturnStatement) in an array.
|
|
33557
|
-
// The branch is retrieved when processing slots again in ssr mode.
|
|
33558
|
-
const vnodeBranches = [];
|
|
33559
|
-
const clonedNode = clone(node);
|
|
33560
|
-
return function ssrPostTransformComponent() {
|
|
33561
|
-
// Using the cloned node, build the normal VNode-based branches (for
|
|
33562
|
-
// fallback in case the child is render-fn based). Store them in an array
|
|
33563
|
-
// for later use.
|
|
33564
|
-
if (clonedNode.children.length) {
|
|
33565
|
-
buildSlots(clonedNode, context, (props, children) => {
|
|
33566
|
-
vnodeBranches.push(createVNodeSlotBranch(props, children, context));
|
|
33567
|
-
return createFunctionExpression(undefined);
|
|
33568
|
-
});
|
|
33569
|
-
}
|
|
33570
|
-
const props = node.props.length > 0
|
|
33571
|
-
? // note we are not passing ssr: true here because for components, v-on
|
|
33572
|
-
// handlers should still be passed
|
|
33573
|
-
buildProps(node, context).props || `null`
|
|
33574
|
-
: `null`;
|
|
33575
|
-
const wipEntries = [];
|
|
33576
|
-
wipMap$1.set(node, wipEntries);
|
|
33577
|
-
const buildSSRSlotFn = (props, children, loc) => {
|
|
33578
|
-
const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
|
|
33579
|
-
true, // newline
|
|
33580
|
-
true, // isSlot
|
|
33581
|
-
loc);
|
|
33582
|
-
wipEntries.push({
|
|
33583
|
-
fn,
|
|
33584
|
-
children,
|
|
33585
|
-
// also collect the corresponding vnode branch built earlier
|
|
33586
|
-
vnodeBranch: vnodeBranches[wipEntries.length]
|
|
33587
|
-
});
|
|
33588
|
-
return fn;
|
|
33589
|
-
};
|
|
33590
|
-
const slots = node.children.length
|
|
33591
|
-
? buildSlots(node, context, buildSSRSlotFn).slots
|
|
33592
|
-
: `null`;
|
|
33593
|
-
if (typeof component !== 'string') {
|
|
33594
|
-
// dynamic component that resolved to a `resolveDynamicComponent` call
|
|
33595
|
-
// expression - since the resolved result may be a plain element (string)
|
|
33596
|
-
// or a VNode, handle it with `renderVNode`.
|
|
33597
|
-
node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
|
|
33598
|
-
`_push`,
|
|
33599
|
-
createCallExpression(context.helper(CREATE_VNODE), [
|
|
33600
|
-
component,
|
|
33601
|
-
props,
|
|
33602
|
-
slots
|
|
33603
|
-
]),
|
|
33604
|
-
`_parent`
|
|
33605
|
-
]);
|
|
33606
|
-
}
|
|
33607
|
-
else {
|
|
33608
|
-
node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, props, slots, `_parent`]);
|
|
33609
|
-
}
|
|
33610
|
-
};
|
|
33611
|
-
};
|
|
33612
|
-
function ssrProcessComponent(node, context) {
|
|
33613
|
-
const component = componentTypeMap.get(node);
|
|
33614
|
-
if (!node.ssrCodegenNode) {
|
|
33615
|
-
// this is a built-in component that fell-through.
|
|
33616
|
-
if (component === TELEPORT) {
|
|
33617
|
-
return ssrProcessTeleport(node, context);
|
|
33618
|
-
}
|
|
33619
|
-
else if (component === SUSPENSE) {
|
|
33620
|
-
return ssrProcessSuspense(node, context);
|
|
33621
|
-
}
|
|
33622
|
-
else if (component === TRANSITION_GROUP) {
|
|
33623
|
-
return ssrProcessTransitionGroup(node, context);
|
|
33624
|
-
}
|
|
33625
|
-
else {
|
|
33626
|
-
// real fall-through: Transition / KeepAlive
|
|
33627
|
-
// just render its children.
|
|
33628
|
-
processChildren(node.children, context);
|
|
33629
|
-
}
|
|
33630
|
-
}
|
|
33631
|
-
else {
|
|
33632
|
-
// finish up slot function expressions from the 1st pass.
|
|
33633
|
-
const wipEntries = wipMap$1.get(node) || [];
|
|
33634
|
-
for (let i = 0; i < wipEntries.length; i++) {
|
|
33635
|
-
const { fn, children, vnodeBranch } = wipEntries[i];
|
|
33636
|
-
// For each slot, we generate two branches: one SSR-optimized branch and
|
|
33637
|
-
// one normal vnode-based branch. The branches are taken based on the
|
|
33638
|
-
// presence of the 2nd `_push` argument (which is only present if the slot
|
|
33639
|
-
// is called by `_ssrRenderSlot`.
|
|
33640
|
-
fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
|
|
33641
|
-
}
|
|
33642
|
-
// component is inside a slot, inherit slot scope Id
|
|
33643
|
-
if (context.withSlotScopeId) {
|
|
33644
|
-
node.ssrCodegenNode.arguments.push(`_scopeId`);
|
|
33645
|
-
}
|
|
33646
|
-
if (typeof component === 'string') {
|
|
33647
|
-
// static component
|
|
33648
|
-
context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
|
|
33649
|
-
}
|
|
33650
|
-
else {
|
|
33651
|
-
// dynamic component (`resolveDynamicComponent` call)
|
|
33652
|
-
// the codegen node is a `renderVNode` call
|
|
33653
|
-
context.pushStatement(node.ssrCodegenNode);
|
|
33654
|
-
}
|
|
33655
|
-
}
|
|
33656
|
-
}
|
|
33657
|
-
const rawOptionsMap = new WeakMap();
|
|
33658
|
-
const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
|
|
33659
|
-
const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
|
|
33660
|
-
const vnodeDirectiveTransforms = Object.assign(Object.assign({}, baseDirectiveTransforms), DOMDirectiveTransforms);
|
|
33661
|
-
function createVNodeSlotBranch(props, children, parentContext) {
|
|
33662
|
-
// apply a sub-transform using vnode-based transforms.
|
|
33663
|
-
const rawOptions = rawOptionsMap.get(parentContext.root);
|
|
33664
|
-
const subOptions = Object.assign(Object.assign({}, rawOptions), {
|
|
33665
|
-
// overwrite with vnode-based transforms
|
|
33666
|
-
nodeTransforms: [
|
|
33667
|
-
...vnodeNodeTransforms,
|
|
33668
|
-
...(rawOptions.nodeTransforms || [])
|
|
33669
|
-
], directiveTransforms: Object.assign(Object.assign({}, vnodeDirectiveTransforms), (rawOptions.directiveTransforms || {})) });
|
|
33670
|
-
// wrap the children with a wrapper template for proper children treatment.
|
|
33671
|
-
const wrapperNode = {
|
|
33672
|
-
type: 1 /* ELEMENT */,
|
|
33673
|
-
ns: 0 /* HTML */,
|
|
33674
|
-
tag: 'template',
|
|
33675
|
-
tagType: 3 /* TEMPLATE */,
|
|
33676
|
-
isSelfClosing: false,
|
|
33677
|
-
// important: provide v-slot="props" on the wrapper for proper
|
|
33678
|
-
// scope analysis
|
|
33679
|
-
props: [
|
|
33680
|
-
{
|
|
33681
|
-
type: 7 /* DIRECTIVE */,
|
|
33682
|
-
name: 'slot',
|
|
33683
|
-
exp: props,
|
|
33684
|
-
arg: undefined,
|
|
33685
|
-
modifiers: [],
|
|
33686
|
-
loc: locStub
|
|
33687
|
-
}
|
|
33688
|
-
],
|
|
33689
|
-
children,
|
|
33690
|
-
loc: locStub,
|
|
33691
|
-
codegenNode: undefined
|
|
33692
|
-
};
|
|
33693
|
-
subTransform(wrapperNode, subOptions, parentContext);
|
|
33694
|
-
return createReturnStatement(children);
|
|
33695
|
-
}
|
|
33696
|
-
function subTransform(node, options, parentContext) {
|
|
33697
|
-
const childRoot = createRoot([node]);
|
|
33698
|
-
const childContext = createTransformContext(childRoot, options);
|
|
33699
|
-
// this sub transform is for vnode fallback branch so it should be handled
|
|
33700
|
-
// like normal render functions
|
|
33701
|
-
childContext.ssr = false;
|
|
33702
|
-
// inherit parent scope analysis state
|
|
33703
|
-
childContext.scopes = Object.assign({}, parentContext.scopes);
|
|
33704
|
-
childContext.identifiers = Object.assign({}, parentContext.identifiers);
|
|
33705
|
-
childContext.imports = parentContext.imports;
|
|
33706
|
-
// traverse
|
|
33707
|
-
traverseNode(childRoot, childContext);
|
|
33708
|
-
['helpers', 'components', 'directives'].forEach(key => {
|
|
33709
|
-
childContext[key].forEach((value, helperKey) => {
|
|
33710
|
-
if (key === 'helpers') {
|
|
33711
|
-
const parentCount = parentContext.helpers.get(helperKey);
|
|
33712
|
-
if (parentCount === undefined) {
|
|
33713
|
-
parentContext.helpers.set(helperKey, value);
|
|
33714
|
-
}
|
|
33715
|
-
else {
|
|
33716
|
-
parentContext.helpers.set(helperKey, value + parentCount);
|
|
33717
|
-
}
|
|
33718
|
-
}
|
|
33719
|
-
else {
|
|
33720
|
-
parentContext[key].add(value);
|
|
33721
|
-
}
|
|
33722
|
-
});
|
|
33723
|
-
});
|
|
33724
|
-
// imports/hoists are not merged because:
|
|
33725
|
-
// - imports are only used for asset urls and should be consistent between
|
|
33726
|
-
// node/client branches
|
|
33727
|
-
// - hoists are not enabled for the client branch here
|
|
33728
|
-
}
|
|
33729
|
-
function clone(v) {
|
|
33730
|
-
if (isArray(v)) {
|
|
33731
|
-
return v.map(clone);
|
|
33732
|
-
}
|
|
33733
|
-
else if (isObject(v)) {
|
|
33734
|
-
const res = {};
|
|
33735
|
-
for (const key in v) {
|
|
33736
|
-
res[key] = clone(v[key]);
|
|
33737
|
-
}
|
|
33738
|
-
return res;
|
|
33739
|
-
}
|
|
33740
|
-
else {
|
|
33741
|
-
return v;
|
|
33742
|
-
}
|
|
33743
|
-
}
|
|
33744
|
-
|
|
33745
33556
|
// for directives with children overwrite (e.g. v-html & v-text), we need to
|
|
33746
33557
|
// store the raw children so that they can be added in the 2nd pass.
|
|
33747
33558
|
const rawChildrenMap = new WeakMap();
|
|
@@ -33756,14 +33567,17 @@ const ssrTransformElement = (node, context) => {
|
|
|
33756
33567
|
const openTag = [`<${node.tag}`];
|
|
33757
33568
|
// some tags need to be passed to runtime for special checks
|
|
33758
33569
|
const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
|
|
33759
|
-
// v-bind="obj"
|
|
33760
|
-
// attrs and can affect final rendering result,
|
|
33761
|
-
// we need to bail out to full `renderAttrs`
|
|
33570
|
+
// v-bind="obj", v-bind:[key] and custom directives can potentially
|
|
33571
|
+
// overwrite other static attrs and can affect final rendering result,
|
|
33572
|
+
// so when they are present we need to bail out to full `renderAttrs`
|
|
33762
33573
|
const hasDynamicVBind = hasDynamicKeyVBind(node);
|
|
33763
|
-
|
|
33764
|
-
|
|
33765
|
-
|
|
33766
|
-
|
|
33574
|
+
const hasCustomDir = node.props.some(p => p.type === 7 /* DIRECTIVE */ && !isBuiltInDirective(p.name));
|
|
33575
|
+
const needMergeProps = hasDynamicVBind || hasCustomDir;
|
|
33576
|
+
if (needMergeProps) {
|
|
33577
|
+
const { props, directives } = buildProps(node, context, node.props, true /* ssr */);
|
|
33578
|
+
if (props || directives.length) {
|
|
33579
|
+
const mergedProps = buildSSRProps(props, directives, context);
|
|
33580
|
+
const propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [mergedProps]);
|
|
33767
33581
|
if (node.tag === 'textarea') {
|
|
33768
33582
|
const existingText = node.children[0];
|
|
33769
33583
|
// If interpolation, this is dynamic <textarea> content, potentially
|
|
@@ -33775,7 +33589,7 @@ const ssrTransformElement = (node, context) => {
|
|
|
33775
33589
|
// it contains value (if yes, render is as children).
|
|
33776
33590
|
const tempId = `_temp${context.temps++}`;
|
|
33777
33591
|
propsExp.arguments = [
|
|
33778
|
-
createAssignmentExpression(createSimpleExpression(tempId, false),
|
|
33592
|
+
createAssignmentExpression(createSimpleExpression(tempId, false), mergedProps)
|
|
33779
33593
|
];
|
|
33780
33594
|
rawChildrenMap.set(node, createCallExpression(context.helper(SSR_INTERPOLATE), [
|
|
33781
33595
|
createConditionalExpression(createSimpleExpression(`"value" in ${tempId}`, false), createSimpleExpression(`${tempId}.value`, false), createSimpleExpression(existingText ? existingText.content : ``, true), false)
|
|
@@ -33793,7 +33607,7 @@ const ssrTransformElement = (node, context) => {
|
|
|
33793
33607
|
const tempExp = createSimpleExpression(tempId, false);
|
|
33794
33608
|
propsExp.arguments = [
|
|
33795
33609
|
createSequenceExpression([
|
|
33796
|
-
createAssignmentExpression(tempExp,
|
|
33610
|
+
createAssignmentExpression(tempExp, mergedProps),
|
|
33797
33611
|
createCallExpression(context.helper(MERGE_PROPS), [
|
|
33798
33612
|
tempExp,
|
|
33799
33613
|
createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
|
|
@@ -33835,11 +33649,11 @@ const ssrTransformElement = (node, context) => {
|
|
|
33835
33649
|
context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, prop.loc));
|
|
33836
33650
|
}
|
|
33837
33651
|
else if (isTextareaWithValue(node, prop) && prop.exp) {
|
|
33838
|
-
if (!
|
|
33652
|
+
if (!needMergeProps) {
|
|
33839
33653
|
node.children = [createInterpolation(prop.exp, prop.loc)];
|
|
33840
33654
|
}
|
|
33841
33655
|
}
|
|
33842
|
-
else if (!
|
|
33656
|
+
else if (!needMergeProps) {
|
|
33843
33657
|
// Directive transforms.
|
|
33844
33658
|
const directiveTransform = context.directiveTransforms[prop.name];
|
|
33845
33659
|
if (directiveTransform) {
|
|
@@ -33905,7 +33719,7 @@ const ssrTransformElement = (node, context) => {
|
|
|
33905
33719
|
if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
|
|
33906
33720
|
rawChildrenMap.set(node, escapeHtml(prop.value.content));
|
|
33907
33721
|
}
|
|
33908
|
-
else if (!
|
|
33722
|
+
else if (!needMergeProps) {
|
|
33909
33723
|
if (prop.name === 'key' || prop.name === 'ref') {
|
|
33910
33724
|
continue;
|
|
33911
33725
|
}
|
|
@@ -33929,6 +33743,29 @@ const ssrTransformElement = (node, context) => {
|
|
|
33929
33743
|
node.ssrCodegenNode = createTemplateLiteral(openTag);
|
|
33930
33744
|
};
|
|
33931
33745
|
};
|
|
33746
|
+
function buildSSRProps(props, directives, context) {
|
|
33747
|
+
let mergePropsArgs = [];
|
|
33748
|
+
if (props) {
|
|
33749
|
+
if (props.type === 14 /* JS_CALL_EXPRESSION */) {
|
|
33750
|
+
// already a mergeProps call
|
|
33751
|
+
mergePropsArgs = props.arguments;
|
|
33752
|
+
}
|
|
33753
|
+
else {
|
|
33754
|
+
mergePropsArgs.push(props);
|
|
33755
|
+
}
|
|
33756
|
+
}
|
|
33757
|
+
if (directives.length) {
|
|
33758
|
+
for (const dir of directives) {
|
|
33759
|
+
mergePropsArgs.push(createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
|
|
33760
|
+
`_ctx`,
|
|
33761
|
+
...buildDirectiveArgs(dir, context).elements
|
|
33762
|
+
]));
|
|
33763
|
+
}
|
|
33764
|
+
}
|
|
33765
|
+
return mergePropsArgs.length > 1
|
|
33766
|
+
? createCallExpression(context.helper(MERGE_PROPS), mergePropsArgs)
|
|
33767
|
+
: mergePropsArgs[0];
|
|
33768
|
+
}
|
|
33932
33769
|
function isTrueFalseValue(prop) {
|
|
33933
33770
|
if (prop.type === 7 /* DIRECTIVE */) {
|
|
33934
33771
|
return (prop.name === 'bind' &&
|
|
@@ -33989,6 +33826,228 @@ function ssrProcessElement(node, context) {
|
|
|
33989
33826
|
}
|
|
33990
33827
|
}
|
|
33991
33828
|
|
|
33829
|
+
// We need to construct the slot functions in the 1st pass to ensure proper
|
|
33830
|
+
// scope tracking, but the children of each slot cannot be processed until
|
|
33831
|
+
// the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
|
|
33832
|
+
// pass and complete them in the 2nd pass.
|
|
33833
|
+
const wipMap$1 = new WeakMap();
|
|
33834
|
+
const componentTypeMap = new WeakMap();
|
|
33835
|
+
// ssr component transform is done in two phases:
|
|
33836
|
+
// In phase 1. we use `buildSlot` to analyze the children of the component into
|
|
33837
|
+
// WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
|
|
33838
|
+
// the core transform context).
|
|
33839
|
+
// In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
|
|
33840
|
+
// nodes.
|
|
33841
|
+
const ssrTransformComponent = (node, context) => {
|
|
33842
|
+
if (node.type !== 1 /* ELEMENT */ ||
|
|
33843
|
+
node.tagType !== 1 /* COMPONENT */) {
|
|
33844
|
+
return;
|
|
33845
|
+
}
|
|
33846
|
+
const component = resolveComponentType(node, context, true /* ssr */);
|
|
33847
|
+
componentTypeMap.set(node, component);
|
|
33848
|
+
if (isSymbol(component)) {
|
|
33849
|
+
if (component === SUSPENSE) {
|
|
33850
|
+
return ssrTransformSuspense(node, context);
|
|
33851
|
+
}
|
|
33852
|
+
return; // built-in component: fallthrough
|
|
33853
|
+
}
|
|
33854
|
+
// Build the fallback vnode-based branch for the component's slots.
|
|
33855
|
+
// We need to clone the node into a fresh copy and use the buildSlots' logic
|
|
33856
|
+
// to get access to the children of each slot. We then compile them with
|
|
33857
|
+
// a child transform pipeline using vnode-based transforms (instead of ssr-
|
|
33858
|
+
// based ones), and save the result branch (a ReturnStatement) in an array.
|
|
33859
|
+
// The branch is retrieved when processing slots again in ssr mode.
|
|
33860
|
+
const vnodeBranches = [];
|
|
33861
|
+
const clonedNode = clone(node);
|
|
33862
|
+
return function ssrPostTransformComponent() {
|
|
33863
|
+
// Using the cloned node, build the normal VNode-based branches (for
|
|
33864
|
+
// fallback in case the child is render-fn based). Store them in an array
|
|
33865
|
+
// for later use.
|
|
33866
|
+
if (clonedNode.children.length) {
|
|
33867
|
+
buildSlots(clonedNode, context, (props, children) => {
|
|
33868
|
+
vnodeBranches.push(createVNodeSlotBranch(props, children, context));
|
|
33869
|
+
return createFunctionExpression(undefined);
|
|
33870
|
+
});
|
|
33871
|
+
}
|
|
33872
|
+
let propsExp = `null`;
|
|
33873
|
+
if (node.props.length) {
|
|
33874
|
+
// note we are not passing ssr: true here because for components, v-on
|
|
33875
|
+
// handlers should still be passed
|
|
33876
|
+
const { props, directives } = buildProps(node, context);
|
|
33877
|
+
if (props || directives.length) {
|
|
33878
|
+
propsExp = buildSSRProps(props, directives, context);
|
|
33879
|
+
}
|
|
33880
|
+
}
|
|
33881
|
+
const wipEntries = [];
|
|
33882
|
+
wipMap$1.set(node, wipEntries);
|
|
33883
|
+
const buildSSRSlotFn = (props, children, loc) => {
|
|
33884
|
+
const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
|
|
33885
|
+
true, // newline
|
|
33886
|
+
true, // isSlot
|
|
33887
|
+
loc);
|
|
33888
|
+
wipEntries.push({
|
|
33889
|
+
fn,
|
|
33890
|
+
children,
|
|
33891
|
+
// also collect the corresponding vnode branch built earlier
|
|
33892
|
+
vnodeBranch: vnodeBranches[wipEntries.length]
|
|
33893
|
+
});
|
|
33894
|
+
return fn;
|
|
33895
|
+
};
|
|
33896
|
+
const slots = node.children.length
|
|
33897
|
+
? buildSlots(node, context, buildSSRSlotFn).slots
|
|
33898
|
+
: `null`;
|
|
33899
|
+
if (typeof component !== 'string') {
|
|
33900
|
+
// dynamic component that resolved to a `resolveDynamicComponent` call
|
|
33901
|
+
// expression - since the resolved result may be a plain element (string)
|
|
33902
|
+
// or a VNode, handle it with `renderVNode`.
|
|
33903
|
+
node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
|
|
33904
|
+
`_push`,
|
|
33905
|
+
createCallExpression(context.helper(CREATE_VNODE), [
|
|
33906
|
+
component,
|
|
33907
|
+
propsExp,
|
|
33908
|
+
slots
|
|
33909
|
+
]),
|
|
33910
|
+
`_parent`
|
|
33911
|
+
]);
|
|
33912
|
+
}
|
|
33913
|
+
else {
|
|
33914
|
+
node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, propsExp, slots, `_parent`]);
|
|
33915
|
+
}
|
|
33916
|
+
};
|
|
33917
|
+
};
|
|
33918
|
+
function ssrProcessComponent(node, context) {
|
|
33919
|
+
const component = componentTypeMap.get(node);
|
|
33920
|
+
if (!node.ssrCodegenNode) {
|
|
33921
|
+
// this is a built-in component that fell-through.
|
|
33922
|
+
if (component === TELEPORT) {
|
|
33923
|
+
return ssrProcessTeleport(node, context);
|
|
33924
|
+
}
|
|
33925
|
+
else if (component === SUSPENSE) {
|
|
33926
|
+
return ssrProcessSuspense(node, context);
|
|
33927
|
+
}
|
|
33928
|
+
else if (component === TRANSITION_GROUP) {
|
|
33929
|
+
return ssrProcessTransitionGroup(node, context);
|
|
33930
|
+
}
|
|
33931
|
+
else {
|
|
33932
|
+
// real fall-through: Transition / KeepAlive
|
|
33933
|
+
// just render its children.
|
|
33934
|
+
processChildren(node.children, context);
|
|
33935
|
+
}
|
|
33936
|
+
}
|
|
33937
|
+
else {
|
|
33938
|
+
// finish up slot function expressions from the 1st pass.
|
|
33939
|
+
const wipEntries = wipMap$1.get(node) || [];
|
|
33940
|
+
for (let i = 0; i < wipEntries.length; i++) {
|
|
33941
|
+
const { fn, children, vnodeBranch } = wipEntries[i];
|
|
33942
|
+
// For each slot, we generate two branches: one SSR-optimized branch and
|
|
33943
|
+
// one normal vnode-based branch. The branches are taken based on the
|
|
33944
|
+
// presence of the 2nd `_push` argument (which is only present if the slot
|
|
33945
|
+
// is called by `_ssrRenderSlot`.
|
|
33946
|
+
fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
|
|
33947
|
+
}
|
|
33948
|
+
// component is inside a slot, inherit slot scope Id
|
|
33949
|
+
if (context.withSlotScopeId) {
|
|
33950
|
+
node.ssrCodegenNode.arguments.push(`_scopeId`);
|
|
33951
|
+
}
|
|
33952
|
+
if (typeof component === 'string') {
|
|
33953
|
+
// static component
|
|
33954
|
+
context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
|
|
33955
|
+
}
|
|
33956
|
+
else {
|
|
33957
|
+
// dynamic component (`resolveDynamicComponent` call)
|
|
33958
|
+
// the codegen node is a `renderVNode` call
|
|
33959
|
+
context.pushStatement(node.ssrCodegenNode);
|
|
33960
|
+
}
|
|
33961
|
+
}
|
|
33962
|
+
}
|
|
33963
|
+
const rawOptionsMap = new WeakMap();
|
|
33964
|
+
const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
|
|
33965
|
+
const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
|
|
33966
|
+
const vnodeDirectiveTransforms = Object.assign(Object.assign({}, baseDirectiveTransforms), DOMDirectiveTransforms);
|
|
33967
|
+
function createVNodeSlotBranch(props, children, parentContext) {
|
|
33968
|
+
// apply a sub-transform using vnode-based transforms.
|
|
33969
|
+
const rawOptions = rawOptionsMap.get(parentContext.root);
|
|
33970
|
+
const subOptions = Object.assign(Object.assign({}, rawOptions), {
|
|
33971
|
+
// overwrite with vnode-based transforms
|
|
33972
|
+
nodeTransforms: [
|
|
33973
|
+
...vnodeNodeTransforms,
|
|
33974
|
+
...(rawOptions.nodeTransforms || [])
|
|
33975
|
+
], directiveTransforms: Object.assign(Object.assign({}, vnodeDirectiveTransforms), (rawOptions.directiveTransforms || {})) });
|
|
33976
|
+
// wrap the children with a wrapper template for proper children treatment.
|
|
33977
|
+
const wrapperNode = {
|
|
33978
|
+
type: 1 /* ELEMENT */,
|
|
33979
|
+
ns: 0 /* HTML */,
|
|
33980
|
+
tag: 'template',
|
|
33981
|
+
tagType: 3 /* TEMPLATE */,
|
|
33982
|
+
isSelfClosing: false,
|
|
33983
|
+
// important: provide v-slot="props" on the wrapper for proper
|
|
33984
|
+
// scope analysis
|
|
33985
|
+
props: [
|
|
33986
|
+
{
|
|
33987
|
+
type: 7 /* DIRECTIVE */,
|
|
33988
|
+
name: 'slot',
|
|
33989
|
+
exp: props,
|
|
33990
|
+
arg: undefined,
|
|
33991
|
+
modifiers: [],
|
|
33992
|
+
loc: locStub
|
|
33993
|
+
}
|
|
33994
|
+
],
|
|
33995
|
+
children,
|
|
33996
|
+
loc: locStub,
|
|
33997
|
+
codegenNode: undefined
|
|
33998
|
+
};
|
|
33999
|
+
subTransform(wrapperNode, subOptions, parentContext);
|
|
34000
|
+
return createReturnStatement(children);
|
|
34001
|
+
}
|
|
34002
|
+
function subTransform(node, options, parentContext) {
|
|
34003
|
+
const childRoot = createRoot([node]);
|
|
34004
|
+
const childContext = createTransformContext(childRoot, options);
|
|
34005
|
+
// this sub transform is for vnode fallback branch so it should be handled
|
|
34006
|
+
// like normal render functions
|
|
34007
|
+
childContext.ssr = false;
|
|
34008
|
+
// inherit parent scope analysis state
|
|
34009
|
+
childContext.scopes = Object.assign({}, parentContext.scopes);
|
|
34010
|
+
childContext.identifiers = Object.assign({}, parentContext.identifiers);
|
|
34011
|
+
childContext.imports = parentContext.imports;
|
|
34012
|
+
// traverse
|
|
34013
|
+
traverseNode(childRoot, childContext);
|
|
34014
|
+
['helpers', 'components', 'directives'].forEach(key => {
|
|
34015
|
+
childContext[key].forEach((value, helperKey) => {
|
|
34016
|
+
if (key === 'helpers') {
|
|
34017
|
+
const parentCount = parentContext.helpers.get(helperKey);
|
|
34018
|
+
if (parentCount === undefined) {
|
|
34019
|
+
parentContext.helpers.set(helperKey, value);
|
|
34020
|
+
}
|
|
34021
|
+
else {
|
|
34022
|
+
parentContext.helpers.set(helperKey, value + parentCount);
|
|
34023
|
+
}
|
|
34024
|
+
}
|
|
34025
|
+
else {
|
|
34026
|
+
parentContext[key].add(value);
|
|
34027
|
+
}
|
|
34028
|
+
});
|
|
34029
|
+
});
|
|
34030
|
+
// imports/hoists are not merged because:
|
|
34031
|
+
// - imports are only used for asset urls and should be consistent between
|
|
34032
|
+
// node/client branches
|
|
34033
|
+
// - hoists are not enabled for the client branch here
|
|
34034
|
+
}
|
|
34035
|
+
function clone(v) {
|
|
34036
|
+
if (isArray(v)) {
|
|
34037
|
+
return v.map(clone);
|
|
34038
|
+
}
|
|
34039
|
+
else if (isObject(v)) {
|
|
34040
|
+
const res = {};
|
|
34041
|
+
for (const key in v) {
|
|
34042
|
+
res[key] = clone(v[key]);
|
|
34043
|
+
}
|
|
34044
|
+
return res;
|
|
34045
|
+
}
|
|
34046
|
+
else {
|
|
34047
|
+
return v;
|
|
34048
|
+
}
|
|
34049
|
+
}
|
|
34050
|
+
|
|
33992
34051
|
// Because SSR codegen output is completely different from client-side output
|
|
33993
34052
|
// (e.g. multiple elements can be concatenated into a single template literal
|
|
33994
34053
|
// instead of each getting a corresponding call), we need to apply an extra
|
|
@@ -34764,6 +34823,15 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
|
|
|
34764
34823
|
stmt.left.type === 'VariableDeclaration') {
|
|
34765
34824
|
walkVariableDeclaration(stmt.left);
|
|
34766
34825
|
}
|
|
34826
|
+
else if (stmt.type === 'ExportNamedDeclaration' &&
|
|
34827
|
+
stmt.declaration &&
|
|
34828
|
+
stmt.declaration.type === 'VariableDeclaration') {
|
|
34829
|
+
walkVariableDeclaration(stmt.declaration, isRoot);
|
|
34830
|
+
}
|
|
34831
|
+
else if (stmt.type === 'LabeledStatement' &&
|
|
34832
|
+
stmt.body.type === 'VariableDeclaration') {
|
|
34833
|
+
walkVariableDeclaration(stmt.body, isRoot);
|
|
34834
|
+
}
|
|
34767
34835
|
}
|
|
34768
34836
|
}
|
|
34769
34837
|
function walkVariableDeclaration(stmt, isRoot = false) {
|
|
@@ -35042,6 +35110,7 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
|
|
|
35042
35110
|
walkScope(node);
|
|
35043
35111
|
return;
|
|
35044
35112
|
}
|
|
35113
|
+
// skip type nodes
|
|
35045
35114
|
if (parent &&
|
|
35046
35115
|
parent.type.startsWith('TS') &&
|
|
35047
35116
|
parent.type !== 'TSAsExpression' &&
|
|
@@ -35141,7 +35210,7 @@ function compileScript(sfc, options) {
|
|
|
35141
35210
|
let { script, scriptSetup, source, filename } = sfc;
|
|
35142
35211
|
// feature flags
|
|
35143
35212
|
// TODO remove support for deprecated options when out of experimental
|
|
35144
|
-
const
|
|
35213
|
+
const enableReactivityTransform = !!options.reactivityTransform ||
|
|
35145
35214
|
!!options.refSugar ||
|
|
35146
35215
|
!!options.refTransform;
|
|
35147
35216
|
const enablePropsTransform = !!options.reactivityTransform || !!options.propsDestructureTransform;
|
|
@@ -35161,6 +35230,7 @@ function compileScript(sfc, options) {
|
|
|
35161
35230
|
scriptLang === 'tsx' ||
|
|
35162
35231
|
scriptSetupLang === 'ts' ||
|
|
35163
35232
|
scriptSetupLang === 'tsx';
|
|
35233
|
+
// resolve parser plugins
|
|
35164
35234
|
const plugins = [];
|
|
35165
35235
|
if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
|
|
35166
35236
|
plugins.push('jsx');
|
|
@@ -35185,7 +35255,7 @@ function compileScript(sfc, options) {
|
|
|
35185
35255
|
sourceType: 'module'
|
|
35186
35256
|
}).program;
|
|
35187
35257
|
const bindings = analyzeScriptBindings(scriptAst.body);
|
|
35188
|
-
if (
|
|
35258
|
+
if (enableReactivityTransform && shouldTransform(content)) {
|
|
35189
35259
|
const s = new MagicString(source);
|
|
35190
35260
|
const startOffset = script.loc.start.offset;
|
|
35191
35261
|
const endOffset = script.loc.end.offset;
|
|
@@ -35652,10 +35722,10 @@ function compileScript(sfc, options) {
|
|
|
35652
35722
|
walkDeclaration(node, scriptBindings, userImportAlias);
|
|
35653
35723
|
}
|
|
35654
35724
|
}
|
|
35655
|
-
// apply
|
|
35656
|
-
if (
|
|
35657
|
-
const { rootRefs
|
|
35658
|
-
refBindings =
|
|
35725
|
+
// apply reactivity transform
|
|
35726
|
+
if (enableReactivityTransform && shouldTransform(script.content)) {
|
|
35727
|
+
const { rootRefs, importedHelpers } = transformAST(scriptAst, s, scriptStartOffset);
|
|
35728
|
+
refBindings = rootRefs;
|
|
35659
35729
|
for (const h of importedHelpers) {
|
|
35660
35730
|
helperImports.add(h);
|
|
35661
35731
|
}
|
|
@@ -35840,8 +35910,10 @@ function compileScript(sfc, options) {
|
|
|
35840
35910
|
}
|
|
35841
35911
|
}
|
|
35842
35912
|
}
|
|
35843
|
-
// 3. Apply
|
|
35844
|
-
if ((
|
|
35913
|
+
// 3. Apply reactivity transform
|
|
35914
|
+
if ((enableReactivityTransform &&
|
|
35915
|
+
// normal <script> had ref bindings that maybe used in <script setup>
|
|
35916
|
+
(refBindings || shouldTransform(scriptSetup.content))) ||
|
|
35845
35917
|
propsDestructureDecl) {
|
|
35846
35918
|
const { rootRefs, importedHelpers } = transformAST(scriptSetupAst, s, startOffset, refBindings, propsDestructuredBindings);
|
|
35847
35919
|
refBindings = refBindings ? [...refBindings, ...rootRefs] : rootRefs;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vue/compiler-sfc",
|
|
3
|
-
"version": "3.2.
|
|
3
|
+
"version": "3.2.31",
|
|
4
4
|
"description": "@vue/compiler-sfc",
|
|
5
5
|
"main": "dist/compiler-sfc.cjs.js",
|
|
6
6
|
"module": "dist/compiler-sfc.esm-browser.js",
|
|
@@ -19,7 +19,7 @@
|
|
|
19
19
|
},
|
|
20
20
|
"repository": {
|
|
21
21
|
"type": "git",
|
|
22
|
-
"url": "git+https://github.com/vuejs/
|
|
22
|
+
"url": "git+https://github.com/vuejs/core.git",
|
|
23
23
|
"directory": "packages/compiler-sfc"
|
|
24
24
|
},
|
|
25
25
|
"keywords": [
|
|
@@ -28,16 +28,16 @@
|
|
|
28
28
|
"author": "Evan You",
|
|
29
29
|
"license": "MIT",
|
|
30
30
|
"bugs": {
|
|
31
|
-
"url": "https://github.com/vuejs/
|
|
31
|
+
"url": "https://github.com/vuejs/core/issues"
|
|
32
32
|
},
|
|
33
|
-
"homepage": "https://github.com/vuejs/
|
|
33
|
+
"homepage": "https://github.com/vuejs/core/tree/main/packages/compiler-sfc#readme",
|
|
34
34
|
"dependencies": {
|
|
35
35
|
"@babel/parser": "^7.16.4",
|
|
36
|
-
"@vue/compiler-core": "3.2.
|
|
37
|
-
"@vue/compiler-dom": "3.2.
|
|
38
|
-
"@vue/compiler-ssr": "3.2.
|
|
39
|
-
"@vue/reactivity-transform": "3.2.
|
|
40
|
-
"@vue/shared": "3.2.
|
|
36
|
+
"@vue/compiler-core": "3.2.31",
|
|
37
|
+
"@vue/compiler-dom": "3.2.31",
|
|
38
|
+
"@vue/compiler-ssr": "3.2.31",
|
|
39
|
+
"@vue/reactivity-transform": "3.2.31",
|
|
40
|
+
"@vue/shared": "3.2.31",
|
|
41
41
|
"estree-walker": "^2.0.2",
|
|
42
42
|
"magic-string": "^0.25.7",
|
|
43
43
|
"source-map": "^0.6.1",
|