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

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.
@@ -453,7 +453,13 @@ const capitalize = cacheStringFunction((str) => str.charAt(0).toUpperCase() + st
453
453
  /**
454
454
  * @private
455
455
  */
456
- const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
456
+ const toHandlerKey = cacheStringFunction((str) => str ? `on${capitalize(str)}` : ``);
457
+ const identRE = /^[_$a-zA-Z\xA0-\uFFFF][_$a-zA-Z0-9\xA0-\uFFFF]*$/;
458
+ function genPropsAccessExp(name) {
459
+ return identRE.test(name)
460
+ ? `__props.${name}`
461
+ : `__props[${JSON.stringify(name)}]`;
462
+ }
457
463
 
458
464
  function defaultOnError(error) {
459
465
  throw error;
@@ -20973,6 +20979,7 @@ var sourceMap = {
20973
20979
  };
20974
20980
 
20975
20981
  const PURE_ANNOTATION = `/*#__PURE__*/`;
20982
+ const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
20976
20983
  function createCodegenContext(ast, { mode = 'function', prefixIdentifiers = mode === 'module', sourceMap = false, filename = `template.vue.html`, scopeId = null, optimizeImports = false, runtimeGlobalName = `Vue`, runtimeModuleName = `vue`, ssrRuntimeModuleName = 'vue/server-renderer', ssr = false, isTS = false, inSSR = false }) {
20977
20984
  const context = {
20978
20985
  mode,
@@ -21100,9 +21107,7 @@ function generate(ast, options = {}) {
21100
21107
  // function mode const declarations should be inside with block
21101
21108
  // also they should be renamed to avoid collision with user properties
21102
21109
  if (hasHelpers) {
21103
- push(`const { ${ast.helpers
21104
- .map(s => `${helperNameMap[s]}: _${helperNameMap[s]}`)
21105
- .join(', ')} } = _Vue`);
21110
+ push(`const { ${ast.helpers.map(aliasHelper).join(', ')} } = _Vue`);
21106
21111
  push(`\n`);
21107
21112
  newline();
21108
21113
  }
@@ -21159,7 +21164,6 @@ function genFunctionPreamble(ast, context) {
21159
21164
  const VueBinding = ssr
21160
21165
  ? `require(${JSON.stringify(runtimeModuleName)})`
21161
21166
  : runtimeGlobalName;
21162
- const aliasHelper = (s) => `${helperNameMap[s]}: _${helperNameMap[s]}`;
21163
21167
  // Generate const declaration for helpers
21164
21168
  // In prefix mode, we place the const declaration at top so it's done
21165
21169
  // only once; But if we not prefixing, we place the declaration inside the
@@ -22286,7 +22290,9 @@ asRawStatements = false, localVars = Object.create(context.identifiers)) {
22286
22290
  const isUpdateArg = parent && parent.type === 'UpdateExpression' && parent.argument === id;
22287
22291
  // ({ x } = y)
22288
22292
  const isDestructureAssignment = parent && isInDestructureAssignment(parent, parentStack);
22289
- if (type === "setup-const" /* SETUP_CONST */ || localVars[raw]) {
22293
+ if (type === "setup-const" /* SETUP_CONST */ ||
22294
+ type === "setup-reactive-const" /* SETUP_REACTIVE_CONST */ ||
22295
+ localVars[raw]) {
22290
22296
  return raw;
22291
22297
  }
22292
22298
  else if (type === "setup-ref" /* SETUP_REF */) {
@@ -22340,11 +22346,11 @@ asRawStatements = false, localVars = Object.create(context.identifiers)) {
22340
22346
  else if (type === "props" /* PROPS */) {
22341
22347
  // use __props which is generated by compileScript so in ts mode
22342
22348
  // it gets correct type
22343
- return `__props.${raw}`;
22349
+ return genPropsAccessExp(raw);
22344
22350
  }
22345
22351
  else if (type === "props-aliased" /* PROPS_ALIASED */) {
22346
22352
  // prop with a different local alias (from defineProps() destructure)
22347
- return `__props.${bindingMetadata.__propsAliases[raw]}`;
22353
+ return genPropsAccessExp(bindingMetadata.__propsAliases[raw]);
22348
22354
  }
22349
22355
  }
22350
22356
  else {
@@ -22353,7 +22359,7 @@ asRawStatements = false, localVars = Object.create(context.identifiers)) {
22353
22359
  return `$setup.${raw}`;
22354
22360
  }
22355
22361
  else if (type === "props-aliased" /* PROPS_ALIASED */) {
22356
- return `$props.${bindingMetadata.__propsAliases[raw]}`;
22362
+ return `$props['${bindingMetadata.__propsAliases[raw]}']`;
22357
22363
  }
22358
22364
  else if (type) {
22359
22365
  return `$${type}.${raw}`;
@@ -22614,14 +22620,14 @@ function processIf(node, dir, context, processCodegen) {
22614
22620
  }
22615
22621
  }
22616
22622
  function createIfBranch(node, dir) {
22623
+ const isTemplateIf = node.tagType === 3 /* TEMPLATE */;
22617
22624
  return {
22618
22625
  type: 10 /* IF_BRANCH */,
22619
22626
  loc: node.loc,
22620
22627
  condition: dir.name === 'else' ? undefined : dir.exp,
22621
- children: node.tagType === 3 /* TEMPLATE */ && !findDir(node, 'for')
22622
- ? node.children
22623
- : [node],
22624
- userKey: findProp(node, `key`)
22628
+ children: isTemplateIf && !findDir(node, 'for') ? node.children : [node],
22629
+ userKey: findProp(node, `key`),
22630
+ isTemplateIf
22625
22631
  };
22626
22632
  }
22627
22633
  function createCodegenNodeForBranch(branch, keyIndex, context) {
@@ -22656,7 +22662,8 @@ function createChildrenCodegenNode(branch, keyIndex, context) {
22656
22662
  let patchFlagText = PatchFlagNames[64 /* STABLE_FRAGMENT */];
22657
22663
  // check if the fragment actually contains a single valid child with
22658
22664
  // the rest being comments
22659
- if (children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
22665
+ if (!branch.isTemplateIf &&
22666
+ children.filter(c => c.type !== 3 /* COMMENT */).length === 1) {
22660
22667
  patchFlag |= 2048 /* DEV_ROOT_FRAGMENT */;
22661
22668
  patchFlagText += `, ${PatchFlagNames[2048 /* DEV_ROOT_FRAGMENT */]}`;
22662
22669
  }
@@ -23447,7 +23454,8 @@ function resolveSetupReference(name, context) {
23447
23454
  return PascalName;
23448
23455
  }
23449
23456
  };
23450
- const fromConst = checkType("setup-const" /* SETUP_CONST */);
23457
+ const fromConst = checkType("setup-const" /* SETUP_CONST */) ||
23458
+ checkType("setup-reactive-const" /* SETUP_REACTIVE_CONST */);
23451
23459
  if (fromConst) {
23452
23460
  return context.inline
23453
23461
  ? // in inline mode, const setup bindings (e.g. imports) can be used as-is
@@ -23721,10 +23729,11 @@ function buildProps(node, context, props = node.props, ssr = false) {
23721
23729
  classProp.value = createCallExpression(context.helper(NORMALIZE_CLASS), [classProp.value]);
23722
23730
  }
23723
23731
  if (styleProp &&
23724
- !isStaticExp(styleProp.value) &&
23725
23732
  // the static style is compiled into an object,
23726
23733
  // so use `hasStyleBinding` to ensure that it is a dynamic style binding
23727
23734
  (hasStyleBinding ||
23735
+ (styleProp.value.type === 4 /* SIMPLE_EXPRESSION */ &&
23736
+ styleProp.value.content.trim()[0] === `[`) ||
23728
23737
  // v-bind:style and style both exist,
23729
23738
  // v-bind:style with static literal object
23730
23739
  styleProp.value.type === 17 /* JS_ARRAY_EXPRESSION */)) {
@@ -24115,11 +24124,7 @@ const transformText = (node, context) => {
24115
24124
  const next = children[j];
24116
24125
  if (isText(next)) {
24117
24126
  if (!currentContainer) {
24118
- currentContainer = children[i] = {
24119
- type: 8 /* COMPOUND_EXPRESSION */,
24120
- loc: child.loc,
24121
- children: [child]
24122
- };
24127
+ currentContainer = children[i] = createCompoundExpression([child], child.loc);
24123
24128
  }
24124
24129
  // merge adjacent text node into current
24125
24130
  currentContainer.children.push(` + `, next);
@@ -26903,7 +26908,9 @@ const transformVText = (dir, node, context) => {
26903
26908
  return {
26904
26909
  props: [
26905
26910
  createObjectProperty(createSimpleExpression(`textContent`, true), exp
26906
- ? createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
26911
+ ? getConstantType(exp, context) > 0
26912
+ ? exp
26913
+ : createCallExpression(context.helperString(TO_DISPLAY_STRING), [exp], loc)
26907
26914
  : createSimpleExpression('', true))
26908
26915
  ]
26909
26916
  };
@@ -27111,19 +27118,38 @@ const transformShow = (dir, node, context) => {
27111
27118
  };
27112
27119
  };
27113
27120
 
27114
- const warnTransitionChildren = (node, context) => {
27121
+ const transformTransition = (node, context) => {
27115
27122
  if (node.type === 1 /* ELEMENT */ &&
27116
27123
  node.tagType === 1 /* COMPONENT */) {
27117
27124
  const component = context.isBuiltInComponent(node.tag);
27118
27125
  if (component === TRANSITION) {
27119
27126
  return () => {
27120
- if (node.children.length && hasMultipleChildren(node)) {
27127
+ if (!node.children.length) {
27128
+ return;
27129
+ }
27130
+ // warn multiple transition children
27131
+ if (hasMultipleChildren(node)) {
27121
27132
  context.onError(createDOMCompilerError(59 /* X_TRANSITION_INVALID_CHILDREN */, {
27122
27133
  start: node.children[0].loc.start,
27123
27134
  end: node.children[node.children.length - 1].loc.end,
27124
27135
  source: ''
27125
27136
  }));
27126
27137
  }
27138
+ // check if it's s single child w/ v-show
27139
+ // if yes, inject "persisted: true" to the transition props
27140
+ const child = node.children[0];
27141
+ if (child.type === 1 /* ELEMENT */) {
27142
+ for (const p of child.props) {
27143
+ if (p.type === 7 /* DIRECTIVE */ && p.name === 'show') {
27144
+ node.props.push({
27145
+ type: 6 /* ATTRIBUTE */,
27146
+ name: 'persisted',
27147
+ value: undefined,
27148
+ loc: node.loc
27149
+ });
27150
+ }
27151
+ }
27152
+ }
27127
27153
  };
27128
27154
  }
27129
27155
  }
@@ -27339,6 +27365,7 @@ function stringifyNode(node, context) {
27339
27365
  }
27340
27366
  function stringifyElement(node, context) {
27341
27367
  let res = `<${node.tag}`;
27368
+ let innerHTML = '';
27342
27369
  for (let i = 0; i < node.props.length; i++) {
27343
27370
  const p = node.props[i];
27344
27371
  if (p.type === 6 /* ATTRIBUTE */) {
@@ -27347,25 +27374,35 @@ function stringifyElement(node, context) {
27347
27374
  res += `="${escapeHtml(p.value.content)}"`;
27348
27375
  }
27349
27376
  }
27350
- else if (p.type === 7 /* DIRECTIVE */ && p.name === 'bind') {
27351
- const exp = p.exp;
27352
- if (exp.content[0] === '_') {
27353
- // internally generated string constant references
27354
- // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
27355
- res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
27356
- continue;
27357
- }
27358
- // constant v-bind, e.g. :foo="1"
27359
- let evaluated = evaluateConstant(exp);
27360
- if (evaluated != null) {
27361
- const arg = p.arg && p.arg.content;
27362
- if (arg === 'class') {
27363
- evaluated = normalizeClass(evaluated);
27377
+ else if (p.type === 7 /* DIRECTIVE */) {
27378
+ if (p.name === 'bind') {
27379
+ const exp = p.exp;
27380
+ if (exp.content[0] === '_') {
27381
+ // internally generated string constant references
27382
+ // e.g. imported URL strings via compiler-sfc transformAssetUrl plugin
27383
+ res += ` ${p.arg.content}="__VUE_EXP_START__${exp.content}__VUE_EXP_END__"`;
27384
+ continue;
27364
27385
  }
27365
- else if (arg === 'style') {
27366
- evaluated = stringifyStyle(normalizeStyle(evaluated));
27386
+ // constant v-bind, e.g. :foo="1"
27387
+ let evaluated = evaluateConstant(exp);
27388
+ if (evaluated != null) {
27389
+ const arg = p.arg && p.arg.content;
27390
+ if (arg === 'class') {
27391
+ evaluated = normalizeClass(evaluated);
27392
+ }
27393
+ else if (arg === 'style') {
27394
+ evaluated = stringifyStyle(normalizeStyle(evaluated));
27395
+ }
27396
+ res += ` ${p.arg.content}="${escapeHtml(evaluated)}"`;
27367
27397
  }
27368
- res += ` ${p.arg.content}="${escapeHtml(evaluated)}"`;
27398
+ }
27399
+ else if (p.name === 'html') {
27400
+ // #5439 v-html with constant value
27401
+ // not sure why would anyone do this but it can happen
27402
+ innerHTML = evaluateConstant(p.exp);
27403
+ }
27404
+ else if (p.name === 'text') {
27405
+ innerHTML = escapeHtml(toDisplayString(evaluateConstant(p.exp)));
27369
27406
  }
27370
27407
  }
27371
27408
  }
@@ -27373,8 +27410,13 @@ function stringifyElement(node, context) {
27373
27410
  res += ` ${context.scopeId}`;
27374
27411
  }
27375
27412
  res += `>`;
27376
- for (let i = 0; i < node.children.length; i++) {
27377
- res += stringifyNode(node.children[i], context);
27413
+ if (innerHTML) {
27414
+ res += innerHTML;
27415
+ }
27416
+ else {
27417
+ for (let i = 0; i < node.children.length; i++) {
27418
+ res += stringifyNode(node.children[i], context);
27419
+ }
27378
27420
  }
27379
27421
  if (!isVoidTag(node.tag)) {
27380
27422
  res += `</${node.tag}>`;
@@ -27387,7 +27429,7 @@ function stringifyElement(node, context) {
27387
27429
  // here, e.g. `{{ 1 }}` or `{{ 'foo' }}`
27388
27430
  // in addition, constant exps bail on presence of parens so you can't even
27389
27431
  // run JSFuck in here. But we mark it unsafe for security review purposes.
27390
- // (see compiler-core/src/transformExpressions)
27432
+ // (see compiler-core/src/transforms/transformExpression)
27391
27433
  function evaluateConstant(exp) {
27392
27434
  if (exp.type === 4 /* SIMPLE_EXPRESSION */) {
27393
27435
  return new Function(`return ${exp.content}`)();
@@ -27424,7 +27466,7 @@ const ignoreSideEffectTags = (node, context) => {
27424
27466
 
27425
27467
  const DOMNodeTransforms = [
27426
27468
  transformStyle,
27427
- ...([warnTransitionChildren] )
27469
+ ...([transformTransition] )
27428
27470
  ];
27429
27471
  const DOMDirectiveTransforms = {
27430
27472
  cloak: noopDirectiveTransform,
@@ -27497,6 +27539,7 @@ var CompilerDOM = /*#__PURE__*/Object.freeze({
27497
27539
  buildProps: buildProps,
27498
27540
  buildDirectiveArgs: buildDirectiveArgs,
27499
27541
  processSlotOutlet: processSlotOutlet,
27542
+ getConstantType: getConstantType,
27500
27543
  generateCodeFrame: generateCodeFrame,
27501
27544
  checkCompatEnabled: checkCompatEnabled,
27502
27545
  warnDeprecation: warnDeprecation,
@@ -27668,9 +27711,9 @@ var hashSum = sum;
27668
27711
  const CSS_VARS_HELPER = `useCssVars`;
27669
27712
  // match v-bind() with max 2-levels of nested parens.
27670
27713
  const cssVarRE = /v-bind\s*\(((?:[^)(]+|\((?:[^)(]+|\([^)(]*\))*\))*)\)/g;
27671
- function genCssVarsFromList(vars, id, isProd) {
27714
+ function genCssVarsFromList(vars, id, isProd, isSSR = false) {
27672
27715
  return `{\n ${vars
27673
- .map(key => `"${genVarName(id, key, isProd)}": (${key})`)
27716
+ .map(key => `"${isSSR ? `--` : ``}${genVarName(id, key, isProd)}": (${key})`)
27674
27717
  .join(',\n ')}\n}`;
27675
27718
  }
27676
27719
  function genVarName(id, raw, isProd) {
@@ -27681,7 +27724,7 @@ function genVarName(id, raw, isProd) {
27681
27724
  return `${id}-${raw.replace(/([^\w-])/g, '_')}`;
27682
27725
  }
27683
27726
  }
27684
- function noramlizeExpression(exp) {
27727
+ function normalizeExpression(exp) {
27685
27728
  exp = exp.trim();
27686
27729
  if ((exp[0] === `'` && exp[exp.length - 1] === `'`) ||
27687
27730
  (exp[0] === `"` && exp[exp.length - 1] === `"`)) {
@@ -27696,7 +27739,7 @@ function parseCssVars(sfc) {
27696
27739
  // ignore v-bind() in comments /* ... */
27697
27740
  const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '');
27698
27741
  while ((match = cssVarRE.exec(content))) {
27699
- const variable = noramlizeExpression(match[1]);
27742
+ const variable = normalizeExpression(match[1]);
27700
27743
  if (!vars.includes(variable)) {
27701
27744
  vars.push(variable);
27702
27745
  }
@@ -27712,7 +27755,7 @@ const cssVarsPlugin = opts => {
27712
27755
  // rewrite CSS variables
27713
27756
  if (cssVarRE.test(decl.value)) {
27714
27757
  decl.value = decl.value.replace(cssVarRE, (_, $1) => {
27715
- return `var(--${genVarName(id, noramlizeExpression($1), isProd)})`;
27758
+ return `var(--${genVarName(id, normalizeExpression($1), isProd)})`;
27716
27759
  });
27717
27760
  }
27718
27761
  }
@@ -33166,6 +33209,10 @@ function getImportsExpressionExp(path, hash, loc, context) {
33166
33209
  return exp;
33167
33210
  }
33168
33211
  const hashExp = `${name} + '${hash}'`;
33212
+ const finalExp = createSimpleExpression(hashExp, false, loc, 3 /* CAN_STRINGIFY */);
33213
+ if (!context.hoistStatic) {
33214
+ return finalExp;
33215
+ }
33169
33216
  const existingHoistIndex = context.hoists.findIndex(h => {
33170
33217
  return (h &&
33171
33218
  h.type === 4 /* SIMPLE_EXPRESSION */ &&
@@ -33175,7 +33222,7 @@ function getImportsExpressionExp(path, hash, loc, context) {
33175
33222
  if (existingHoistIndex > -1) {
33176
33223
  return createSimpleExpression(`_hoisted_${existingHoistIndex + 1}`, false, loc, 3 /* CAN_STRINGIFY */);
33177
33224
  }
33178
- return context.hoist(createSimpleExpression(hashExp, false, loc, 3 /* CAN_STRINGIFY */));
33225
+ return context.hoist(finalExp);
33179
33226
  }
33180
33227
  else {
33181
33228
  return createSimpleExpression(`''`, false, loc, 3 /* CAN_STRINGIFY */);
@@ -33217,35 +33264,41 @@ const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
33217
33264
  imageCandidates.splice(i, 1);
33218
33265
  }
33219
33266
  }
33220
- const hasQualifiedUrl = imageCandidates.some(({ url }) => {
33267
+ const shouldProcessUrl = (url) => {
33221
33268
  return (!isExternalUrl(url) &&
33222
33269
  !isDataUrl(url) &&
33223
33270
  (options.includeAbsolute || isRelativeUrl(url)));
33224
- });
33271
+ };
33225
33272
  // When srcset does not contain any qualified URLs, skip transforming
33226
- if (!hasQualifiedUrl) {
33273
+ if (!imageCandidates.some(({ url }) => shouldProcessUrl(url))) {
33227
33274
  return;
33228
33275
  }
33229
33276
  if (options.base) {
33230
33277
  const base = options.base;
33231
33278
  const set = [];
33232
- imageCandidates.forEach(({ url, descriptor }) => {
33279
+ let needImportTransform = false;
33280
+ imageCandidates.forEach(candidate => {
33281
+ let { url, descriptor } = candidate;
33233
33282
  descriptor = descriptor ? ` ${descriptor}` : ``;
33234
- if (isRelativeUrl(url)) {
33235
- set.push((path.posix || path).join(base, url) + descriptor);
33283
+ if (url[0] === '.') {
33284
+ candidate.url = (path.posix || path).join(base, url);
33285
+ set.push(candidate.url + descriptor);
33286
+ }
33287
+ else if (shouldProcessUrl(url)) {
33288
+ needImportTransform = true;
33236
33289
  }
33237
33290
  else {
33238
33291
  set.push(url + descriptor);
33239
33292
  }
33240
33293
  });
33241
- attr.value.content = set.join(', ');
33242
- return;
33294
+ if (!needImportTransform) {
33295
+ attr.value.content = set.join(', ');
33296
+ return;
33297
+ }
33243
33298
  }
33244
33299
  const compoundExpression = createCompoundExpression([], attr.loc);
33245
33300
  imageCandidates.forEach(({ url, descriptor }, index) => {
33246
- if (!isExternalUrl(url) &&
33247
- !isDataUrl(url) &&
33248
- (options.includeAbsolute || isRelativeUrl(url))) {
33301
+ if (shouldProcessUrl(url)) {
33249
33302
  const { path } = parseUrl(url);
33250
33303
  let exp;
33251
33304
  if (path) {
@@ -33275,13 +33328,16 @@ const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
33275
33328
  compoundExpression.children.push(` + ', ' + `);
33276
33329
  }
33277
33330
  });
33278
- const hoisted = context.hoist(compoundExpression);
33279
- hoisted.constType = 3 /* CAN_STRINGIFY */;
33331
+ let exp = compoundExpression;
33332
+ if (context.hoistStatic) {
33333
+ exp = context.hoist(compoundExpression);
33334
+ exp.constType = 3 /* CAN_STRINGIFY */;
33335
+ }
33280
33336
  node.props[index] = {
33281
33337
  type: 7 /* DIRECTIVE */,
33282
33338
  name: 'bind',
33283
33339
  arg: createSimpleExpression('srcset', true, attr.loc),
33284
- exp: hoisted,
33340
+ exp,
33285
33341
  modifiers: [],
33286
33342
  loc: attr.loc
33287
33343
  };
@@ -33295,6 +33351,7 @@ const SSR_INTERPOLATE = Symbol(`ssrInterpolate`);
33295
33351
  const SSR_RENDER_VNODE = Symbol(`ssrRenderVNode`);
33296
33352
  const SSR_RENDER_COMPONENT = Symbol(`ssrRenderComponent`);
33297
33353
  const SSR_RENDER_SLOT = Symbol(`ssrRenderSlot`);
33354
+ const SSR_RENDER_SLOT_INNER = Symbol(`ssrRenderSlotInner`);
33298
33355
  const SSR_RENDER_CLASS = Symbol(`ssrRenderClass`);
33299
33356
  const SSR_RENDER_STYLE = Symbol(`ssrRenderStyle`);
33300
33357
  const SSR_RENDER_ATTRS = Symbol(`ssrRenderAttrs`);
@@ -33314,6 +33371,7 @@ const ssrHelpers = {
33314
33371
  [SSR_RENDER_VNODE]: `ssrRenderVNode`,
33315
33372
  [SSR_RENDER_COMPONENT]: `ssrRenderComponent`,
33316
33373
  [SSR_RENDER_SLOT]: `ssrRenderSlot`,
33374
+ [SSR_RENDER_SLOT_INNER]: `ssrRenderSlotInner`,
33317
33375
  [SSR_RENDER_CLASS]: `ssrRenderClass`,
33318
33376
  [SSR_RENDER_STYLE]: `ssrRenderStyle`,
33319
33377
  [SSR_RENDER_ATTRS]: `ssrRenderAttrs`,
@@ -33407,7 +33465,20 @@ const ssrTransformSlotOutlet = (node, context) => {
33407
33465
  if (context.scopeId && context.slotted !== false) {
33408
33466
  args.push(`"${context.scopeId}-s"`);
33409
33467
  }
33410
- node.ssrCodegenNode = createCallExpression(context.helper(SSR_RENDER_SLOT), args);
33468
+ let method = SSR_RENDER_SLOT;
33469
+ // #3989
33470
+ // check if this is a single slot inside a transition wrapper - since
33471
+ // transition will unwrap the slot fragment into a single vnode at runtime,
33472
+ // we need to avoid rendering the slot as a fragment.
33473
+ const parent = context.parent;
33474
+ if (parent &&
33475
+ parent.type === 1 /* ELEMENT */ &&
33476
+ parent.tagType === 1 /* COMPONENT */ &&
33477
+ resolveComponentType(parent, context, true) === TRANSITION &&
33478
+ parent.children.filter(c => c.type === 1 /* ELEMENT */).length === 1) {
33479
+ method = SSR_RENDER_SLOT_INNER;
33480
+ }
33481
+ node.ssrCodegenNode = createCallExpression(context.helper(method), args);
33411
33482
  }
33412
33483
  };
33413
33484
  function ssrProcessSlotOutlet(node, context) {
@@ -34547,7 +34618,7 @@ function doCompileTemplate({ filename, id, scoped, slotted, inMap, source, ssr =
34547
34618
  const shortId = id.replace(/^data-v-/, '');
34548
34619
  const longId = `data-v-${shortId}`;
34549
34620
  let { code, ast, preamble, map } = compiler.compile(source, Object.assign(Object.assign({ mode: 'module', prefixIdentifiers: true, hoistStatic: true, cacheHandlers: true, ssrCssVars: ssr && ssrCssVars && ssrCssVars.length
34550
- ? genCssVarsFromList(ssrCssVars, shortId, isProd)
34621
+ ? genCssVarsFromList(ssrCssVars, shortId, isProd, true)
34551
34622
  : '', scopeId: scoped ? longId : undefined, slotted, sourceMap: true }, compilerOptions), { nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []), filename, onError: e => errors.push(e), onWarn: w => warnings.push(w) }));
34552
34623
  // inMap should be the map produced by ./parse.ts which is a simple line-only
34553
34624
  // mapping. If it is present, we need to adjust the final map and errors to
@@ -35045,13 +35116,13 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
35045
35116
  if (isProp) {
35046
35117
  if (escapeScope) {
35047
35118
  // prop binding in $$()
35048
- // { prop } -> { prop: __prop_prop }
35119
+ // { prop } -> { prop: __props_prop }
35049
35120
  registerEscapedPropBinding(id);
35050
35121
  s.appendLeft(id.end + offset, `: __props_${propsLocalToPublicMap[id.name]}`);
35051
35122
  }
35052
35123
  else {
35053
- // { prop } -> { prop: __prop.prop }
35054
- s.appendLeft(id.end + offset, `: __props.${propsLocalToPublicMap[id.name]}`);
35124
+ // { prop } -> { prop: __props.prop }
35125
+ s.appendLeft(id.end + offset, `: ${genPropsAccessExp(propsLocalToPublicMap[id.name])}`);
35055
35126
  }
35056
35127
  }
35057
35128
  else {
@@ -35069,7 +35140,7 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
35069
35140
  }
35070
35141
  else {
35071
35142
  // x --> __props.x
35072
- s.overwrite(id.start + offset, id.end + offset, `__props.${propsLocalToPublicMap[id.name]}`);
35143
+ s.overwrite(id.start + offset, id.end + offset, genPropsAccessExp(propsLocalToPublicMap[id.name]));
35073
35144
  }
35074
35145
  }
35075
35146
  else {
@@ -35216,6 +35287,7 @@ const isBuiltInDir = makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,m
35216
35287
  * normal `<script>` + `<script setup>` if both are present.
35217
35288
  */
35218
35289
  function compileScript(sfc, options) {
35290
+ var _a;
35219
35291
  let { script, scriptSetup, source, filename } = sfc;
35220
35292
  // feature flags
35221
35293
  // TODO remove support for deprecated options when out of experimental
@@ -35244,6 +35316,11 @@ function compileScript(sfc, options) {
35244
35316
  if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
35245
35317
  plugins.push('jsx');
35246
35318
  }
35319
+ else {
35320
+ // If don't match the case of adding jsx, should remove the jsx from the babelParserPlugins
35321
+ if (options.babelParserPlugins)
35322
+ options.babelParserPlugins = options.babelParserPlugins.filter(n => n !== 'jsx');
35323
+ }
35247
35324
  if (options.babelParserPlugins)
35248
35325
  plugins.push(...options.babelParserPlugins);
35249
35326
  if (isTS)
@@ -35319,6 +35396,8 @@ function compileScript(sfc, options) {
35319
35396
  let hasDefinePropsCall = false;
35320
35397
  let hasDefineEmitCall = false;
35321
35398
  let hasDefineExposeCall = false;
35399
+ let hasDefaultExportName = false;
35400
+ let hasDefaultExportRender = false;
35322
35401
  let propsRuntimeDecl;
35323
35402
  let propsRuntimeDefaults;
35324
35403
  let propsDestructureDecl;
@@ -35361,12 +35440,18 @@ function compileScript(sfc, options) {
35361
35440
  function error(msg, node, end = node.end + startOffset) {
35362
35441
  throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${generateCodeFrame(source, node.start + startOffset, end)}`);
35363
35442
  }
35364
- function registerUserImport(source, local, imported, isType, isFromSetup) {
35443
+ function registerUserImport(source, local, imported, isType, isFromSetup, needTemplateUsageCheck) {
35365
35444
  if (source === 'vue' && imported) {
35366
35445
  userImportAlias[imported] = local;
35367
35446
  }
35368
- let isUsedInTemplate = true;
35369
- if (isTS && sfc.template && !sfc.template.src && !sfc.template.lang) {
35447
+ // template usage check is only needed in non-inline mode, so we can skip
35448
+ // the work if inlineTemplate is true.
35449
+ let isUsedInTemplate = needTemplateUsageCheck;
35450
+ if (needTemplateUsageCheck &&
35451
+ isTS &&
35452
+ sfc.template &&
35453
+ !sfc.template.src &&
35454
+ !sfc.template.lang) {
35370
35455
  isUsedInTemplate = isImportUsed(local, sfc);
35371
35456
  }
35372
35457
  userImports[local] = {
@@ -35408,7 +35493,9 @@ function compileScript(sfc, options) {
35408
35493
  if (prop.computed) {
35409
35494
  error(`${DEFINE_PROPS}() destructure cannot use computed key.`, prop.key);
35410
35495
  }
35411
- const propKey = prop.key.name;
35496
+ const propKey = prop.key.type === 'StringLiteral'
35497
+ ? prop.key.value
35498
+ : prop.key.name;
35412
35499
  if (prop.value.type === 'AssignmentPattern') {
35413
35500
  // default value { foo = 123 }
35414
35501
  const { left, right } = prop.value;
@@ -35637,7 +35724,7 @@ function compileScript(sfc, options) {
35637
35724
  if (destructured && destructured.default) {
35638
35725
  const value = scriptSetup.content.slice(destructured.default.start, destructured.default.end);
35639
35726
  const isLiteral = destructured.default.type.endsWith('Literal');
35640
- return isLiteral ? value : `() => ${value}`;
35727
+ return isLiteral ? value : `() => (${value})`;
35641
35728
  }
35642
35729
  }
35643
35730
  function genSetupPropsType(node) {
@@ -35687,12 +35774,40 @@ function compileScript(sfc, options) {
35687
35774
  specifier.imported.name;
35688
35775
  registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type' ||
35689
35776
  (specifier.type === 'ImportSpecifier' &&
35690
- specifier.importKind === 'type'), false);
35777
+ specifier.importKind === 'type'), false, !options.inlineTemplate);
35691
35778
  }
35692
35779
  }
35693
35780
  else if (node.type === 'ExportDefaultDeclaration') {
35694
35781
  // export default
35695
35782
  defaultExport = node;
35783
+ // check if user has manually specified `name` or 'render` option in
35784
+ // export default
35785
+ // if has name, skip name inference
35786
+ // if has render and no template, generate return object instead of
35787
+ // empty render function (#4980)
35788
+ let optionProperties;
35789
+ if (defaultExport.declaration.type === 'ObjectExpression') {
35790
+ optionProperties = defaultExport.declaration.properties;
35791
+ }
35792
+ else if (defaultExport.declaration.type === 'CallExpression' &&
35793
+ defaultExport.declaration.arguments[0].type === 'ObjectExpression') {
35794
+ optionProperties = defaultExport.declaration.arguments[0].properties;
35795
+ }
35796
+ if (optionProperties) {
35797
+ for (const s of optionProperties) {
35798
+ if (s.type === 'ObjectProperty' &&
35799
+ s.key.type === 'Identifier' &&
35800
+ s.key.name === 'name') {
35801
+ hasDefaultExportName = true;
35802
+ }
35803
+ if ((s.type === 'ObjectMethod' || s.type === 'ObjectProperty') &&
35804
+ s.key.type === 'Identifier' &&
35805
+ s.key.name === 'render') {
35806
+ // TODO warn when we provide a better way to do it?
35807
+ hasDefaultExportRender = true;
35808
+ }
35809
+ }
35810
+ }
35696
35811
  // export default { ... } --> const __default__ = { ... }
35697
35812
  const start = node.start + scriptStartOffset;
35698
35813
  const end = node.declaration.start + scriptStartOffset;
@@ -35745,6 +35860,10 @@ function compileScript(sfc, options) {
35745
35860
  // we need to move the block up so that `const __default__` is
35746
35861
  // declared before being used in the actual component definition
35747
35862
  if (scriptStartOffset > startOffset) {
35863
+ // if content doesn't end with newline, add one
35864
+ if (!/\n$/.test(script.content.trim())) {
35865
+ s.appendLeft(scriptEndOffset, `\n`);
35866
+ }
35748
35867
  s.move(scriptStartOffset, scriptEndOffset, 0);
35749
35868
  }
35750
35869
  }
@@ -35799,9 +35918,12 @@ function compileScript(sfc, options) {
35799
35918
  for (let i = 0; i < node.specifiers.length; i++) {
35800
35919
  const specifier = node.specifiers[i];
35801
35920
  const local = specifier.local.name;
35802
- const imported = specifier.type === 'ImportSpecifier' &&
35921
+ let imported = specifier.type === 'ImportSpecifier' &&
35803
35922
  specifier.imported.type === 'Identifier' &&
35804
35923
  specifier.imported.name;
35924
+ if (specifier.type === 'ImportNamespaceSpecifier') {
35925
+ imported = '*';
35926
+ }
35805
35927
  const source = node.source.value;
35806
35928
  const existing = userImports[local];
35807
35929
  if (source === 'vue' &&
@@ -35823,7 +35945,7 @@ function compileScript(sfc, options) {
35823
35945
  else {
35824
35946
  registerUserImport(source, local, imported, node.importKind === 'type' ||
35825
35947
  (specifier.type === 'ImportSpecifier' &&
35826
- specifier.importKind === 'type'), true);
35948
+ specifier.importKind === 'type'), true, !options.inlineTemplate);
35827
35949
  }
35828
35950
  }
35829
35951
  if (node.specifiers.length && removed === node.specifiers.length) {
@@ -35886,18 +36008,33 @@ function compileScript(sfc, options) {
35886
36008
  // await
35887
36009
  if ((node.type === 'VariableDeclaration' && !node.declare) ||
35888
36010
  node.type.endsWith('Statement')) {
36011
+ const scope = [scriptSetupAst.body];
35889
36012
  walk$1(node, {
35890
36013
  enter(child, parent) {
35891
36014
  if (isFunctionType(child)) {
35892
36015
  this.skip();
35893
36016
  }
36017
+ if (child.type === 'BlockStatement') {
36018
+ scope.push(child.body);
36019
+ }
35894
36020
  if (child.type === 'AwaitExpression') {
35895
36021
  hasAwait = true;
35896
- const needsSemi = scriptSetupAst.body.some(n => {
35897
- return n.type === 'ExpressionStatement' && n.start === child.start;
36022
+ // if the await expression is an expression statement and
36023
+ // - is in the root scope
36024
+ // - or is not the first statement in a nested block scope
36025
+ // then it needs a semicolon before the generated code.
36026
+ const currentScope = scope[scope.length - 1];
36027
+ const needsSemi = currentScope.some((n, i) => {
36028
+ return ((scope.length === 1 || i > 0) &&
36029
+ n.type === 'ExpressionStatement' &&
36030
+ n.start === child.start);
35898
36031
  });
35899
36032
  processAwait(child, needsSemi, parent.type === 'ExpressionStatement');
35900
36033
  }
36034
+ },
36035
+ exit(node) {
36036
+ if (node.type === 'BlockStatement')
36037
+ scope.pop();
35901
36038
  }
35902
36039
  });
35903
36040
  }
@@ -35946,7 +36083,7 @@ function compileScript(sfc, options) {
35946
36083
  checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
35947
36084
  checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
35948
36085
  checkInvalidScopeReference(propsDestructureDecl, DEFINE_PROPS);
35949
- checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
36086
+ checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_EMITS);
35950
36087
  // 6. remove non-script content
35951
36088
  if (script) {
35952
36089
  if (startOffset < scriptStartOffset) {
@@ -35982,7 +36119,8 @@ function compileScript(sfc, options) {
35982
36119
  // props aliases
35983
36120
  if (propsDestructureDecl) {
35984
36121
  if (propsDestructureRestId) {
35985
- bindingMetadata[propsDestructureRestId] = "setup-const" /* SETUP_CONST */;
36122
+ bindingMetadata[propsDestructureRestId] =
36123
+ "setup-reactive-const" /* SETUP_REACTIVE_CONST */;
35986
36124
  }
35987
36125
  for (const key in propsDestructuredBindings) {
35988
36126
  const { local } = propsDestructuredBindings[key];
@@ -35997,7 +36135,9 @@ function compileScript(sfc, options) {
35997
36135
  if (isType)
35998
36136
  continue;
35999
36137
  bindingMetadata[key] =
36000
- (imported === 'default' && source.endsWith('.vue')) || source === 'vue'
36138
+ imported === '*' ||
36139
+ (imported === 'default' && source.endsWith('.vue')) ||
36140
+ source === 'vue'
36001
36141
  ? "setup-const" /* SETUP_CONST */
36002
36142
  : "setup-maybe-ref" /* SETUP_MAYBE_REF */;
36003
36143
  }
@@ -36014,7 +36154,9 @@ function compileScript(sfc, options) {
36014
36154
  }
36015
36155
  }
36016
36156
  // 8. inject `useCssVars` calls
36017
- if (cssVars.length) {
36157
+ if (cssVars.length &&
36158
+ // no need to do this when targeting SSR
36159
+ !(options.inlineTemplate && ((_a = options.templateOptions) === null || _a === void 0 ? void 0 : _a.ssr))) {
36018
36160
  helperImports.add(CSS_VARS_HELPER);
36019
36161
  helperImports.add('unref');
36020
36162
  s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, isProd)}\n`);
@@ -36053,7 +36195,19 @@ function compileScript(sfc, options) {
36053
36195
  }
36054
36196
  // 10. generate return statement
36055
36197
  let returned;
36056
- if (options.inlineTemplate) {
36198
+ if (!options.inlineTemplate || (!sfc.template && hasDefaultExportRender)) {
36199
+ // non-inline mode, or has manual render in normal <script>
36200
+ // return bindings from script and script setup
36201
+ const allBindings = Object.assign(Object.assign({}, scriptBindings), setupBindings);
36202
+ for (const key in userImports) {
36203
+ if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
36204
+ allBindings[key] = true;
36205
+ }
36206
+ }
36207
+ returned = `{ ${Object.keys(allBindings).join(', ')} }`;
36208
+ }
36209
+ else {
36210
+ // inline mode
36057
36211
  if (sfc.template && !sfc.template.src) {
36058
36212
  if (options.templateOptions && options.templateOptions.ssr) {
36059
36213
  hasInlinedSsrRenderFn = true;
@@ -36096,16 +36250,6 @@ function compileScript(sfc, options) {
36096
36250
  returned = `() => {}`;
36097
36251
  }
36098
36252
  }
36099
- else {
36100
- // return bindings from script and script setup
36101
- const allBindings = Object.assign(Object.assign({}, scriptBindings), setupBindings);
36102
- for (const key in userImports) {
36103
- if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
36104
- allBindings[key] = true;
36105
- }
36106
- }
36107
- returned = `{ ${Object.keys(allBindings).join(', ')} }`;
36108
- }
36109
36253
  if (!options.inlineTemplate && !false) {
36110
36254
  // in non-inline mode, the `__isScriptSetup: true` flag is used by
36111
36255
  // componentPublicInstance proxy to allow properties that start with $ or _
@@ -36119,6 +36263,12 @@ function compileScript(sfc, options) {
36119
36263
  }
36120
36264
  // 11. finalize default export
36121
36265
  let runtimeOptions = ``;
36266
+ if (!hasDefaultExportName && filename && filename !== DEFAULT_FILENAME) {
36267
+ const match = filename.match(/([^/\\]+)\.\w+$/);
36268
+ if (match) {
36269
+ runtimeOptions += `\n name: '${match[1]}',`;
36270
+ }
36271
+ }
36122
36272
  if (hasInlinedSsrRenderFn) {
36123
36273
  runtimeOptions += `\n __ssrInlineRender: true,`;
36124
36274
  }
@@ -36208,14 +36358,18 @@ function walkDeclaration(node, bindings, userImportAlias) {
36208
36358
  const userReactiveBinding = userImportAlias['reactive'] || 'reactive';
36209
36359
  if (isCallOf(init, userReactiveBinding)) {
36210
36360
  // treat reactive() calls as let since it's meant to be mutable
36211
- bindingType = "setup-let" /* SETUP_LET */;
36361
+ bindingType = isConst
36362
+ ? "setup-reactive-const" /* SETUP_REACTIVE_CONST */
36363
+ : "setup-let" /* SETUP_LET */;
36212
36364
  }
36213
36365
  else if (
36214
36366
  // if a declaration is a const literal, we can mark it so that
36215
36367
  // the generated render fn code doesn't need to unref() it
36216
36368
  isDefineCall ||
36217
36369
  (isConst && canNeverBeRef(init, userReactiveBinding))) {
36218
- bindingType = "setup-const" /* SETUP_CONST */;
36370
+ bindingType = isCallOf(init, DEFINE_PROPS)
36371
+ ? "setup-reactive-const" /* SETUP_REACTIVE_CONST */
36372
+ : "setup-const" /* SETUP_CONST */;
36219
36373
  }
36220
36374
  else if (isConst) {
36221
36375
  if (isCallOf(init, userImportAlias['ref'] || 'ref')) {
@@ -36628,13 +36782,13 @@ function resolveTemplateUsageCheckString(sfc) {
36628
36782
  code += `,v${capitalize(camelize(prop.name))}`;
36629
36783
  }
36630
36784
  if (prop.exp) {
36631
- code += `,${stripStrings(prop.exp.content)}`;
36785
+ code += `,${processExp(prop.exp.content)}`;
36632
36786
  }
36633
36787
  }
36634
36788
  }
36635
36789
  }
36636
36790
  else if (node.type === 5 /* INTERPOLATION */) {
36637
- code += `,${stripStrings(node.content.content)}`;
36791
+ code += `,${processExp(node.content.content)}`;
36638
36792
  }
36639
36793
  }
36640
36794
  ]
@@ -36643,6 +36797,18 @@ function resolveTemplateUsageCheckString(sfc) {
36643
36797
  templateUsageCheckCache.set(content, code);
36644
36798
  return code;
36645
36799
  }
36800
+ function processExp(exp) {
36801
+ if (/ as \w|<.*>/.test(exp)) {
36802
+ let ret = '';
36803
+ // has potential type cast or generic arguments that uses types
36804
+ const ast = parseExpression_1(exp, { plugins: ['typescript'] });
36805
+ walkIdentifiers(ast, node => {
36806
+ ret += `,` + node.name;
36807
+ });
36808
+ return ret;
36809
+ }
36810
+ return stripStrings(exp);
36811
+ }
36646
36812
  function stripStrings(exp) {
36647
36813
  return exp
36648
36814
  .replace(/'[^']*'|"[^"]*"/g, '')
@@ -36683,8 +36849,9 @@ function hmrShouldReload(prevImports, next) {
36683
36849
  return false;
36684
36850
  }
36685
36851
 
36852
+ const DEFAULT_FILENAME = 'anonymous.vue';
36686
36853
  const sourceToSFC = createCache();
36687
- function parse$4(source, { sourceMap = true, filename = 'anonymous.vue', sourceRoot = '', pad = false, ignoreEmpty = true, compiler = CompilerDOM } = {}) {
36854
+ function parse$4(source, { sourceMap = true, filename = DEFAULT_FILENAME, sourceRoot = '', pad = false, ignoreEmpty = true, compiler = CompilerDOM } = {}) {
36688
36855
  const sourceKey = source + sourceMap + filename + sourceRoot + pad + compiler.parse;
36689
36856
  const cache = sourceToSFC.get(sourceKey);
36690
36857
  if (cache) {