@vue/compiler-sfc 3.2.26 → 3.2.30

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.
@@ -109,7 +109,8 @@ function sum (o) {
109
109
  var hashSum = sum;
110
110
 
111
111
  const CSS_VARS_HELPER = `useCssVars`;
112
- const cssVarRE = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g;
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] || match[2] || match[3];
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, $2, $3) => {
149
- return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`;
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 enableRefTransform = !!options.reactivityTransform ||
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 (enableRefTransform && reactivityTransform.shouldTransform(content)) {
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 ref transform
3803
- if (enableRefTransform && reactivityTransform.shouldTransform(script.content)) {
3804
- const { rootRefs: rootVars, importedHelpers } = reactivityTransform.transformAST(scriptAst, s, scriptStartOffset);
3805
- refBindings = rootVars;
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 ref sugar transform
3991
- if ((enableRefTransform && reactivityTransform.shouldTransform(scriptSetup.content)) ||
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;
@@ -208,7 +208,7 @@ export declare interface SFCScriptCompileOptions {
208
208
  */
209
209
  propsDestructureTransform?: boolean;
210
210
  /**
211
- * @deprecated use `refTransform` instead.
211
+ * @deprecated use `reactivityTransform` instead.
212
212
  */
213
213
  refSugar?: boolean;
214
214
  /**
@@ -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 == null
355
- ? ''
356
- : isArray(val) ||
357
- (isObject(val) &&
358
- (val.toString === objectToString || !isFunction(val.toString)))
359
- ? JSON.stringify(val, replacer, 2)
360
- : String(val);
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/guide/migration/custom-elements-interop.html`
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/guide/migration/v-model.html`
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/guide/migration/v-bind.html`
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/guide/migration/v-on-native-modifier-removed.html`
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/guide/migration/v-if-v-for.html`
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/guide/migration/inline-template-attribute.html`
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/guide/migration/filters.html`
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/vue-next/issues/4251
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.indexOf('&') === -1) {
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 = { somePropert: NODE }
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 (context.prefixIdentifiers &&
22719
- keyProperty &&
22720
- keyProp.type !== 6 /* ATTRIBUTE */) {
22721
- // #2085 process :key expression needs to be processed in order for it
22722
- // to behave consistently for <template v-for> and <div v-for>.
22723
- // In the case of `<template v-for>`, the node is discarded and never
22724
- // traversed so its key expression won't be processed by the normal
22725
- // transforms.
22726
- keyProperty.value = processExpression(keyProperty.value, context);
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
- const cssVarRE = /\bv-bind\(\s*(?:'([^']+)'|"([^"]+)"|([^'"][^)]*))\s*\)/g;
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] || match[2] || match[3];
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, $2, $3) => {
27688
- return `var(--${genVarName(id, $1 || $2 || $3, isProd)})`;
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!
@@ -33404,17 +33433,16 @@ function createSSRCompilerError(code, loc) {
33404
33433
  return createCompilerError(code, loc, SSRErrorMessages);
33405
33434
  }
33406
33435
  const SSRErrorMessages = {
33407
- [61 /* X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM */]: `Custom directive is missing corresponding SSR transform and will be ignored.`,
33408
- [62 /* X_SSR_UNSAFE_ATTR_NAME */]: `Unsafe attribute name for SSR.`,
33409
- [63 /* X_SSR_NO_TELEPORT_TARGET */]: `Missing the 'to' prop on teleport element.`,
33410
- [64 /* X_SSR_INVALID_AST_NODE */]: `Invalid AST node during SSR transform.`
33436
+ [61 /* X_SSR_UNSAFE_ATTR_NAME */]: `Unsafe attribute name for SSR.`,
33437
+ [62 /* X_SSR_NO_TELEPORT_TARGET */]: `Missing the 'to' prop on teleport element.`,
33438
+ [63 /* X_SSR_INVALID_AST_NODE */]: `Invalid AST node during SSR transform.`
33411
33439
  };
33412
33440
 
33413
33441
  // Note: this is a 2nd-pass codegen transform.
33414
33442
  function ssrProcessTeleport(node, context) {
33415
33443
  const targetProp = findProp(node, 'to');
33416
33444
  if (!targetProp) {
33417
- context.onError(createSSRCompilerError(63 /* X_SSR_NO_TELEPORT_TARGET */, node.loc));
33445
+ context.onError(createSSRCompilerError(62 /* X_SSR_NO_TELEPORT_TARGET */, node.loc));
33418
33446
  return;
33419
33447
  }
33420
33448
  let target;
@@ -33426,7 +33454,7 @@ function ssrProcessTeleport(node, context) {
33426
33454
  target = targetProp.exp;
33427
33455
  }
33428
33456
  if (!target) {
33429
- context.onError(createSSRCompilerError(63 /* X_SSR_NO_TELEPORT_TARGET */, targetProp.loc));
33457
+ context.onError(createSSRCompilerError(62 /* X_SSR_NO_TELEPORT_TARGET */, targetProp.loc));
33430
33458
  return;
33431
33459
  }
33432
33460
  const disabledProp = findProp(node, 'disabled', false, true /* allow empty */);
@@ -33525,224 +33553,6 @@ function ssrProcessTransitionGroup(node, context) {
33525
33553
  }
33526
33554
  }
33527
33555
 
33528
- // We need to construct the slot functions in the 1st pass to ensure proper
33529
- // scope tracking, but the children of each slot cannot be processed until
33530
- // the 2nd pass, so we store the WIP slot functions in a weakmap during the 1st
33531
- // pass and complete them in the 2nd pass.
33532
- const wipMap$1 = new WeakMap();
33533
- const componentTypeMap = new WeakMap();
33534
- // ssr component transform is done in two phases:
33535
- // In phase 1. we use `buildSlot` to analyze the children of the component into
33536
- // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
33537
- // the core transform context).
33538
- // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
33539
- // nodes.
33540
- const ssrTransformComponent = (node, context) => {
33541
- if (node.type !== 1 /* ELEMENT */ ||
33542
- node.tagType !== 1 /* COMPONENT */) {
33543
- return;
33544
- }
33545
- const component = resolveComponentType(node, context, true /* ssr */);
33546
- componentTypeMap.set(node, component);
33547
- if (isSymbol(component)) {
33548
- if (component === SUSPENSE) {
33549
- return ssrTransformSuspense(node, context);
33550
- }
33551
- return; // built-in component: fallthrough
33552
- }
33553
- // Build the fallback vnode-based branch for the component's slots.
33554
- // We need to clone the node into a fresh copy and use the buildSlots' logic
33555
- // to get access to the children of each slot. We then compile them with
33556
- // a child transform pipeline using vnode-based transforms (instead of ssr-
33557
- // based ones), and save the result branch (a ReturnStatement) in an array.
33558
- // The branch is retrieved when processing slots again in ssr mode.
33559
- const vnodeBranches = [];
33560
- const clonedNode = clone(node);
33561
- return function ssrPostTransformComponent() {
33562
- // Using the cloned node, build the normal VNode-based branches (for
33563
- // fallback in case the child is render-fn based). Store them in an array
33564
- // for later use.
33565
- if (clonedNode.children.length) {
33566
- buildSlots(clonedNode, context, (props, children) => {
33567
- vnodeBranches.push(createVNodeSlotBranch(props, children, context));
33568
- return createFunctionExpression(undefined);
33569
- });
33570
- }
33571
- const props = node.props.length > 0
33572
- ? // note we are not passing ssr: true here because for components, v-on
33573
- // handlers should still be passed
33574
- buildProps(node, context).props || `null`
33575
- : `null`;
33576
- const wipEntries = [];
33577
- wipMap$1.set(node, wipEntries);
33578
- const buildSSRSlotFn = (props, children, loc) => {
33579
- const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
33580
- true, // newline
33581
- true, // isSlot
33582
- loc);
33583
- wipEntries.push({
33584
- fn,
33585
- children,
33586
- // also collect the corresponding vnode branch built earlier
33587
- vnodeBranch: vnodeBranches[wipEntries.length]
33588
- });
33589
- return fn;
33590
- };
33591
- const slots = node.children.length
33592
- ? buildSlots(node, context, buildSSRSlotFn).slots
33593
- : `null`;
33594
- if (typeof component !== 'string') {
33595
- // dynamic component that resolved to a `resolveDynamicComponent` call
33596
- // expression - since the resolved result may be a plain element (string)
33597
- // or a VNode, handle it with `renderVNode`.
33598
- node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
33599
- `_push`,
33600
- createCallExpression(context.helper(CREATE_VNODE), [
33601
- component,
33602
- props,
33603
- slots
33604
- ]),
33605
- `_parent`
33606
- ]);
33607
- }
33608
- else {
33609
- node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, props, slots, `_parent`]);
33610
- }
33611
- };
33612
- };
33613
- function ssrProcessComponent(node, context) {
33614
- const component = componentTypeMap.get(node);
33615
- if (!node.ssrCodegenNode) {
33616
- // this is a built-in component that fell-through.
33617
- if (component === TELEPORT) {
33618
- return ssrProcessTeleport(node, context);
33619
- }
33620
- else if (component === SUSPENSE) {
33621
- return ssrProcessSuspense(node, context);
33622
- }
33623
- else if (component === TRANSITION_GROUP) {
33624
- return ssrProcessTransitionGroup(node, context);
33625
- }
33626
- else {
33627
- // real fall-through: Transition / KeepAlive
33628
- // just render its children.
33629
- processChildren(node.children, context);
33630
- }
33631
- }
33632
- else {
33633
- // finish up slot function expressions from the 1st pass.
33634
- const wipEntries = wipMap$1.get(node) || [];
33635
- for (let i = 0; i < wipEntries.length; i++) {
33636
- const { fn, children, vnodeBranch } = wipEntries[i];
33637
- // For each slot, we generate two branches: one SSR-optimized branch and
33638
- // one normal vnode-based branch. The branches are taken based on the
33639
- // presence of the 2nd `_push` argument (which is only present if the slot
33640
- // is called by `_ssrRenderSlot`.
33641
- fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
33642
- }
33643
- // component is inside a slot, inherit slot scope Id
33644
- if (context.withSlotScopeId) {
33645
- node.ssrCodegenNode.arguments.push(`_scopeId`);
33646
- }
33647
- if (typeof component === 'string') {
33648
- // static component
33649
- context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
33650
- }
33651
- else {
33652
- // dynamic component (`resolveDynamicComponent` call)
33653
- // the codegen node is a `renderVNode` call
33654
- context.pushStatement(node.ssrCodegenNode);
33655
- }
33656
- }
33657
- }
33658
- const rawOptionsMap = new WeakMap();
33659
- const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
33660
- const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
33661
- const vnodeDirectiveTransforms = Object.assign(Object.assign({}, baseDirectiveTransforms), DOMDirectiveTransforms);
33662
- function createVNodeSlotBranch(props, children, parentContext) {
33663
- // apply a sub-transform using vnode-based transforms.
33664
- const rawOptions = rawOptionsMap.get(parentContext.root);
33665
- const subOptions = Object.assign(Object.assign({}, rawOptions), {
33666
- // overwrite with vnode-based transforms
33667
- nodeTransforms: [
33668
- ...vnodeNodeTransforms,
33669
- ...(rawOptions.nodeTransforms || [])
33670
- ], directiveTransforms: Object.assign(Object.assign({}, vnodeDirectiveTransforms), (rawOptions.directiveTransforms || {})) });
33671
- // wrap the children with a wrapper template for proper children treatment.
33672
- const wrapperNode = {
33673
- type: 1 /* ELEMENT */,
33674
- ns: 0 /* HTML */,
33675
- tag: 'template',
33676
- tagType: 3 /* TEMPLATE */,
33677
- isSelfClosing: false,
33678
- // important: provide v-slot="props" on the wrapper for proper
33679
- // scope analysis
33680
- props: [
33681
- {
33682
- type: 7 /* DIRECTIVE */,
33683
- name: 'slot',
33684
- exp: props,
33685
- arg: undefined,
33686
- modifiers: [],
33687
- loc: locStub
33688
- }
33689
- ],
33690
- children,
33691
- loc: locStub,
33692
- codegenNode: undefined
33693
- };
33694
- subTransform(wrapperNode, subOptions, parentContext);
33695
- return createReturnStatement(children);
33696
- }
33697
- function subTransform(node, options, parentContext) {
33698
- const childRoot = createRoot([node]);
33699
- const childContext = createTransformContext(childRoot, options);
33700
- // this sub transform is for vnode fallback branch so it should be handled
33701
- // like normal render functions
33702
- childContext.ssr = false;
33703
- // inherit parent scope analysis state
33704
- childContext.scopes = Object.assign({}, parentContext.scopes);
33705
- childContext.identifiers = Object.assign({}, parentContext.identifiers);
33706
- childContext.imports = parentContext.imports;
33707
- // traverse
33708
- traverseNode(childRoot, childContext);
33709
- ['helpers', 'components', 'directives'].forEach(key => {
33710
- childContext[key].forEach((value, helperKey) => {
33711
- if (key === 'helpers') {
33712
- const parentCount = parentContext.helpers.get(helperKey);
33713
- if (parentCount === undefined) {
33714
- parentContext.helpers.set(helperKey, value);
33715
- }
33716
- else {
33717
- parentContext.helpers.set(helperKey, value + parentCount);
33718
- }
33719
- }
33720
- else {
33721
- parentContext[key].add(value);
33722
- }
33723
- });
33724
- });
33725
- // imports/hoists are not merged because:
33726
- // - imports are only used for asset urls and should be consistent between
33727
- // node/client branches
33728
- // - hoists are not enabled for the client branch here
33729
- }
33730
- function clone(v) {
33731
- if (isArray(v)) {
33732
- return v.map(clone);
33733
- }
33734
- else if (isObject(v)) {
33735
- const res = {};
33736
- for (const key in v) {
33737
- res[key] = clone(v[key]);
33738
- }
33739
- return res;
33740
- }
33741
- else {
33742
- return v;
33743
- }
33744
- }
33745
-
33746
33556
  // for directives with children overwrite (e.g. v-html & v-text), we need to
