@vue/compiler-sfc 3.2.34-beta.1 → 3.2.36

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.
@@ -3264,7 +3264,7 @@ function patchErrors(errors, source, inMap) {
3264
3264
  }
3265
3265
 
3266
3266
  const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
3267
- const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/s;
3267
+ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)(?:as)?(\s*)default/s;
3268
3268
  const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
3269
3269
  /**
3270
3270
  * Utility for rewriting `export default` in a script block into a variable
@@ -3299,21 +3299,56 @@ function rewriteDefault(input, as, parserPlugins) {
3299
3299
  s.overwrite(node.start, node.declaration.start, `const ${as} = `);
3300
3300
  }
3301
3301
  if (node.type === 'ExportNamedDeclaration') {
3302
- node.specifiers.forEach(specifier => {
3302
+ for (const specifier of node.specifiers) {
3303
3303
  if (specifier.type === 'ExportSpecifier' &&
3304
3304
  specifier.exported.type === 'Identifier' &&
3305
3305
  specifier.exported.name === 'default') {
3306
- const end = specifier.end;
3307
- s.overwrite(specifier.start, input.charAt(end) === ',' ? end + 1 : end, ``);
3306
+ if (node.source) {
3307
+ if (specifier.local.name === 'default') {
3308
+ const end = specifierEnd(input, specifier.local.end, node.end);
3309
+ s.prepend(`import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n`);
3310
+ s.overwrite(specifier.start, end, ``);
3311
+ s.append(`\nconst ${as} = __VUE_DEFAULT__`);
3312
+ continue;
3313
+ }
3314
+ else {
3315
+ const end = specifierEnd(input, specifier.exported.end, node.end);
3316
+ s.prepend(`import { ${input.slice(specifier.local.start, specifier.local.end)} } from '${node.source.value}'\n`);
3317
+ s.overwrite(specifier.start, end, ``);
3318
+ s.append(`\nconst ${as} = ${specifier.local.name}`);
3319
+ continue;
3320
+ }
3321
+ }
3322
+ const end = specifierEnd(input, specifier.end, node.end);
3323
+ s.overwrite(specifier.start, end, ``);
3308
3324
  s.append(`\nconst ${as} = ${specifier.local.name}`);
3309
3325
  }
3310
- });
3326
+ }
3311
3327
  }
3312
3328
  });
3313
3329
  return s.toString();
3314
3330
  }
3315
3331
  function hasDefaultExport(input) {
3316
3332
  return defaultExportRE.test(input) || namedDefaultExportRE.test(input);
3333
+ }
3334
+ function specifierEnd(input, end, nodeEnd) {
3335
+ // export { default , foo } ...
3336
+ let hasCommas = false;
3337
+ let oldEnd = end;
3338
+ while (end < nodeEnd) {
3339
+ if (/\s/.test(input.charAt(end))) {
3340
+ end++;
3341
+ }
3342
+ else if (input.charAt(end) === ',') {
3343
+ end++;
3344
+ hasCommas = true;
3345
+ break;
3346
+ }
3347
+ else if (input.charAt(end) === '}') {
3348
+ break;
3349
+ }
3350
+ }
3351
+ return hasCommas ? end : oldEnd;
3317
3352
  }
3318
3353
 
3319
3354
  // Special compiler macros
@@ -3323,13 +3358,14 @@ const DEFINE_EXPOSE = 'defineExpose';
3323
3358
  const WITH_DEFAULTS = 'withDefaults';
3324
3359
  // constants
3325
3360
  const DEFAULT_VAR = `__default__`;
3326
- const isBuiltInDir = shared.makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
3361
+ const isBuiltInDir = shared.makeMap(`once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
3327
3362
  /**
3328
3363
  * Compile `<script setup>`
3329
3364
  * It requires the whole SFC descriptor because we need to handle and merge
3330
3365
  * normal `<script>` + `<script setup>` if both are present.
3331
3366
  */
