@vue/compiler-sfc 3.2.29 → 3.2.32

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.
@@ -363,13 +363,15 @@ function escapeHtml(string) {
363
363
  * @private
364
364
  */
365
365
  const toDisplayString = (val) => {
366
- return val == null
367
- ? ''
368
- : isArray(val) ||
369
- (isObject(val) &&
370
- (val.toString === objectToString || !isFunction(val.toString)))
371
- ? JSON.stringify(val, replacer, 2)
372
- : 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);
373
375
  };
374
376
  const replacer = (_key, val) => {
375
377
  // can't use isRef here since @vue/shared has no deps
@@ -424,6 +426,7 @@ const isReservedProp = /*#__PURE__*/ makeMap(
424
426
  'onVnodeBeforeMount,onVnodeMounted,' +
425
427
  'onVnodeBeforeUpdate,onVnodeUpdated,' +
426
428
  'onVnodeBeforeUnmount,onVnodeUnmounted');
429
+ const isBuiltInDirective = /*#__PURE__*/ makeMap('bind,cloak,else-if,else,for,html,if,model,on,once,pre,show,slot,text,memo');
427
430
  const cacheStringFunction = (fn) => {
428
431
  const cache = Object.create(null);
429
432
  return ((str) => {
@@ -16332,13 +16335,13 @@ const deprecationData = {
16332
16335
  message: `Platform-native elements with "is" prop will no longer be ` +
16333
16336
  `treated as components in Vue 3 unless the "is" value is explicitly ` +
16334
16337
  `prefixed with "vue:".`,
16335
- link: `https://v3.vuejs.org/guide/migration/custom-elements-interop.html`
16338
+ link: `https://v3-migration.vuejs.org/breaking-changes/custom-elements-interop.html`
16336
16339
  },
16337
16340
  ["COMPILER_V_BIND_SYNC" /* COMPILER_V_BIND_SYNC */]: {
16338
16341
  message: key => `.sync modifier for v-bind has been removed. Use v-model with ` +
16339
16342
  `argument instead. \`v-bind:${key}.sync\` should be changed to ` +
16340
16343
  `\`v-model:${key}\`.`,
16341
- link: `https://v3.vuejs.org/guide/migration/v-model.html`
16344
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-model.html`
16342
16345
  },
16343
16346
  ["COMPILER_V_BIND_PROP" /* COMPILER_V_BIND_PROP */]: {
16344
16347
  message: `.prop modifier for v-bind has been removed and no longer necessary. ` +
@@ -16350,11 +16353,11 @@ const deprecationData = {
16350
16353
  `that appears before v-bind in the case of conflict. ` +
16351
16354
  `To retain 2.x behavior, move v-bind to make it the first attribute. ` +
16352
16355
  `You can also suppress this warning if the usage is intended.`,
16353
- link: `https://v3.vuejs.org/guide/migration/v-bind.html`
16356
+ link: `https://v3-migration.vuejs.org/breaking-changes/v-bind.html`
16354
16357
  },
16355
16358
  ["COMPILER_V_ON_NATIVE" /* COMPILER_V_ON_NATIVE */]: {
16356
16359
  message: `.native modifier for v-on has been removed as is no longer necessary.`,
16357
- 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`
16358
16361
  },
16359
16362
  ["COMPILER_V_IF_V_FOR_PRECEDENCE" /* COMPILER_V_IF_V_FOR_PRECEDENCE */]: {
16360
16363
  message: `v-if / v-for precedence when used on the same element has changed ` +
@@ -16362,7 +16365,7 @@ const deprecationData = {
16362
16365
  `access to v-for scope variables. It is best to avoid the ambiguity ` +
16363
16366
  `with <template> tags or use a computed property that filters v-for ` +
16364
16367
  `data source.`,
16365
- 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`
16366
16369
  },
16367
16370
  ["COMPILER_NATIVE_TEMPLATE" /* COMPILER_NATIVE_TEMPLATE */]: {
16368
16371
  message: `<template> with no special directives will render as a native template ` +
@@ -16370,13 +16373,13 @@ const deprecationData = {
16370
16373
  },
16371
16374
  ["COMPILER_INLINE_TEMPLATE" /* COMPILER_INLINE_TEMPLATE */]: {
16372
16375
  message: `"inline-template" has been removed in Vue 3.`,
16373
- link: `https://v3.vuejs.org/guide/migration/inline-template-attribute.html`
16376
+ link: `https://v3-migration.vuejs.org/breaking-changes/inline-template-attribute.html`
16374
16377
  },
16375
16378
  ["COMPILER_FILTER" /* COMPILER_FILTERS */]: {
16376
16379
  message: `filters have been removed in Vue 3. ` +
16377
16380
  `The "|" symbol will be treated as native JavaScript bitwise OR operator. ` +
16378
16381
  `Use method calls or computed properties instead.`,
16379
- link: `https://v3.vuejs.org/guide/migration/filters.html`
16382
+ link: `https://v3-migration.vuejs.org/breaking-changes/filters.html`
16380
16383
  }
16381
16384
  };
16382
16385
  function getCompatValue(key, context) {
@@ -23636,7 +23639,7 @@ function buildProps(node, context, props = node.props, ssr = false) {
23636
23639
  }
23637
23640
  }
23638
23641
  }
23639
- else {
23642
+ else if (!isBuiltInDirective(name)) {
23640
23643
  // no built-in transform, this is a user custom directive.
23641
23644
  runtimeDirectives.push(prop);
23642
23645
  // custom dirs may use beforeUpdate so they need to force blocks
@@ -27492,6 +27495,7 @@ var CompilerDOM = /*#__PURE__*/Object.freeze({
27492
27495
  transformElement: transformElement,
27493
27496
  resolveComponentType: resolveComponentType,
27494
27497
  buildProps: buildProps,
27498
+ buildDirectiveArgs: buildDirectiveArgs,
27495
27499
  processSlotOutlet: processSlotOutlet,
27496
27500
  generateCodeFrame: generateCodeFrame,
27497
27501
  checkCompatEnabled: checkCompatEnabled,
@@ -33304,6 +33308,7 @@ const SSR_RENDER_DYNAMIC_MODEL = Symbol(`ssrRenderDynamicModel`);
33304
33308
  const SSR_GET_DYNAMIC_MODEL_PROPS = Symbol(`ssrGetDynamicModelProps`);
33305
33309
  const SSR_RENDER_TELEPORT = Symbol(`ssrRenderTeleport`);
33306
33310
  const SSR_RENDER_SUSPENSE = Symbol(`ssrRenderSuspense`);
33311
+ const SSR_GET_DIRECTIVE_PROPS = Symbol(`ssrGetDirectiveProps`);
33307
33312
  const ssrHelpers = {
33308
33313
  [SSR_INTERPOLATE]: `ssrInterpolate`,
33309
33314
  [SSR_RENDER_VNODE]: `ssrRenderVNode`,
@@ -33321,7 +33326,8 @@ const ssrHelpers = {
33321
33326
  [SSR_RENDER_DYNAMIC_MODEL]: `ssrRenderDynamicModel`,
33322
33327
  [SSR_GET_DYNAMIC_MODEL_PROPS]: `ssrGetDynamicModelProps`,
33323
33328
  [SSR_RENDER_TELEPORT]: `ssrRenderTeleport`,
33324
- [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`
33329
+ [SSR_RENDER_SUSPENSE]: `ssrRenderSuspense`,
33330
+ [SSR_GET_DIRECTIVE_PROPS]: `ssrGetDirectiveProps`
33325
33331
  };
33326
33332
  // Note: these are helpers imported from @vue/server-renderer
33327
33333
  // make sure the names match!
@@ -33547,224 +33553,6 @@ function ssrProcessTransitionGroup(node, context) {
33547
33553
  }
33548
33554
  }
33549
33555
 
33550
- // We need to construct the slot functions in the 1st pass to ensure proper
33551
- // scope tracking, but the children of each slot cannot be processed until
33552
- // the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
33553
- // pass and complete them in the 2nd pass.
33554
- const wipMap$1 = new WeakMap();
33555
- const componentTypeMap = new WeakMap();
33556
- // ssr component transform is done in two phases:
33557
- // In phase 1. we use `buildSlot` to analyze the children of the component into
33558
- // WIP slot functions (it must be done in phase 1 because `buildSlot` relies on
33559
- // the core transform context).
33560
- // In phase 2. we convert the WIP slots from phase 1 into ssr-specific codegen
33561
- // nodes.
33562
- const ssrTransformComponent = (node, context) => {
33563
- if (node.type !== 1 /* ELEMENT */ ||
33564
- node.tagType !== 1 /* COMPONENT */) {
33565
- return;
33566
- }
33567
- const component = resolveComponentType(node, context, true /* ssr */);
33568
- componentTypeMap.set(node, component);
33569
- if (isSymbol(component)) {
33570
- if (component === SUSPENSE) {
33571
- return ssrTransformSuspense(node, context);
33572
- }
33573
- return; // built-in component: fallthrough
33574
- }
33575
- // Build the fallback vnode-based branch for the component's slots.
33576
- // We need to clone the node into a fresh copy and use the buildSlots' logic
33577
- // to get access to the children of each slot. We then compile them with
33578
- // a child transform pipeline using vnode-based transforms (instead of ssr-
33579
- // based ones), and save the result branch (a ReturnStatement) in an array.
33580
- // The branch is retrieved when processing slots again in ssr mode.
33581
- const vnodeBranches = [];
33582
- const clonedNode = clone(node);
33583
- return function ssrPostTransformComponent() {
33584
- // Using the cloned node, build the normal VNode-based branches (for
33585
- // fallback in case the child is render-fn based). Store them in an array
33586
- // for later use.
33587
- if (clonedNode.children.length) {
33588
- buildSlots(clonedNode, context, (props, children) => {
33589
- vnodeBranches.push(createVNodeSlotBranch(props, children, context));
33590
- return createFunctionExpression(undefined);
33591
- });
33592
- }
33593
- const props = node.props.length > 0
33594
- ? // note we are not passing ssr: true here because for components, v-on
33595
- // handlers should still be passed
33596
- buildProps(node, context).props || `null`
33597
- : `null`;
33598
- const wipEntries = [];
33599
- wipMap$1.set(node, wipEntries);
33600
- const buildSSRSlotFn = (props, children, loc) => {
33601
- const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
33602
- true, // newline
33603
- true, // isSlot
33604
- loc);
33605
- wipEntries.push({
33606
- fn,
33607
- children,
33608
- // also collect the corresponding vnode branch built earlier
33609
- vnodeBranch: vnodeBranches[wipEntries.length]
33610
- });
33611
- return fn;
33612
- };
33613
- const slots = node.children.length
33614
- ? buildSlots(node, context, buildSSRSlotFn).slots
33615
- : `null`;
33616
- if (typeof component !== 'string') {
33617
- // dynamic component that resolved to a `resolveDynamicComponent` call
33618
- // expression - since the resolved result may be a plain element (string)
33619
- // or a VNode, handle it with `renderVNode`.
33620
- node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_VNODE), [
33621
- `_push`,
33622
- createCallExpression(context.helper(CREATE_VNODE), [
33623
- component,
33624
- props,
33625
- slots
33626
- ]),
33627
- `_parent`
33628
- ]);
33629
- }
33630
- else {
33631
- node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_COMPONENT), [component, props, slots, `_parent`]);
33632
- }
33633
- };
33634
- };
33635
- function ssrProcessComponent(node, context) {
33636
- const component = componentTypeMap.get(node);
33637
- if (!node.ssrCodegenNode) {
33638
- // this is a built-in component that fell-through.
33639
- if (component === TELEPORT) {
33640
- return ssrProcessTeleport(node, context);
33641
- }
33642
- else if (component === SUSPENSE) {
33643
- return ssrProcessSuspense(node, context);
33644
- }
33645
- else if (component === TRANSITION_GROUP) {
33646
- return ssrProcessTransitionGroup(node, context);
33647
- }
33648
- else {
33649
- // real fall-through: Transition / KeepAlive
33650
- // just render its children.
33651
- processChildren(node.children, context);
33652
- }
33653
- }
33654
- else {
33655
- // finish up slot function expressions from the 1st pass.
33656
- const wipEntries = wipMap$1.get(node) || [];
33657
- for (let i = 0; i < wipEntries.length; i++) {
33658
- const { fn, children, vnodeBranch } = wipEntries[i];
33659
- // For each slot, we generate two branches: one SSR-optimized branch and
33660
- // one normal vnode-based branch. The branches are taken based on the
33661
- // presence of the 2nd `_push` argument (which is only present if the slot
33662
- // is called by `_ssrRenderSlot`.
33663
- fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
33664
- }
33665
- // component is inside a slot, inherit slot scope Id
33666
- if (context.withSlotScopeId) {
33667
- node.ssrCodegenNode.arguments.push(`_scopeId`);
33668
- }
33669
- if (typeof component === 'string') {
33670
- // static component
33671
- context.pushStatement(createCallExpression(`_push`, [node.ssrCodegenNode]));
33672
- }
33673
- else {
33674
- // dynamic component (`resolveDynamicComponent` call)
33675
- // the codegen node is a `renderVNode` call
33676
- context.pushStatement(node.ssrCodegenNode);
33677
- }
33678
- }
33679
- }
33680
- const rawOptionsMap = new WeakMap();
33681
- const [baseNodeTransforms, baseDirectiveTransforms] = getBaseTransformPreset(true);
33682
- const vnodeNodeTransforms = [...baseNodeTransforms, ...DOMNodeTransforms];
33683
- const vnodeDirectiveTransforms = Object.assign(Object.assign({}, baseDirectiveTransforms), DOMDirectiveTransforms);
33684
- function createVNodeSlotBranch(props, children, parentContext) {
33685
- // apply a sub-transform using vnode-based transforms.
33686
- const rawOptions = rawOptionsMap.get(parentContext.root);
33687
- const subOptions = Object.assign(Object.assign({}, rawOptions), {
33688
- // overwrite with vnode-based transforms
33689
- nodeTransforms: [
33690
- ...vnodeNodeTransforms,
33691
- ...(rawOptions.nodeTransforms || [])
33692
- ], directiveTransforms: Object.assign(Object.assign({}, vnodeDirectiveTransforms), (rawOptions.directiveTransforms || {})) });
33693
- // wrap the children with a wrapper template for proper children treatment.
33694
- const wrapperNode = {
33695
- type: 1 /* ELEMENT */,
33696
- ns: 0 /* HTML */,
33697
- tag: 'template',
33698
- tagType: 3 /* TEMPLATE */,
33699
- isSelfClosing: false,
33700
- // important: provide v-slot="props" on the wrapper for proper
33701
- // scope analysis
33702
- props: [
33703
- {
33704
- type: 7 /* DIRECTIVE */,
33705
- name: 'slot',
33706
- exp: props,
33707
- arg: undefined,
33708
- modifiers: [],
33709
- loc: locStub
33710
- }
33711
- ],
33712
- children,
33713
- loc: locStub,
33714
- codegenNode: undefined
33715
- };
33716
- subTransform(wrapperNode, subOptions, parentContext);
33717
- return createReturnStatement(children);
33718
- }
33719
- function subTransform(node, options, parentContext) {
33720
- const childRoot = createRoot([node]);
33721
- const childContext = createTransformContext(childRoot, options);
33722
- // this sub transform is for vnode fallback branch so it should be handled
33723
- // like normal render functions
33724
- childContext.ssr = false;
33725
- // inherit parent scope analysis state
33726
- childContext.scopes = Object.assign({}, parentContext.scopes);
33727
- childContext.identifiers = Object.assign({}, parentContext.identifiers);
33728
- childContext.imports = parentContext.imports;
33729
- // traverse
33730
- traverseNode(childRoot, childContext);
33731
- ['helpers', 'components', 'directives'].forEach(key => {
33732
- childContext[key].forEach((value, helperKey) => {
33733
- if (key === 'helpers') {
33734
- const parentCount = parentContext.helpers.get(helperKey);
33735
- if (parentCount === undefined) {
33736
- parentContext.helpers.set(helperKey, value);
33737
- }
33738
- else {
33739
- parentContext.helpers.set(helperKey, value + parentCount);
33740
- }
33741
- }
33742
- else {
33743
- parentContext[key].add(value);
33744
- }
33745
- });
33746
- });
33747
- // imports/hoists are not merged because:
33748
- // - imports are only used for asset urls and should be consistent between
33749
- // node/client branches
33750
- // - hoists are not enabled for the client branch here
33751
- }
33752
- function clone(v) {
33753
- if (isArray(v)) {
33754
- return v.map(clone);
33755
- }
33756
- else if (isObject(v)) {
33757
- const res = {};
33758
- for (const key in v) {
33759
- res[key] = clone(v[key]);
33760
- }
33761
- return res;
33762
- }
33763
- else {
33764
- return v;
33765
- }
33766
- }
33767
-
33768
33556
  // for directives with children overwrite (e.g. v-html & v-text), we need to
33769
33557
  // store the raw children so that they can be added in the 2nd pass.
33770
33558
  const rawChildrenMap = new WeakMap();
@@ -33779,14 +33567,17 @@ const ssrTransformElement = (node, context) => {
33779
33567
  const openTag = [`<${node.tag}`];
33780
33568
  // some tags need to be passed to runtime for special checks
33781
33569
  const needTagForRuntime = node.tag === 'textarea' || node.tag.indexOf('-') > 0;
33782
- // v-bind="obj" or v-bind:[key] can potentially overwrite other static
33783
- // attrs and can affect final rendering result, so when they are present
33784
- // 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`
33785
33573
  const hasDynamicVBind = hasDynamicKeyVBind(node);
33786
- if (hasDynamicVBind) {
33787
- const { props } = buildProps(node, context, node.props, true /* ssr */);
33788
- if (props) {
33789
- 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]);
33790
33581
  if (node.tag === 'textarea') {
33791
33582
  const existingText = node.children[0];
33792
33583
  // If interpolation, this is dynamic <textarea> content, potentially
@@ -33798,7 +33589,7 @@ const ssrTransformElement = (node, context) => {
33798
33589
  // it contains value (if yes, render is as children).
33799
33590
  const tempId = `_temp${context.temps++}`;
33800
33591
  propsExp.arguments = [
33801
- createAssignmentExpression(createSimpleExpression(tempId, false), props)
33592
+ createAssignmentExpression(createSimpleExpression(tempId, false), mergedProps)
33802
33593
  ];
33803
33594
  rawChildrenMap.set(node, createCallExpression(context.helper(SSR_INTERPOLATE), [
33804
33595
  createConditionalExpression(createSimpleExpression(`"value" in ${tempId}`, false), createSimpleExpression(`${tempId}.value`, false), createSimpleExpression(existingText ? existingText.content : ``, true), false)
@@ -33816,7 +33607,7 @@ const ssrTransformElement = (node, context) => {
33816
33607
  const tempExp = createSimpleExpression(tempId, false);
33817
33608
  propsExp.arguments = [
33818
33609
  createSequenceExpression([
33819
- createAssignmentExpression(tempExp, props),
33610
+ createAssignmentExpression(tempExp, mergedProps),
33820
33611
  createCallExpression(context.helper(MERGE_PROPS), [
33821
33612
  tempExp,
33822
33613
  createCallExpression(context.helper(SSR_GET_DYNAMIC_MODEL_PROPS), [
@@ -33858,11 +33649,11 @@ const ssrTransformElement = (node, context) => {
33858
33649
  context.onError(createCompilerError(40 /* X_V_SLOT_MISPLACED */, prop.loc));
33859
33650
  }
33860
33651
  else if (isTextareaWithValue(node, prop) && prop.exp) {
33861
- if (!hasDynamicVBind) {
33652
+ if (!needMergeProps) {
33862
33653
  node.children = [createInterpolation(prop.exp, prop.loc)];
33863
33654
  }
33864
33655
  }
33865
- else if (!hasDynamicVBind) {
33656
+ else if (!needMergeProps) {
33866
33657
  // Directive transforms.
33867
33658
  const directiveTransform = context.directiveTransforms[prop.name];
33868
33659
  if (directiveTransform) {
@@ -33928,7 +33719,7 @@ const ssrTransformElement = (node, context) => {
33928
33719
  if (node.tag === 'textarea' && prop.name === 'value' && prop.value) {
33929
33720
  rawChildrenMap.set(node, escapeHtml(prop.value.content));
33930
33721
  }
33931
- else if (!hasDynamicVBind) {
33722
+ else if (!needMergeProps) {
33932
33723
  if (prop.name === 'key' || prop.name === 'ref') {
33933
33724
  continue;
33934
33725
  }
@@ -33952,6 +33743,29 @@ const ssrTransformElement = (node, context) => {
33952
33743
  node.ssrCodegenNode = createTemplateLiteral(openTag);
33953
33744
  };
33954
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
+ }
33955
33769
  function isTrueFalseValue(prop) {
33956
33770
  if (prop.type === 7 /* DIRECTIVE */) {
33957
33771
  return (prop.name === 'bind' &&
@@ -34012,6 +33826,228 @@ function ssrProcessElement(node, context) {
34012
33826
  }
34013
33827
  }
34014
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
+
34015
34051
  // Because SSR codegen output is completely different from client-side output
34016
34052
  // (e.g. multiple elements can be concatenated into a single template literal
34017
34053
  // instead of each getting a corresponding call), we need to apply an extra
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "3.2.29",
3
+ "version": "3.2.32",
4
4
  "description": "@vue/compiler-sfc",
5
5
  "main": "dist/compiler-sfc.cjs.js",
6
6
  "module": "dist/compiler-sfc.esm-browser.js",
@@ -33,11 +33,11 @@
33
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.29",
37
- "@vue/compiler-dom": "3.2.29",
38
- "@vue/compiler-ssr": "3.2.29",
39
- "@vue/reactivity-transform": "3.2.29",
40
- "@vue/shared": "3.2.29",
36
+ "@vue/compiler-core": "3.2.32",
37
+ "@vue/compiler-dom": "3.2.32",
38
+ "@vue/compiler-ssr": "3.2.32",
39
+ "@vue/reactivity-transform": "3.2.32",
40
+ "@vue/shared": "3.2.32",
41
41
  "estree-walker": "^2.0.2",
42
42
  "magic-string": "^0.25.7",
43
43
  "source-map": "^0.6.1",