@vue/compiler-sfc 3.2.31 → 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 {
@@ -35104,6 +35175,15 @@ function transformAST(ast, s, offset = 0, knownRefs, knownProps) {
35104
35175
  }
35105
35176
  return;
35106
35177
  }
35178
+ // catch param
35179
+ if (node.type === 'CatchClause') {
35180
+ scopeStack.push((currentScope = {}));
35181
+ if (node.param && node.param.type === 'Identifier') {
35182
+ registerBinding(node.param);
35183
+ }
35184
+ walkScope(node.body);
35185
+ return;
35186
+ }
35107
35187
  // non-function block scopes
35108
35188
  if (node.type === 'BlockStatement' && !isFunctionType(parent)) {
35109
35189
  scopeStack.push((currentScope = {}));
@@ -35207,6 +35287,7 @@ const isBuiltInDir = makeMap(`once,memo,if,else,else-if,slot,text,html,on,bind,m
35207
35287
  * normal `<script>` + `<script setup>` if both are present.
35208
35288
  */
35209
35289
  function compileScript(sfc, options) {
35290
+ var _a;
35210
35291
  let { script, scriptSetup, source, filename } = sfc;
35211
35292
  // feature flags
35212
35293
  // TODO remove support for deprecated options when out of experimental
@@ -35235,6 +35316,11 @@ function compileScript(sfc, options) {
35235
35316
  if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
35236
35317
  plugins.push('jsx');
35237
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
+ }
35238
35324
  if (options.babelParserPlugins)
35239
35325
  plugins.push(...options.babelParserPlugins);
35240
35326
  if (isTS)
@@ -35310,6 +35396,8 @@ function compileScript(sfc, options) {
35310
35396
  let hasDefinePropsCall = false;
35311
35397
  let hasDefineEmitCall = false;
35312
35398
  let hasDefineExposeCall = false;
35399
+ let hasDefaultExportName = false;
35400
+ let hasDefaultExportRender = false;
35313
35401
  let propsRuntimeDecl;
35314
35402
  let propsRuntimeDefaults;
35315
35403
  let propsDestructureDecl;
@@ -35352,12 +35440,18 @@ function compileScript(sfc, options) {
35352
35440
  function error(msg, node, end = node.end + startOffset) {
35353
35441
  throw new Error(`[@vue/compiler-sfc] ${msg}\n\n${sfc.filename}\n${generateCodeFrame(source, node.start + startOffset, end)}`);
35354
35442
  }
35355
- function registerUserImport(source, local, imported, isType, isFromSetup) {
35443
+ function registerUserImport(source, local, imported, isType, isFromSetup, needTemplateUsageCheck) {
35356
35444
  if (source === 'vue' && imported) {
35357
35445
  userImportAlias[imported] = local;
35358
35446
  }
35359
- let isUsedInTemplate = true;
35360
- 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) {
35361
35455
  isUsedInTemplate = isImportUsed(local, sfc);
35362
35456
  }
35363
35457
  userImports[local] = {
@@ -35399,7 +35493,9 @@ function compileScript(sfc, options) {
35399
35493
  if (prop.computed) {
35400
35494
  error(`${DEFINE_PROPS}() destructure cannot use computed key.`, prop.key);
35401
35495
  }
35402
- const propKey = prop.key.name;
35496
+ const propKey = prop.key.type === 'StringLiteral'
35497
+ ? prop.key.value
35498
+ : prop.key.name;
35403
35499
  if (prop.value.type === 'AssignmentPattern') {
35404
35500
  // default value { foo = 123 }
35405
35501
  const { left, right } = prop.value;
@@ -35628,7 +35724,7 @@ function compileScript(sfc, options) {
35628
35724
  if (destructured && destructured.default) {
35629
35725
  const value = scriptSetup.content.slice(destructured.default.start, destructured.default.end);
35630
35726
  const isLiteral = destructured.default.type.endsWith('Literal');
35631
- return isLiteral ? value : `() => ${value}`;
35727
+ return isLiteral ? value : `() => (${value})`;
35632
35728
  }
35633
35729
  }
35634
35730
  function genSetupPropsType(node) {
@@ -35676,12 +35772,42 @@ function compileScript(sfc, options) {
35676
35772
  const imported = specifier.type === 'ImportSpecifier' &&
35677
35773
  specifier.imported.type === 'Identifier' &&
35678
35774
  specifier.imported.name;
35679
- registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type', false);
35775
+ registerUserImport(node.source.value, specifier.local.name, imported, node.importKind === 'type' ||
35776
+ (specifier.type === 'ImportSpecifier' &&
35777
+ specifier.importKind === 'type'), false, !options.inlineTemplate);
35680
35778
  }
35681
35779
  }
35682
35780
  else if (node.type === 'ExportDefaultDeclaration') {
35683
35781
  // export default
35684
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
+ }
35685
35811
  // export default { ... } --> const __default__ = { ... }
35686
35812
  const start = node.start + scriptStartOffset;
35687
35813
  const end = node.declaration.start + scriptStartOffset;
@@ -35734,6 +35860,10 @@ function compileScript(sfc, options) {
35734
35860
  // we need to move the block up so that `const __default__` is
35735
35861
  // declared before being used in the actual component definition
35736
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
+ }
35737
35867
  s.move(scriptStartOffset, scriptEndOffset, 0);
35738
35868
  }
35739
35869
  }
@@ -35788,9 +35918,12 @@ function compileScript(sfc, options) {
35788
35918
  for (let i = 0; i < node.specifiers.length; i++) {
35789
35919
  const specifier = node.specifiers[i];
35790
35920
  const local = specifier.local.name;
35791
- const imported = specifier.type === 'ImportSpecifier' &&
35921
+ let imported = specifier.type === 'ImportSpecifier' &&
35792
35922
  specifier.imported.type === 'Identifier' &&
35793
35923
  specifier.imported.name;
35924
+ if (specifier.type === 'ImportNamespaceSpecifier') {
35925
+ imported = '*';
35926
+ }
35794
35927
  const source = node.source.value;
35795
35928
  const existing = userImports[local];
35796
35929
  if (source === 'vue' &&
@@ -35810,7 +35943,9 @@ function compileScript(sfc, options) {
35810
35943
  }
35811
35944
  }
35812
35945
  else {
35813
- registerUserImport(source, local, imported, node.importKind === 'type', true);
35946
+ registerUserImport(source, local, imported, node.importKind === 'type' ||
35947
+ (specifier.type === 'ImportSpecifier' &&
35948
+ specifier.importKind === 'type'), true, !options.inlineTemplate);
35814
35949
  }
35815
35950
  }
35816
35951
  if (node.specifiers.length && removed === node.specifiers.length) {
@@ -35873,18 +36008,33 @@ function compileScript(sfc, options) {
35873
36008
  // await
35874
36009
  if ((node.type === 'VariableDeclaration' && !node.declare) ||
35875
36010
  node.type.endsWith('Statement')) {
36011
+ const scope = [scriptSetupAst.body];
35876
36012
  walk$1(node, {
35877
36013
  enter(child, parent) {
35878
36014
  if (isFunctionType(child)) {
35879
36015
  this.skip();
35880
36016
  }
36017
+ if (child.type === 'BlockStatement') {
36018
+ scope.push(child.body);
36019
+ }
35881
36020
  if (child.type === 'AwaitExpression') {
35882
36021
  hasAwait = true;
35883
- const needsSemi = scriptSetupAst.body.some(n => {
35884
- 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);
35885
36031
  });
35886
36032
  processAwait(child, needsSemi, parent.type === 'ExpressionStatement');
35887
36033
  }
36034
+ },
36035
+ exit(node) {
36036
+ if (node.type === 'BlockStatement')
36037
+ scope.pop();
35888
36038
  }
35889
36039
  });
35890
36040
  }
@@ -35933,7 +36083,7 @@ function compileScript(sfc, options) {
35933
36083
  checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
35934
36084
  checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
35935
36085
  checkInvalidScopeReference(propsDestructureDecl, DEFINE_PROPS);
35936
- checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
36086
+ checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_EMITS);
35937
36087
  // 6. remove non-script content
35938
36088
  if (script) {
35939
36089
  if (startOffset < scriptStartOffset) {
@@ -35969,7 +36119,8 @@ function compileScript(sfc, options) {
35969
36119
  // props aliases
35970
36120
  if (propsDestructureDecl) {
35971
36121
  if (propsDestructureRestId) {
35972
- bindingMetadata[propsDestructureRestId] = "setup-const" /* SETUP_CONST */;
36122
+ bindingMetadata[propsDestructureRestId] =
36123
+ "setup-reactive-const" /* SETUP_REACTIVE_CONST */;
35973
36124
  }
35974
36125
  for (const key in propsDestructuredBindings) {
35975
36126
  const { local } = propsDestructuredBindings[key];
@@ -35984,7 +36135,9 @@ function compileScript(sfc, options) {
35984
36135
  if (isType)
35985
36136
  continue;
35986
36137
  bindingMetadata[key] =
35987
- (imported === 'default' && source.endsWith('.vue')) || source === 'vue'
36138
+ imported === '*' ||
36139
+ (imported === 'default' && source.endsWith('.vue')) ||
36140
+ source === 'vue'
35988
36141
  ? "setup-const" /* SETUP_CONST */
35989
36142
  : "setup-maybe-ref" /* SETUP_MAYBE_REF */;
35990
36143
  }
@@ -36001,7 +36154,9 @@ function compileScript(sfc, options) {
36001
36154
  }
36002
36155
  }
36003
36156
  // 8. inject `useCssVars` calls
36004
- 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))) {
36005
36160
  helperImports.add(CSS_VARS_HELPER);
36006
36161
  helperImports.add('unref');
36007
36162
  s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, isProd)}\n`);
@@ -36040,7 +36195,19 @@ function compileScript(sfc, options) {
36040
36195
  }
36041
36196
  // 10. generate return statement
36042
36197
  let returned;
36043
- 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
36044
36211
  if (sfc.template && !sfc.template.src) {
36045
36212
  if (options.templateOptions && options.templateOptions.ssr) {
36046
36213
  hasInlinedSsrRenderFn = true;
@@ -36083,16 +36250,6 @@ function compileScript(sfc, options) {
36083
36250
  returned = `() => {}`;
36084
36251
  }
36085
36252
  }
36086
- else {
36087
- // return bindings from script and script setup
36088
- const allBindings = Object.assign(Object.assign({}, scriptBindings), setupBindings);
36089
- for (const key in userImports) {
36090
- if (!userImports[key].isType && userImports[key].isUsedInTemplate) {
36091
- allBindings[key] = true;
36092
- }
36093
- }
36094
- returned = `{ ${Object.keys(allBindings).join(', ')} }`;
36095
- }
36096
36253
  if (!options.inlineTemplate && !false) {
36097
36254
  // in non-inline mode, the `__isScriptSetup: true` flag is used by
36098
36255
  // componentPublicInstance proxy to allow properties that start with $ or _
@@ -36106,6 +36263,12 @@ function compileScript(sfc, options) {
36106
36263
  }
36107
36264
  // 11. finalize default export
36108
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
+ }
36109
36272
  if (hasInlinedSsrRenderFn) {
36110
36273
  runtimeOptions += `\n __ssrInlineRender: true,`;
36111
36274
  }
@@ -36195,14 +36358,18 @@ function walkDeclaration(node, bindings, userImportAlias) {
36195
36358
  const userReactiveBinding = userImportAlias['reactive'] || 'reactive';
36196
36359
  if (isCallOf(init, userReactiveBinding)) {
36197
36360
  // treat reactive() calls as let since it's meant to be mutable
36198
- bindingType = "setup-let" /* SETUP_LET */;
36361
+ bindingType = isConst
36362
+ ? "setup-reactive-const" /* SETUP_REACTIVE_CONST */
36363
+ : "setup-let" /* SETUP_LET */;
36199
36364
  }
36200
36365
  else if (
36201
36366
  // if a declaration is a const literal, we can mark it so that
36202
36367
  // the generated render fn code doesn't need to unref() it
36203
36368
  isDefineCall ||
36204
36369
  (isConst && canNeverBeRef(init, userReactiveBinding))) {
36205
- bindingType = "setup-const" /* SETUP_CONST */;
36370
+ bindingType = isCallOf(init, DEFINE_PROPS)
36371
+ ? "setup-reactive-const" /* SETUP_REACTIVE_CONST */
36372
+ : "setup-const" /* SETUP_CONST */;
36206
36373
  }
36207
36374
  else if (isConst) {
36208
36375
  if (isCallOf(init, userImportAlias['ref'] || 'ref')) {
@@ -36615,13 +36782,13 @@ function resolveTemplateUsageCheckString(sfc) {
36615
36782
  code += `,v${capitalize(camelize(prop.name))}`;
36616
36783
  }
36617
36784
  if (prop.exp) {
36618
- code += `,${stripStrings(prop.exp.content)}`;
36785
+ code += `,${processExp(prop.exp.content)}`;
36619
36786
  }
36620
36787
  }
36621
36788
  }
36622
36789
  }
36623
36790
  else if (node.type === 5 /* INTERPOLATION */) {
36624
- code += `,${stripStrings(node.content.content)}`;
36791
+ code += `,${processExp(node.content.content)}`;
36625
36792
  }
36626
36793
  }
36627
36794
  ]
@@ -36630,6 +36797,18 @@ function resolveTemplateUsageCheckString(sfc) {
36630
36797
  templateUsageCheckCache.set(content, code);
36631
36798
  return code;
36632
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
+ }
36633
36812
  function stripStrings(exp) {
36634
36813
  return exp
36635
36814
  .replace(/'[^']*'|"[^"]*"/g, '')
@@ -36670,8 +36849,9 @@ function hmrShouldReload(prevImports, next) {
36670
36849
  return false;
36671
36850
  }
36672
36851
 
36852
+ const DEFAULT_FILENAME = 'anonymous.vue';
36673
36853
  const sourceToSFC = createCache();
36674
- 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 } = {}) {
36675
36855
  const sourceKey = source + sourceMap + filename + sourceRoot + pad + compiler.parse;
36676
36856
  const cache = sourceToSFC.get(sourceKey);
36677
36857
  if (cache) {