3332
3367
  function compileScript(sfc, options) {
3368
+ var _a;
3333
3369
  let { script, scriptSetup, source, filename } = sfc;
3334
3370
  // feature flags
3335
3371
  // TODO remove support for deprecated options when out of experimental
@@ -4202,7 +4238,7 @@ function compileScript(sfc, options) {
4202
4238
  // 8. inject `useCssVars` calls
4203
4239
  if (cssVars.length &&
4204
4240
  // no need to do this when targeting SSR
4205
- !(options.inlineTemplate && options.templateOptions?.ssr)) {
4241
+ !(options.inlineTemplate && ((_a = options.templateOptions) === null || _a === void 0 ? void 0 : _a.ssr))) {
4206
4242
  helperImports.add(CSS_VARS_HELPER);
4207
4243
  helperImports.add('unref');
4208
4244
  s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, isProd)}\n`);
@@ -4410,8 +4446,8 @@ function compileScript(sfc, options) {
4410
4446
  includeContent: true
4411
4447
  })
4412
4448
  : undefined,
4413
- scriptAst: scriptAst?.body,
4414
- scriptSetupAst: scriptSetupAst?.body
4449
+ scriptAst: scriptAst === null || scriptAst === void 0 ? void 0 : scriptAst.body,
4450
+ scriptSetupAst: scriptSetupAst === null || scriptSetupAst === void 0 ? void 0 : scriptSetupAst.body
4415
4451
  };
4416
4452
  }
4417
4453
  function registerBinding(bindings, node, type) {
@@ -4616,6 +4652,7 @@ function inferRuntimeType(node, declaredTypes) {
4616
4652
  case 'WeakSet':
4617
4653
  case 'WeakMap':
4618
4654
  case 'Date':
4655
+ case 'Promise':
4619
4656
  return [node.typeName.name];
4620
4657
  case 'Record':
4621
4658
  case 'Partial':
@@ -4853,7 +4890,7 @@ function resolveTemplateUsageCheckString(sfc) {
4853
4890
  code += `,v${shared.capitalize(shared.camelize(prop.name))}`;
4854
4891
  }
4855
4892
  if (prop.exp) {
4856
- code += `,${processExp(prop.exp.content)}`;
4893
+ code += `,${processExp(prop.exp.content, prop.name)}`;
4857
4894
  }
4858
4895
  }
4859
4896
  }
@@ -4868,8 +4905,19 @@ function resolveTemplateUsageCheckString(sfc) {
4868
4905
  templateUsageCheckCache.set(content, code);
4869
4906
  return code;
4870
4907
  }
4871
- function processExp(exp) {
4872
- if (/ as \w|<.*>/.test(exp)) {
4908
+ const forAliasRE = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
4909
+ function processExp(exp, dir) {
4910
+ if (/ as\s+\w|<.*>|:/.test(exp)) {
4911
+ if (dir === 'slot') {
4912
+ exp = `(${exp})=>{}`;
4913
+ }
4914
+ else if (dir === 'for') {
4915
+ const inMatch = exp.match(forAliasRE);
4916
+ if (inMatch) {
4917
+ const [, LHS, RHS] = inMatch;
4918
+ return processExp(`(${LHS})=>{}`) + processExp(RHS);
4919
+ }
4920
+ }
4873
4921
  let ret = '';
4874
4922
  // has potential type cast or generic arguments that uses types
4875
4923
  const ast = parser$2.parseExpression(exp, { plugins: ['typescript'] });
@@ -17347,6 +17347,14 @@ function getConstantType(node, context) {
17347
17347
  // static then they don't need to be blocks since there will be no
17348
17348
  // nested updates.
17349
17349
  if (codegenNode.isBlock) {
17350
+ // except set custom directives.
17351
+ for (let i = 0; i < node.props.length; i++) {
17352
+ const p = node.props[i];
17353
+ if (p.type === 7 /* DIRECTIVE */) {
17354
+ constantCache.set(node, 0 /* NOT_CONSTANT */);
17355
+ return 0 /* NOT_CONSTANT */;
17356
+ }
17357
+ }
17350
17358
  context.removeHelper(OPEN_BLOCK);
17351
17359
  context.removeHelper(getVNodeBlockHelper(context.inSSR, codegenNode.isComponent));
17352
17360
  codegenNode.isBlock = false;
@@ -23271,7 +23279,7 @@ const transformElement = (node, context) => {
23271
23279
  (tag === 'svg' || tag === 'foreignObject'));
23272
23280
  // props
23273
23281
  if (props.length > 0) {
23274
- const propsBuildResult = buildProps(node, context);
23282
+ const propsBuildResult = buildProps(node, context, undefined, isComponent, isDynamicComponent);
23275
23283
  vnodeProps = propsBuildResult.props;
23276
23284
  patchFlag = propsBuildResult.patchFlag;
23277
23285
  dynamicPropNames = propsBuildResult.dynamicPropNames;
@@ -23472,9 +23480,8 @@ function resolveSetupReference(name, context) {
23472
23480
  : `$setup[${JSON.stringify(fromMaybeRef)}]`;
23473
23481
  }
23474
23482
  }
23475
- function buildProps(node, context, props = node.props, ssr = false) {
23483
+ function buildProps(node, context, props = node.props, isComponent, isDynamicComponent, ssr = false) {
23476
23484
  const { tag, loc: elementLoc, children } = node;
23477
- const isComponent = node.tagType === 1 /* COMPONENT */;
23478
23485
  let properties = [];
23479
23486
  const mergeArgs = [];
23480
23487
  const runtimeDirectives = [];
@@ -23493,8 +23500,8 @@ function buildProps(node, context, props = node.props, ssr = false) {
23493
23500
  if (isStaticExp(key)) {
23494
23501
  const name = key.content;
23495
23502
  const isEventHandler = isOn(name);
23496
- if (!isComponent &&
23497
- isEventHandler &&
23503
+ if (isEventHandler &&
23504
+ (!isComponent || isDynamicComponent) &&
23498
23505
  // omit the flag for click handlers because hydration gives click
23499
23506
  // dedicated fast path.
23500
23507
  name.toLowerCase() !== 'onclick' &&
@@ -23918,7 +23925,7 @@ function processSlotOutlet(node, context) {
23918
23925
  }
23919
23926
  }
23920
23927
  if (nonNameProps.length > 0) {
23921
- const { props, directives } = buildProps(node, context, nonNameProps);
23928
+ const { props, directives } = buildProps(node, context, nonNameProps, false, false);
23922
23929
  slotProps = props;
23923
23930
  if (directives.length) {
23924
23931
  context.onError(createCompilerError(36 /* X_V_SLOT_UNEXPECTED_DIRECTIVE_ON_SLOT_OUTLET */, directives[0].loc));
@@ -33424,7 +33431,7 @@ function processIfBranch(branch, context, disableNestedFragments = false) {
33424
33431
  (children.length !== 1 || children[0].type !== 1 /* ELEMENT */) &&
33425
33432
  // optimize away nested fragments when the only child is a ForNode
33426
33433
  !(children.length === 1 && children[0].type === 11 /* FOR */);
33427
- return processChildrenAsStatement(children, context, needFragmentWrapper);
33434
+ return processChildrenAsStatement(branch, context, needFragmentWrapper);
33428
33435
  }
33429
33436
 
33430
33437
  // Plugin for the first transform pass, which simply constructs the AST node
@@ -33435,7 +33442,7 @@ function ssrProcessFor(node, context, disableNestedFragments = false) {
33435
33442
  const needFragmentWrapper = !disableNestedFragments &&
33436
33443
  (node.children.length !== 1 || node.children[0].type !== 1 /* ELEMENT */);
33437
33444
  const renderLoop = createFunctionExpression(createForLoopParams(node.parseResult));
33438
- renderLoop.body = processChildrenAsStatement(node.children, context, needFragmentWrapper);
33445
+ renderLoop.body = processChildrenAsStatement(node, context, needFragmentWrapper);
33439
33446
  // v-for always renders a fragment unless explicitly disabled
33440
33447
  if (!disableNestedFragments) {
33441
33448
  context.pushStringPart(`<!--[-->`);
@@ -33486,7 +33493,7 @@ function ssrProcessSlotOutlet(node, context) {
33486
33493
  // has fallback content
33487
33494
  if (node.children.length) {
33488
33495
  const fallbackRenderFn = createFunctionExpression([]);
33489
- fallbackRenderFn.body = processChildrenAsStatement(node.children, context);
33496
+ fallbackRenderFn.body = processChildrenAsStatement(node, context);
33490
33497
  // _renderSlot(slots, name, props, fallback, ...)
33491
33498
  renderCall.arguments[3] = fallbackRenderFn;
33492
33499
  }
@@ -33538,7 +33545,7 @@ function ssrProcessTeleport(node, context) {
33538
33545
  true, // newline
33539
33546
  false, // isSlot
33540
33547
  node.loc);
33541
- contentRenderFn.body = processChildrenAsStatement(node.children, context);
33548
+ contentRenderFn.body = processChildrenAsStatement(node, context);
33542
33549
  context.pushStatement(createCallExpression(context.helper(SSR_RENDER_TELEPORT), [
33543
33550
  `_push`,
33544
33551
  contentRenderFn,
@@ -33581,8 +33588,8 @@ function ssrProcessSuspense(node, context) {
33581
33588
  }
33582
33589
  const { slotsExp, wipSlots } = wipEntry;
33583
33590
  for (let i = 0; i < wipSlots.length; i++) {
33584
- const { fn, children } = wipSlots[i];
33585
- fn.body = processChildrenAsStatement(children, context);
33591
+ const slot = wipSlots[i];
33592
+ slot.fn.body = processChildrenAsStatement(slot, context);
33586
33593
  }
33587
33594
  // _push(ssrRenderSuspense(slots))
33588
33595
  context.pushStatement(createCallExpression(context.helper(SSR_RENDER_SUSPENSE), [
@@ -33591,39 +33598,6 @@ function ssrProcessSuspense(node, context) {
33591
33598
  ]));
33592
33599
  }
33593
33600
 
33594
- function ssrProcessTransitionGroup(node, context) {
33595
- const tag = findProp(node, 'tag');
33596
- if (tag) {
33597
- if (tag.type === 7 /* DIRECTIVE */) {
33598
- // dynamic :tag
33599
- context.pushStringPart(`<`);
33600
- context.pushStringPart(tag.exp);
33601
- context.pushStringPart(`>`);
33602
- processChildren(node.children, context, false,
33603
- /**
33604
- * TransitionGroup has the special runtime behavior of flattening and
33605
- * concatenating all children into a single fragment (in order for them to
33606
- * be patched using the same key map) so we need to account for that here
33607
- * by disabling nested fragment wrappers from being generated.
33608
- */
33609
- true);
33610
- context.pushStringPart(`</`);
33611
- context.pushStringPart(tag.exp);
33612
- context.pushStringPart(`>`);
33613
- }
33614
- else {
33615
- // static tag
33616
- context.pushStringPart(`<${tag.value.content}>`);
33617
- processChildren(node.children, context, false, true);
33618
- context.pushStringPart(`</${tag.value.content}>`);
33619
- }
33620
- }
33621
- else {
33622
- // fragment
33623
- processChildren(node.children, context, true, true);
33624
- }
33625
- }
33626
-
33627
33601
  // for directives with children overwrite (e.g. v-html & v-text), we need to
33628
33602
  // store the raw children so that they can be added in the 2nd pass.
33629
33603
  const rawChildrenMap = new WeakMap();
@@ -33645,7 +33619,7 @@ const ssrTransformElement = (node, context) => {
33645
33619
  const hasCustomDir = node.props.some(p => p.type === 7 /* DIRECTIVE */ && !isBuiltInDirective(p.name));
33646
33620
  const needMergeProps = hasDynamicVBind || hasCustomDir;
33647
33621
  if (needMergeProps) {
33648
- const { props, directives } = buildProps(node, context, node.props, true /* ssr */);
33622
+ const { props, directives } = buildProps(node, context, node.props, false /* isComponent */, false /* isDynamicComponent */, true /* ssr */);
33649
33623
  if (props || directives.length) {
33650
33624
  const mergedProps = buildSSRProps(props, directives, context);
33651
33625
  const propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [mergedProps]);
@@ -33724,7 +33698,7 @@ const ssrTransformElement = (node, context) => {
33724
33698
  node.children = [createInterpolation(prop.exp, prop.loc)];
33725
33699
  }
33726
33700
  }
33727
- else if (!needMergeProps) {
33701
+ else if (!needMergeProps && prop.name !== 'on') {
33728
33702
  // Directive transforms.
33729
33703
  const directiveTransform = context.directiveTransforms[prop.name];
33730
33704
  if (directiveTransform) {
@@ -33889,7 +33863,7 @@ function ssrProcessElement(node, context) {
33889
33863
  context.pushStringPart(rawChildren);
33890
33864
  }
33891
33865
  else if (node.children.length) {
33892
- processChildren(node.children, context);
33866
+ processChildren(node, context);
33893
33867
  }
33894
33868
  if (!isVoidTag(node.tag)) {
33895
33869
  // push closing tag
@@ -33897,11 +33871,75 @@ function ssrProcessElement(node, context) {
33897
33871
  }
33898
33872
  }
33899
33873
 
33874
+ const wipMap$1 = new WeakMap();
33875
+ // phase 1: build props
33876
+ function ssrTransformTransitionGroup(node, context) {
33877
+ return () => {
33878
+ const tag = findProp(node, 'tag');
33879
+ if (tag) {
33880
+ const otherProps = node.props.filter(p => p !== tag);
33881
+ const { props, directives } = buildProps(node, context, otherProps, true, /* isComponent */ false, /* isDynamicComponent */ true /* ssr (skip event listeners) */);
33882
+ let propsExp = null;
33883
+ if (props || directives.length) {
33884
+ propsExp = createCallExpression(context.helper(SSR_RENDER_ATTRS), [
33885
+ buildSSRProps(props, directives, context)
33886
+ ]);
33887
+ }
33888
+ wipMap$1.set(node, {
33889
+ tag,
33890
+ propsExp
33891
+ });
33892
+ }
33893
+ };
33894
+ }
33895
+ // phase 2: process children
33896
+ function ssrProcessTransitionGroup(node, context) {
33897
+ const entry = wipMap$1.get(node);
33898
+ if (entry) {
33899
+ const { tag, propsExp } = entry;
33900
+ if (tag.type === 7 /* DIRECTIVE */) {
33901
+ // dynamic :tag
33902
+ context.pushStringPart(`<`);
33903
+ context.pushStringPart(tag.exp);
33904
+ if (propsExp) {
33905
+ context.pushStringPart(propsExp);
33906
+ }
33907
+ context.pushStringPart(`>`);
33908
+ processChildren(node, context, false,
33909
+ /**
33910
+ * TransitionGroup has the special runtime behavior of flattening and
33911
+ * concatenating all children into a single fragment (in order for them to
33912
+ * be patched using the same key map) so we need to account for that here
33913
+ * by disabling nested fragment wrappers from being generated.
33914
+ */
33915
+ true);
33916
+ context.pushStringPart(`</`);
33917
+ context.pushStringPart(tag.exp);
33918
+ context.pushStringPart(`>`);
33919
+ }
33920
+ else {
33921
+ // static tag
33922
+ context.pushStringPart(`<${tag.value.content}`);
33923
+ if (propsExp) {
33924
+ context.pushStringPart(propsExp);
33925
+ }
33926
+ context.pushStringPart(`>`);
33927
+ processChildren(node, context, false, true);
33928
+ context.pushStringPart(`</${tag.value.content}>`);
33929
+ }
33930
+ }
33931
+ else {
33932
+ // fragment
33933
+ processChildren(node, context, true, true);
33934
+ }
33935
+ }
33936
+
33900
33937
  // We need to construct the slot functions in the 1st pass to ensure proper
33901
33938
  // scope tracking, but the children of each slot cannot be processed until
33902
33939
  // the 2nd pass, so we store the WIP slot functions in a weakMap during the 1st
33903
33940
  // pass and complete them in the 2nd pass.
33904
- const wipMap$1 = new WeakMap();
33941
+ const wipMap$2 = new WeakMap();
33942
+ const WIP_SLOT = Symbol();
33905
33943
  const componentTypeMap = new WeakMap();
33906
33944
  // ssr component transform is done in two phases:
33907
33945
  // In phase 1. we use `buildSlot` to analyze the children of the component into
@@ -33915,12 +33953,16 @@ const ssrTransformComponent = (node, context) => {
33915
33953
  return;
33916
33954
  }
33917
33955
  const component = resolveComponentType(node, context, true /* ssr */);
33956
+ const isDynamicComponent = isObject(component) && component.callee === RESOLVE_DYNAMIC_COMPONENT;
33918
33957
  componentTypeMap.set(node, component);
33919
33958
  if (isSymbol(component)) {
33920
33959
  if (component === SUSPENSE) {
33921
33960
  return ssrTransformSuspense(node, context);
33922
33961
  }
33923
- return; // built-in component: fallthrough
33962
+ if (component === TRANSITION_GROUP) {
33963
+ return ssrTransformTransitionGroup(node, context);
33964
+ }
33965
+ return; // other built-in components: fallthrough
33924
33966
  }
33925
33967
  // Build the fallback vnode-based branch for the component's slots.
33926
33968
  // We need to clone the node into a fresh copy and use the buildSlots' logic
@@ -33944,19 +33986,20 @@ const ssrTransformComponent = (node, context) => {
33944
33986
  if (node.props.length) {
33945
33987
  // note we are not passing ssr: true here because for components, v-on
33946
33988
  // handlers should still be passed
33947
- const { props, directives } = buildProps(node, context);
33989
+ const { props, directives } = buildProps(node, context, undefined, true, isDynamicComponent);
33948
33990
  if (props || directives.length) {
33949
33991
  propsExp = buildSSRProps(props, directives, context);
33950
33992
  }
33951
33993
  }
33952
33994
  const wipEntries = [];
33953
- wipMap$1.set(node, wipEntries);
33995
+ wipMap$2.set(node, wipEntries);
33954
33996
  const buildSSRSlotFn = (props, children, loc) => {
33955
33997
  const fn = createFunctionExpression([props || `_`, `_push`, `_parent`, `_scopeId`], undefined, // no return, assign body later
33956
33998
  true, // newline
33957
33999
  true, // isSlot
33958
34000
  loc);
33959
34001
  wipEntries.push({
34002
+ type: WIP_SLOT,
33960
34003
  fn,
33961
34004
  children,
33962
34005
  // also collect the corresponding vnode branch built earlier
@@ -33986,7 +34029,7 @@ const ssrTransformComponent = (node, context) => {
33986
34029
  }
33987
34030
  };
33988
34031
  };
33989
- function ssrProcessComponent(node, context) {
34032
+ function ssrProcessComponent(node, context, parent) {
33990
34033
  const component = componentTypeMap.get(node);
33991
34034
  if (!node.ssrCodegenNode) {
33992
34035
  // this is a built-in component that fell-through.
@@ -34002,19 +34045,29 @@ function ssrProcessComponent(node, context) {
34002
34045
  else {
34003
34046
  // real fall-through: Transition / KeepAlive
34004
34047
  // just render its children.
34005
- processChildren(node.children, context);
34048
+ // #5352: if is at root level of a slot, push an empty string.
34049
+ // this does not affect the final output, but avoids all-comment slot
34050
+ // content of being treated as empty by ssrRenderSlot().
34051
+ if (parent.type === WIP_SLOT) {
34052
+ context.pushStringPart(``);
34053
+ }
34054
+ // #5351: filter out comment children inside transition
34055
+ if (component === TRANSITION) {
34056
+ node.children = node.children.filter(c => c.type !== 3 /* COMMENT */);
34057
+ }
34058
+ processChildren(node, context);
34006
34059
  }
34007
34060
  }
34008
34061
  else {
34009
34062
  // finish up slot function expressions from the 1st pass.
34010
- const wipEntries = wipMap$1.get(node) || [];
34063
+ const wipEntries = wipMap$2.get(node) || [];
34011
34064
  for (let i = 0; i < wipEntries.length; i++) {
34012
- const { fn, children, vnodeBranch } = wipEntries[i];
34065
+ const { fn, vnodeBranch } = wipEntries[i];
34013
34066
  // For each slot, we generate two branches: one SSR-optimized branch and
34014
34067
  // one normal vnode-based branch. The branches are taken based on the
34015
34068
  // presence of the 2nd `_push` argument (which is only present if the slot
34016
34069
  // is called by `_ssrRenderSlot`.
34017
- fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(children, context, false, true /* withSlotScopeId */), vnodeBranch);
34070
+ fn.body = createIfStatement(createSimpleExpression(`_push`, false), processChildrenAsStatement(wipEntries[i], context, false, true /* withSlotScopeId */), vnodeBranch);
34018
34071
  }
34019
34072
  // component is inside a slot, inherit slot scope Id
34020
34073
  if (context.withSlotScopeId) {
@@ -34134,7 +34187,7 @@ function ssrCodegenTransform(ast, options) {
34134
34187
  context.body.push(createCompoundExpression([`const _cssVars = { style: `, varsExp, `}`]));
34135
34188
  }
34136
34189
  const isFragment = ast.children.length > 1 && ast.children.some(c => !isText(c));
34137
- processChildren(ast.children, context, isFragment);
34190
+ processChildren(ast, context, isFragment);
34138
34191
  ast.codegenNode = createBlockStatement(context.body);
34139
34192
  // Finalize helpers.
34140
34193
  // We need to separate helpers imported from 'vue' vs. '@vue/server-renderer'
@@ -34185,10 +34238,11 @@ function createChildContext(parent, withSlotScopeId = parent.withSlotScopeId) {
34185
34238
  // ensure child inherits parent helpers
34186
34239
  return createSSRTransformContext(parent.root, parent.options, parent.helpers, withSlotScopeId);
34187
34240
  }
34188
- function processChildren(children, context, asFragment = false, disableNestedFragments = false) {
34241
+ function processChildren(parent, context, asFragment = false, disableNestedFragments = false) {
34189
34242
  if (asFragment) {
34190
34243
  context.pushStringPart(`<!--[-->`);
34191
34244
  }
34245
+ const { children } = parent;
34192
34246
  for (let i = 0; i < children.length; i++) {
34193
34247
  const child = children[i];
34194
34248
  switch (child.type) {
@@ -34198,7 +34252,7 @@ function processChildren(children, context, asFragment = false, disableNestedFra
34198
34252
  ssrProcessElement(child, context);
34199
34253
  break;
34200
34254
  case 1 /* COMPONENT */:
34201
- ssrProcessComponent(child, context);
34255
+ ssrProcessComponent(child, context, parent);
34202
34256
  break;
34203
34257
  case 2 /* SLOT */:
34204
34258
  ssrProcessSlotOutlet(child, context);
@@ -34249,9 +34303,9 @@ function processChildren(children, context, asFragment = false, disableNestedFra
34249
34303
  context.pushStringPart(`<!--]-->`);
34250
34304
  }
34251
34305
  }
34252
- function processChildrenAsStatement(children, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
34306
+ function processChildrenAsStatement(parent, parentContext, asFragment = false, withSlotScopeId = parentContext.withSlotScopeId) {
34253
34307
  const childContext = createChildContext(parentContext, withSlotScopeId);
34254
- processChildren(children, childContext, asFragment);
34308
+ processChildren(parent, childContext, asFragment);
34255
34309
  return createBlockStatement(childContext.body);
34256
34310
  }
34257
34311
 
@@ -34370,7 +34424,8 @@ const ssrTransformShow = (dir, node, context) => {
34370
34424
  };
34371
34425
  };
34372
34426
 
34373
- const hasSingleChild = (node) => node.children.filter(n => n.type !== 3 /* COMMENT */).length === 1;
34427
+ const filterChild = (node) => node.children.filter(n => n.type !== 3 /* COMMENT */);
34428
+ const hasSingleChild = (node) => filterChild(node).length === 1;
34374
34429
  const ssrInjectFallthroughAttrs = (node, context) => {
34375
34430
  // _attrs is provided as a function argument.
34376
34431
  // mark it as a known identifier so that it doesn't get prefixed by
@@ -34382,16 +34437,37 @@ const ssrInjectFallthroughAttrs = (node, context) => {
34382
34437
  node.tagType === 1 /* COMPONENT */ &&
34383
34438
  (isBuiltInType(node.tag, 'Transition') ||
34384
34439
  isBuiltInType(node.tag, 'KeepAlive'))) {
34385
- if (hasSingleChild(node)) {
34386
- injectFallthroughAttrs(node.children[0]);
34440
+ const rootChildren = filterChild(context.root);
34441
+ if (rootChildren.length === 1 && rootChildren[0] === node) {
34442
+ if (hasSingleChild(node)) {
34443
+ injectFallthroughAttrs(node.children[0]);
34444
+ }
34445
+ return;
34387
34446
  }
34388
- return;
34389
34447
  }
34390
34448
  const parent = context.parent;
34391
34449
  if (!parent || parent.type !== 0 /* ROOT */) {
34392
34450
  return;
34393
34451
  }
34394
34452
  if (node.type === 10 /* IF_BRANCH */ && hasSingleChild(node)) {
34453
+ // detect cases where the parent v-if is not the only root level node
34454
+ let hasEncounteredIf = false;
34455
+ for (const c of filterChild(parent)) {
34456
+ if (c.type === 9 /* IF */ ||
34457
+ (c.type === 1 /* ELEMENT */ && findDir(c, 'if'))) {
34458
+ // multiple root v-if
34459
+ if (hasEncounteredIf)
34460
+ return;
34461
+ hasEncounteredIf = true;
34462
+ }
34463
+ else if (
34464
+ // node before v-if
34465
+ !hasEncounteredIf ||
34466
+ // non else nodes
34467
+ !(c.type === 1 /* ELEMENT */ && findDir(c, /else/, true))) {
34468
+ return;
34469
+ }
34470
+ }
34395
34471
  injectFallthroughAttrs(node.children[0]);
34396
34472
  }
34397
34473
  else if (hasSingleChild(parent)) {
@@ -34492,11 +34568,12 @@ function compile$1(template, options = {}) {
34492
34568
  ...(options.nodeTransforms || []) // user transforms
34493
34569
  ], directiveTransforms: Object.assign({
34494
34570
  // reusing core v-bind
34495
- bind: transformBind,
34571
+ bind: transformBind, on: transformOn,
34496
34572
  // model and show has dedicated SSR handling
34497
34573
  model: ssrTransformModel, show: ssrTransformShow,
34498
34574
  // the following are ignored during SSR
34499
- on: noopDirectiveTransform, cloak: noopDirectiveTransform, once: noopDirectiveTransform, memo: noopDirectiveTransform }, (options.directiveTransforms || {}) // user transforms
34575
+ // on: noopDirectiveTransform,
34576
+ cloak: noopDirectiveTransform, once: noopDirectiveTransform, memo: noopDirectiveTransform }, (options.directiveTransforms || {}) // user transforms
34500
34577
  ) }));
34501
34578
  // traverse the template AST and convert into SSR codegen AST
34502
34579
  // by replacing ast.codegenNode.
@@ -34704,7 +34781,7 @@ function patchErrors(errors, source, inMap) {
34704
34781
  }
34705
34782
 
34706
34783
  const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
34707
- const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)as(\s*)default/s;
34784
+ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)(?:as)?(\s*)default/s;
34708
34785
  const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
34709
34786
  /**
34710
34787
  * Utility for rewriting `export default` in a script block into a variable
@@ -34739,21 +34816,56 @@ function rewriteDefault(input, as, parserPlugins) {
34739
34816
  s.overwrite(node.start, node.declaration.start, `const ${as} = `);
34740
34817
  }
34741
34818
  if (node.type === 'ExportNamedDeclaration') {
34742
- node.specifiers.forEach(specifier => {
34819
+ for (const specifier of node.specifiers) {
34743
34820
  if (specifier.type === 'ExportSpecifier' &&
34744
34821
  specifier.exported.type === 'Identifier' &&
34745
34822
  specifier.exported.name === 'default') {
34746
- const end = specifier.end;
34747
- s.overwrite(specifier.start, input.charAt(end) === ',' ? end + 1 : end, ``);
34823
+ if (node.source) {
34824
+ if (specifier.local.name === 'default') {
34825
+ const end = specifierEnd(input, specifier.local.end, node.end);
34826
+ s.prepend(`import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n`);
34827
+ s.overwrite(specifier.start, end, ``);
34828
+ s.append(`\nconst ${as} = __VUE_DEFAULT__`);
34829
+ continue;
34830
+ }
34831
+ else {
34832
+ const end = specifierEnd(input, specifier.exported.end, node.end);
34833
+ s.prepend(`import { ${input.slice(specifier.local.start, specifier.local.end)} } from '${node.source.value}'\n`);
34834
+ s.overwrite(specifier.start, end, ``);
34835
+ s.append(`\nconst ${as} = ${specifier.local.name}`);
34836
+ continue;
34837
+ }
34838
+ }
34839
+ const end = specifierEnd(input, specifier.end, node.end);
34840
+ s.overwrite(specifier.start, end, ``);
34748
34841
  s.append(`\nconst ${as} = ${specifier.local.name}`);
34749
34842
  }
34750
- });
34843
+ }
34751
34844
  }
34752
34845
  });
34753
34846
  return s.toString();
34754
34847
  }
34755
34848
  function hasDefaultExport(input) {
34756
34849
  return defaultExportRE.test(input) || namedDefaultExportRE.test(input);
34850
+ }
34851
+ function specifierEnd(input, end, nodeEnd) {
34852
+ // export { default , foo } ...
34853
+ let hasCommas = false;
34854
+ let oldEnd = end;
34855
+ while (end < nodeEnd) {
34856
+ if (/\s/.test(input.charAt(end))) {
34857
+ end++;
34858
+ }
34859
+ else if (input.charAt(end) === ',') {
34860
+ end++;
34861
+ hasCommas = true;
34862
+ break;
34863
+ }
34864
+ else if (input.charAt(end) === '}') {
34865
+ break;
34866
+ }
34867
+ }
34868
+ return hasCommas ? end : oldEnd;
34757
34869
  }
34758
34870
 
34759
34871
  const CONVERT_SYMBOL = '$';
@@ -35280,7 +35392,7 @@ const DEFINE_EXPOSE = 'defineExpose';
35280
35392
  const WITH_DEFAULTS = 'withDefaults';
35281
35393
  // constants
35282
35394
  const DEFAULT_VAR = `__default__`;
35283
- const isBuiltInDir = makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
35395
+ const isBuiltInDir = makeMap(`once,memo,if,for,else,else-if,slot,text,html,on,bind,model,show,cloak,is`);
35284
35396
  /**
35285
35397
  * Compile `<script setup>`
35286
35398
  * It requires the whole SFC descriptor because we need to handle and merge
@@ -36545,6 +36657,7 @@ function inferRuntimeType(node, declaredTypes) {
36545
36657
  case 'WeakSet':
36546
36658
  case 'WeakMap':
36547
36659
  case 'Date':
36660
+ case 'Promise':
36548
36661
  return [node.typeName.name];
36549
36662
  case 'Record':
36550
36663
  case 'Partial':
@@ -36782,7 +36895,7 @@ function resolveTemplateUsageCheckString(sfc) {
36782
36895
  code += `,v${capitalize(camelize(prop.name))}`;
36783
36896
  }
36784
36897
  if (prop.exp) {
36785
- code += `,${processExp(prop.exp.content)}`;
36898
+ code += `,${processExp(prop.exp.content, prop.name)}`;
36786
36899
  }
36787
36900
  }
36788
36901
  }
@@ -36797,8 +36910,19 @@ function resolveTemplateUsageCheckString(sfc) {
36797
36910
  templateUsageCheckCache.set(content, code);
36798
36911
  return code;
36799
36912
  }
36800
- function processExp(exp) {
36801
- if (/ as \w|<.*>/.test(exp)) {
36913
+ const forAliasRE$1 = /([\s\S]*?)\s+(?:in|of)\s+([\s\S]*)/;
36914
+ function processExp(exp, dir) {
36915
+ if (/ as\s+\w|<.*>|:/.test(exp)) {
36916
+ if (dir === 'slot') {
36917
+ exp = `(${exp})=>{}`;
36918
+ }
36919
+ else if (dir === 'for') {
36920
+ const inMatch = exp.match(forAliasRE$1);
36921
+ if (inMatch) {
36922
+ const [, LHS, RHS] = inMatch;
36923
+ return processExp(`(${LHS})=>{}`) + processExp(RHS);
36924
+ }
36925
+ }
36802
36926
  let ret = '';
36803
36927
  // has potential type cast or generic arguments that uses types
36804
36928
  const ast = parseExpression_1(exp, { plugins: ['typescript'] });
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "3.2.34-beta.1",
3
+ "version": "3.2.36",
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.34-beta.1",
37
- "@vue/compiler-dom": "3.2.34-beta.1",
38
- "@vue/compiler-ssr": "3.2.34-beta.1",
39
- "@vue/reactivity-transform": "3.2.34-beta.1",
40
- "@vue/shared": "3.2.34-beta.1",
36
+ "@vue/compiler-core": "3.2.36",
37
+ "@vue/compiler-dom": "3.2.36",
38
+ "@vue/compiler-ssr": "3.2.36",
39
+ "@vue/reactivity-transform": "3.2.36",
40
+ "@vue/shared": "3.2.36",
41
41
  "estree-walker": "^2.0.2",
42
42
  "magic-string": "^0.25.7",
43
43
  "source-map": "^0.6.1",