33747
33557
  // store the raw children so that they can be added in the 2nd pass.
33748
33558
  const rawChildrenMap = new WeakMap();
@@ -33757,14 +33567,17 @@ const ssrTransformElement = (node, context) => {
33757
33567
  const openTag = [`<${node.tag}`];
33758
33568
  // some tags need to be passed to runtime for special checks
33759
33569
  const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
33760
- // v-bind="obj" or v-bind:[key] can potentially overwrite other static
33761
- // attrs and can affect final rendering result, so when they are present
33762
- // 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`
33763
33573
  const hasDynamicVBind = hasDynamicKeyVBind(node);
33764
- if (hasDynamicVBind) {
33765
- const { props } = buildProps(node, context, node.props, true /* ssr */);
33766
- if (props) {
33767
- const propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [props]);
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]);
33768
33581
  if (node.tag === 'textarea') {
33769
33582
  const existingText = node.children[0];
33770
33583
  // If interpolation, this is dynamic <textarea> content, potentially
@@ -33776,7 +33589,7 @@ const ssrTransformElement = (node, context) => {
33776
33589
  // it contains value (if yes, render is as children).
33777
33590
  const tempId = `_temp${context.temps++}`;
33778
33591
  propsExp.arguments = [
33779
- createAssignmentExpression(createSimpleExpression(tempId, false), props)
33592
+ createAssignmentExpression(createSimpleExpression(tempId, false), mergedProps)
33780
33593
  ];
33781
33594
  rawChildrenMap.set(node, createCallExpression(context.helper(SSR_INTERPOLATE), [
33782
33595
  createConditionalExpression(createSimpleExpression(`"value" in ${tempId}`, false), createSimpleExpression(`${tempId}.value`, false), createSimpleExpression(existingText ? existingText.content : ``, true), false)
@@ -33794,7 +33607,7 @@ const ssrTransformElement = (node, context) => {
33794
33607
  const tempExp = createSimpleExpression(tempId, false);
33795
33608
  propsExp.arguments = [
33796
33609
  createSequenceExpression([
33797
- createAssignmentExpression(tempExp, props),
33610
+ createAssignmentExpression(tempExp, mergedProps),
33798
33611
  createCallExpression(context.helper(MERGE_PROPS), [
33799
33612
  tempExp,
33800
33613
  createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
@@ -33836,18 +33649,14 @@ const ssrTransformElement = (node, context) => {
33836
33649
  context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, prop.loc));
33837
33650
  }
33838
33651
  else if (isTextareaWithValue(node, prop) && prop.exp) {
33839
- if (!hasDynamicVBind) {
33652
+ if (!needMergeProps) {
33840
33653
  node.children = [createInterpolation(prop.exp, prop.loc)];
33841
33654
  }
33842
33655
  }
33843
- else {
33656
+ else if (!needMergeProps) {
33844
33657
  // Directive transforms.
33845
33658
  const directiveTransform = context.directiveTransforms[prop.name];
33846
- if (!directiveTransform) {
33847
- // no corresponding ssr directive transform found.
33848
- context.onError(createSSRCompilerError(61 /* X_SSR_CUSTOM_DIRECTIVE_NO_TRANSFORM */, prop.loc));
33849
- }
33850
- else if (!hasDynamicVBind) {
33659
+ if (directiveTransform) {
33851
33660
  const { props, ssrTagParts } = directiveTransform(prop, node, context);
33852
33661
  if (ssrTagParts) {
33853
33662
  openTag.push(...ssrTagParts);
@@ -33887,7 +33696,7 @@ const ssrTransformElement = (node, context) => {
33887
33696
  ]));
33888
33697
  }
33889
33698
  else {
33890
- context.onError(createSSRCompilerError(62 /* X_SSR_UNSAFE_ATTR_NAME */, key.loc));
33699
+ context.onError(createSSRCompilerError(61 /* X_SSR_UNSAFE_ATTR_NAME */, key.loc));
33891
33700
  }
33892
33701
  }
33893
33702
  }
@@ -33910,7 +33719,7 @@ const ssrTransformElement = (node, context) => {
33910
33719
  if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
33911
33720
  rawChildrenMap.set(node, escapeHtml(prop.value.content));
33912
33721
  }
33913
- else if (!hasDynamicVBind) {
33722
+ else if (!needMergeProps) {
33914
33723
  if (prop.name === 'key' || prop.name === 'ref') {
33915
33724
  continue;
33916
33725
  }
@@ -33934,6 +33743,30 @@ const ssrTransformElement = (node, context) => {
33934
33743
  node.ssrCodegenNode = createTemplateLiteral(openTag);
33935
33744
  };
33936
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
+ context.directives.add(dir.name);
33760
+ mergePropsArgs.push(createCallExpression(context.helper(SSR_GET_DIRECTIVE_PROPS), [
33761
+ `_ctx`,
33762
+ ...buildDirectiveArgs(dir, context).elements
33763
+ ]));
33764
+ }
33765
+ }
33766
+ return mergePropsArgs.length > 1
33767
+ ? createCallExpression(context.helper(MERGE_PROPS), mergePropsArgs)
33768
+ : mergePropsArgs[0];
33769
+ }
33937
33770
  function isTrueFalseValue(prop) {
33938
33771
  if (prop.type === 7 /* DIRECTIVE */) {
33939
33772
  return (prop.name === 'bind' &&
@@ -33994,6 +33827,228 @@ function ssrProcessElement(node, context) {
33994
33827
  }
33995
33828
  }
33996
33829
 
33830
+ // We need to construct the slot functions in the 1st pass to ensure proper
33831
+ // scope tracking, but the children of each slot cannot be processed until
33832
+ // the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
33833
+ // pass and complete them in the 2nd pass.
33834
+ const wipMap$1 = new WeakMap();
33835
+ const componentTypeMap = new WeakMap();
33836
+ // ssr component transform is done in two phases:
33837
+ // In phase 1. we use `buildSlot` to analyze the children of the component into
33838
+ // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
33839
+ // the core transform context).
33840
+ // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
33841
+ // nodes.
33842
+ const ssrTransformComponent = (node, context) => {
33843
+ if (node.type !== 1 /* ELEMENT */ ||
33844
+ node.tagType !== 1 /* COMPONENT */) {
33845
+ return;
33846
+ }
33847
+ const component = resolveComponentType(node, context, true /* ssr */);
33848
+ componentTypeMap.set(node, component);
33849
+ if (isSymbol(component)) {
33850
+ if (component === SUSPENSE) {
33851
+ return ssrTransformSuspense(node, context);
33852
+ }
33853
+ return; // built-in component: fallthrough
33854
+ }
33855
+ // Build the fallback vnode-based branch for the component's slots.
33856
+ // We need to clone the node into a fresh copy and use the buildSlots' logic
33857
+ // to get access to the children of each slot. We then compile them with
33858
+ // a child transform pipeline using vnode-based transforms (instead of ssr-
33859
+ // based ones), and save the result branch (a ReturnStatement) in an array.
33860
+ // The branch is retrieved when processing slots again in ssr mode.
33861
+ const vnodeBranches = [];
33862
+ const clonedNode = clone(node);
33863
+ return function ssrPostTransformComponent() {
33864
+ // Using the cloned node, build the normal VNode-based branches (for
33865
+ // fallback in case the child is render-fn based). Store them in an array
33866
+ // for later use.
33867
+ if (clonedNode.children.length) {
33868
+ buildSlots(clonedNode, context, (props, children) => {
33869
+ vnodeBranches.push(createVNodeSlotBranch(props, children, context));
33870
+ return createFunctionExpression(undefined);
33871
+ });
33872
+ }
33873
+ let propsExp = `null`;
33874
+ if (node.props.length) {
33875
+ // note we are not passing ssr: true here because for components, v-on
33876
+ // handlers should still be passed
33877
+ const { props, directives } = buildProps(node, context);
33878
+ if (props || directives.length) {
33879
+ propsExp = buildSSRProps(props, directives, context);
33880
+ }
33881
+ }
33882
+ const wipEntries = [];
33883
+ wipMap$1.set(node, wipEntries);
33884
+ const buildSSRSlotFn = (props, children, loc) => {
33885
+ const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
33886
+ true, // newline
33887
+ true, // isSlot
33888
+ loc);
33889
+ wipEntries.push({
33890
+ fn,
33891
+ children,
33892
+ // also collect the corresponding vnode branch built earlier
33893
+ vnodeBranch: vnodeBranches[wipEntries.length]
33894
+ });
33895
+ return fn;
33896
+ };
33897
+ const slots = node.children.length
33898
+ ? buildSlots(node, context, buildSSRSlotFn).slots
33899
+ : `null`;
33900
+ if (typeof component !== 'string') {
33901
+ // dynamic component that resolved to a `resolveDynamicComponent` call
33902
+ // expression - since the resolved result may be a plain element (string)
33903
+ // or a VNode, handle it with `renderVNode`.
33904
+ node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
33905
+ `_push`,
33906
+ createCallExpression(context.helper(CREATE_VNODE), [
33907
+ component,
33908
+ propsExp,
33909
+ slots
33910
+ ]),
33911
+ `_parent`
33912
+ ]);
33913
+ }
33914
+ else {
33915
+ node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, propsExp, slots, `_parent`]);
33916
+ }
33917
+ };
33918
+ };
33919
+ function ssrProcessComponent(node, context) {
33920
+ const component = componentTypeMap.get(node);
33921
+ if (!node.ssrCodegenNode) {
33922
+ // this is a built-in component that fell-through.
33923
+ if (component === TELEPORT) {
33924
+ return ssrProcessTeleport(node, context);
33925
+ }
33926
+ else if (component === SUSPENSE) {
33927
+ return ssrProcessSuspense(node, context);
33928
+ }
33929
+ else if (component === TRANSITION_GROUP) {
33930
+ return ssrProcessTransitionGroup(node, context);
33931
+ }
33932
+ else {
33933
+ // real fall-through: Transition / KeepAlive
33934
+ // just render its children.
33935
+ processChildren(node.children, context);
33936
+ }
33937
+ }
33938
+ else {
33939
+ // finish up slot function expressions from the 1st pass.
33940
+ const wipEntries = wipMap$1.get(node) || [];
33941
+ for (let i = 0; i < wipEntries.length; i++) {
33942
+ const { fn, children, vnodeBranch } = wipEntries[i];
33943
+ // For each slot, we generate two branches: one SSR-optimized branch and
33944
+ // one normal vnode-based branch. The branches are taken based on the
33945
+ // presence of the 2nd `_push` argument (which is only present if the slot
33946
+ // is called by `_ssrRenderSlot`.
33947
+ fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
33948
+ }
33949
+ // component is inside a slot, inherit slot scope Id
33950
+ if (context.withSlotScopeId) {
33951
+ node.ssrCodegenNode.arguments.push(`_scopeId`);
33952
+ }
33953
+ if (typeof component === 'string') {
33954
+ // static component
33955
+ context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
33956
+ }
33957
+ else {
33958
+ // dynamic component (`resolveDynamicComponent` call)
33959
+ // the codegen node is a `renderVNode` call
33960
+ context.pushStatement(node.ssrCodegenNode);
33961
+ }
33962
+ }
33963
+ }
33964
+ const rawOptionsMap = new WeakMap();
33965
+ const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
33966
+ const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
33967
+ const vnodeDirectiveTransforms = Object.assign(Object.assign({}, baseDirectiveTransforms), DOMDirectiveTransforms);
33968
+ function createVNodeSlotBranch(props, children, parentContext) {
33969
+ // apply a sub-transform using vnode-based transforms.
33970
+ const rawOptions = rawOptionsMap.get(parentContext.root);
33971
+ const subOptions = Object.assign(Object.assign({}, rawOptions), {
33972
+ // overwrite with vnode-based transforms
33973
+ nodeTransforms: [
33974
+ ...vnodeNodeTransforms,
33975
+ ...(rawOptions.nodeTransforms || [])
33976
+ ], directiveTransforms: Object.assign(Object.assign({}, vnodeDirectiveTransforms), (rawOptions.directiveTransforms || {})) });
33977
+ // wrap the children with a wrapper template for proper children treatment.
33978
+ const wrapperNode = {
33979
+ type: 1 /* ELEMENT */,
33980
+ ns: 0 /* HTML */,
33981
+ tag: 'template',
33982
+ tagType: 3 /* TEMPLATE */,
33983
+ isSelfClosing: false,
33984
+ // important: provide v-slot="props" on the wrapper for proper
33985
+ // scope analysis
33986
+ props: [
33987
+ {
33988
+ type: 7 /* DIRECTIVE */,
33989
+ name: 'slot',
33990
+ exp: props,
33991
+ arg: undefined,
33992
+ modifiers: [],
33993
+ loc: locStub
33994
+ }
33995
+ ],
33996
+ children,
33997
+ loc: locStub,
33998
+ codegenNode: undefined
33999
+ };
34000
+ subTransform(wrapperNode, subOptions, parentContext);
34001
+ return createReturnStatement(children);
34002
+ }
34003
+ function subTransform(node, options, parentContext) {
34004
+ const childRoot = createRoot([node]);
34005
+ const childContext = createTransformContext(childRoot, options);
34006
+ // this sub transform is for vnode fallback branch so it should be handled
34007
+ // like normal render functions
34008
+ childContext.ssr = false;
34009
+ // inherit parent scope analysis state
34010
+ childContext.scopes = Object.assign({}, parentContext.scopes);
34011
+ childContext.identifiers = Object.assign({}, parentContext.identifiers);
34012
+ childContext.imports = parentContext.imports;
34013
+ // traverse
34014
+ traverseNode(childRoot, childContext);
34015
+ ['helpers', 'components', 'directives'].forEach(key => {
34016
+ childContext[key].forEach((value, helperKey) => {
34017
+ if (key === 'helpers') {
34018
+ const parentCount = parentContext.helpers.get(helperKey);
34019
+ if (parentCount === undefined) {
34020
+ parentContext.helpers.set(helperKey, value);
34021
+ }
34022
+ else {
34023
+ parentContext.helpers.set(helperKey, value + parentCount);
34024
+ }
34025
+ }
34026
+ else {
34027
+ parentContext[key].add(value);
34028
+ }
34029
+ });
34030
+ });
34031
+ // imports/hoists are not merged because:
34032
+ // - imports are only used for asset urls and should be consistent between
34033
+ // node/client branches
34034
+ // - hoists are not enabled for the client branch here
34035
+ }
34036
+ function clone(v) {
34037
+ if (isArray(v)) {
34038
+ return v.map(clone);
34039
+ }
34040
+ else if (isObject(v)) {
34041
+ const res = {};
34042
+ for (const key in v) {
34043
+ res[key] = clone(v[key]);
34044
+ }
34045
+ return res;
34046
+ }
34047
+ else {
34048
+ return v;
34049
+ }
34050
+ }
34051
+
33997
34052
  // Because SSR codegen output is completely different from client-side output
33998
34053
  // (e.g. multiple elements can be concatenated into a single template literal
33999
34054
  // instead of each getting a corresponding call), we need to apply an extra
@@ -34082,7 +34137,7 @@ function processChildren(children, context, asFragment = false, disableNestedFra
34082
34137
  // TODO
34083
34138
  break;
34084
34139
  default:
34085
- context.onError(createSSRCompilerError(64 /* X_SSR_INVALID_AST_NODE */, child.loc));
34140
+ context.onError(createSSRCompilerError(63 /* X_SSR_INVALID_AST_NODE */, child.loc));
34086
34141
  // make sure we exhaust all possible types
34087
34142
  const exhaustiveCheck = child;
34088
34143
  return exhaustiveCheck;
@@ -34114,7 +34169,7 @@ function processChildren(children, context, asFragment = false, disableNestedFra
34114
34169
  // `transformText` is not used during SSR compile.
34115
34170
  break;
34116
34171
  default:
34117
- context.onError(createSSRCompilerError(64 /* X_SSR_INVALID_AST_NODE */, child.loc));
34172
+ context.onError(createSSRCompilerError(63 /* X_SSR_INVALID_AST_NODE */, child.loc));
34118
34173
  // make sure we exhaust all possible types
34119
34174
  const exhaustiveCheck = child;
34120
34175
  return exhaustiveCheck;
@@ -34757,33 +34812,7 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
34757
34812
  function walkScope(node, isRoot = false) {
34758
34813
  for (const stmt of node.body) {
34759
34814
  if (stmt.type === 'VariableDeclaration') {
34760
- if (stmt.declare)
34761
- continue;
34762
- for (const decl of stmt.declarations) {
34763
- let refCall;
34764
- const isCall = decl.init &&
34765
- decl.init.type === 'CallExpression' &&
34766
- decl.init.callee.type === 'Identifier';
34767
- if (isCall &&
34768
- (refCall = isRefCreationCall(decl.init.callee.name))) {
34769
- processRefDeclaration(refCall, decl.id, decl.init);
34770
- }
34771
- else {
34772
- const isProps = isRoot &&
34773
- isCall &&
34774
- decl.init.callee.name === 'defineProps';
34775
- for (const id of extractIdentifiers(decl.id)) {
34776
- if (isProps) {
34777
- // for defineProps destructure, only exclude them since they
34778
- // are already passed in as knownProps
34779
- excludedIds.add(id);
34780
- }
34781
- else {
34782
- registerBinding(id);
34783
- }
34784
- }
34785
- }
34786
- }
34815
+ walkVariableDeclaration(stmt, isRoot);
34787
34816
  }
34788
34817
  else if (stmt.type === 'FunctionDeclaration' ||
34789
34818
  stmt.type === 'ClassDeclaration') {
@@ -34791,6 +34820,47 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
34791
34820
  continue;
34792
34821
  registerBinding(stmt.id);
34793
34822
  }
34823
+ else if ((stmt.type === 'ForOfStatement' || stmt.type === 'ForInStatement') &&
34824
+ stmt.left.type === 'VariableDeclaration') {
34825
+ walkVariableDeclaration(stmt.left);
34826
+ }
34827
+ else if (stmt.type === 'ExportNamedDeclaration' &&
34828
+ stmt.declaration &&
34829
+ stmt.declaration.type === 'VariableDeclaration') {
34830
+ walkVariableDeclaration(stmt.declaration, isRoot);
34831
+ }
34832
+ else if (stmt.type === 'LabeledStatement' &&
34833
+ stmt.body.type === 'VariableDeclaration') {
34834
+ walkVariableDeclaration(stmt.body, isRoot);
34835
+ }
34836
+ }
34837
+ }
34838
+ function walkVariableDeclaration(stmt, isRoot = false) {
34839
+ if (stmt.declare) {
34840
+ return;
34841
+ }
34842
+ for (const decl of stmt.declarations) {
34843
+ let refCall;
34844
+ const isCall = decl.init &&
34845
+ decl.init.type === 'CallExpression' &&
34846
+ decl.init.callee.type === 'Identifier';
34847
+ if (isCall &&
34848
+ (refCall = isRefCreationCall(decl.init.callee.name))) {
34849
+ processRefDeclaration(refCall, decl.id, decl.init);
34850
+ }
34851
+ else {
34852
+ const isProps = isRoot && isCall && decl.init.callee.name === 'defineProps';
34853
+ for (const id of extractIdentifiers(decl.id)) {
34854
+ if (isProps) {
34855
+ // for defineProps destructure, only exclude them since they
34856
+ // are already passed in as knownProps
34857
+ excludedIds.add(id);
34858
+ }
34859
+ else {
34860
+ registerBinding(id);
34861
+ }
34862
+ }
34863
+ }
34794
34864
  }
34795
34865
  }
34796
34866
  function processRefDeclaration(method, id, call) {
@@ -35041,6 +35111,7 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
35041
35111
  walkScope(node);
35042
35112
  return;
35043
35113
  }
35114
+ // skip type nodes
35044
35115
  if (parent &&
35045
35116
  parent.type.startsWith('TS') &&
35046
35117
  parent.type !== 'TSAsExpression' &&
@@ -35120,7 +35191,7 @@ function warnOnce$1(msg) {
35120
35191
  }
35121
35192
  }
35122
35193
  function warn$1(msg) {
35123
- console.warn(`\x1b[1m\x1b[33m[@vue/ref-transform]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
35194
+ console.warn(`\x1b[1m\x1b[33m[@vue/reactivity-transform]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
35124
35195
  }
35125
35196
 
35126
35197
  // Special compiler macros
@@ -35140,7 +35211,7 @@ function compileScript(sfc, options) {
35140
35211
  let { script, scriptSetup, source, filename } = sfc;
35141
35212
  // feature flags
35142
35213
  // TODO remove support for deprecated options when out of experimental
35143
- const enableRefTransform = !!options.reactivityTransform ||
35214
+ const enableReactivityTransform = !!options.reactivityTransform ||
35144
35215
  !!options.refSugar ||
35145
35216
  !!options.refTransform;
35146
35217
  const enablePropsTransform = !!options.reactivityTransform || !!options.propsDestructureTransform;
@@ -35160,6 +35231,7 @@ function compileScript(sfc, options) {
35160
35231
  scriptLang === 'tsx' ||
35161
35232
  scriptSetupLang === 'ts' ||
35162
35233
  scriptSetupLang === 'tsx';
35234
+ // resolve parser plugins
35163
35235
  const plugins = [];
35164
35236
  if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
35165
35237
  plugins.push('jsx');
@@ -35184,7 +35256,7 @@ function compileScript(sfc, options) {
35184
35256
  sourceType: 'module'
35185
35257
  }).program;
35186
35258
  const bindings = analyzeScriptBindings(scriptAst.body);
35187
- if (enableRefTransform && shouldTransform(content)) {
35259
+ if (enableReactivityTransform && shouldTransform(content)) {
35188
35260
  const s = new MagicString(source);
35189
35261
  const startOffset = script.loc.start.offset;
35190
35262
  const endOffset = script.loc.end.offset;
@@ -35651,10 +35723,10 @@ function compileScript(sfc, options) {
35651
35723
  walkDeclaration(node, scriptBindings, userImportAlias);
35652
35724
  }
35653
35725
  }
35654
- // apply ref transform
35655
- if (enableRefTransform && shouldTransform(script.content)) {
35656
- const { rootRefs: rootVars, importedHelpers } = transformAST(scriptAst, s, scriptStartOffset);
35657
- refBindings = rootVars;
35726
+ // apply reactivity transform
35727
+ if (enableReactivityTransform && shouldTransform(script.content)) {
35728
+ const { rootRefs, importedHelpers } = transformAST(scriptAst, s, scriptStartOffset);
35729
+ refBindings = rootRefs;
35658
35730
  for (const h of importedHelpers) {
35659
35731
  helperImports.add(h);
35660
35732
  }
@@ -35839,8 +35911,10 @@ function compileScript(sfc, options) {
35839
35911
  }
35840
35912
  }
35841
35913
  }
35842
- // 3. Apply ref sugar transform
35843
- if ((enableRefTransform && shouldTransform(scriptSetup.content)) ||
35914
+ // 3. Apply reactivity transform
35915
+ if ((enableReactivityTransform &&
35916
+ // normal <script> had ref bindings that maybe used in <script setup>
35917
+ (refBindings || shouldTransform(scriptSetup.content))) ||
35844
35918
  propsDestructureDecl) {
35845
35919
  const { rootRefs, importedHelpers } = transformAST(scriptSetupAst, s, startOffset, refBindings, propsDestructuredBindings);
35846
35920
  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.26",
3
+ "version": "3.2.30",
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/vue-next.git",
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/vue-next/issues"
31
+ "url": "https://github.com/vuejs/core/issues"
32
32
  },
33
- "homepage": "https://github.com/vuejs/vue-next/tree/master/packages/compiler-sfc#readme",
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.26",
37
- "@vue/compiler-dom": "3.2.26",
38
- "@vue/compiler-ssr": "3.2.26",
39
- "@vue/reactivity-transform": "3.2.26",
40
- "@vue/shared": "3.2.26",
36
+ "@vue/compiler-core": "3.2.30",
37
+ "@vue/compiler-dom": "3.2.30",
38
+ "@vue/compiler-ssr": "3.2.30",
39
+ "@vue/reactivity-transform": "3.2.30",
40
+ "@vue/shared": "3.2.30",
41
41
  "estree-walker": "^2.0.2",
42
42
  "magic-string": "^0.25.7",
43
43
  "source-map": "^0.6.1",