@vue/compiler-sfc 3.2.16 → 3.2.20

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.
@@ -15780,6 +15780,8 @@ function compileScript(sfc, options) {
15780
15780
  let { script, scriptSetup, source, filename } = sfc;
15781
15781
  // feature flags
15782
15782
  const enableRefTransform = !!options.refSugar || !!options.refTransform;
15783
+ const enablePropsTransform = !!options.propsDestructureTransform;
15784
+ const isProd = !!options.isProd;
15783
15785
  const genSourceMap = options.sourceMap !== false;
15784
15786
  let refBindings;
15785
15787
  if (!options.id) {
@@ -15795,7 +15797,7 @@ function compileScript(sfc, options) {
15795
15797
  scriptLang === 'tsx' ||
15796
15798
  scriptSetupLang === 'ts' ||
15797
15799
  scriptSetupLang === 'tsx';
15798
- const plugins = [...shared.babelParserDefaultPlugins];
15800
+ const plugins = [];
15799
15801
  if (!isTS || scriptLang === 'tsx' || scriptSetupLang === 'tsx') {
15800
15802
  plugins.push('jsx');
15801
15803
  }
@@ -15842,7 +15844,7 @@ function compileScript(sfc, options) {
15842
15844
  }
15843
15845
  if (cssVars.length) {
15844
15846
  content = rewriteDefault(content, `__default__`, plugins);
15845
- content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, !!options.isProd);
15847
+ content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, isProd);
15846
15848
  content += `\nexport default __default__`;
15847
15849
  }
15848
15850
  return Object.assign(Object.assign({}, script), { content,
@@ -15877,6 +15879,8 @@ function compileScript(sfc, options) {
15877
15879
  let hasDefineExposeCall = false;
15878
15880
  let propsRuntimeDecl;
15879
15881
  let propsRuntimeDefaults;
15882
+ let propsDestructureDecl;
15883
+ let propsDestructureRestId;
15880
15884
  let propsTypeDecl;
15881
15885
  let propsTypeDeclRaw;
15882
15886
  let propsIdentifier;
@@ -15891,6 +15895,8 @@ function compileScript(sfc, options) {
15891
15895
  const typeDeclaredEmits = new Set();
15892
15896
  // record declared types for runtime props type generation
15893
15897
  const declaredTypes = {};
15898
+ // props destructure data
15899
+ const propsDestructuredBindings = Object.create(null);
15894
15900
  // magic-string state
15895
15901
  const s = new MagicString__default(source);
15896
15902
  const startOffset = scriptSetup.loc.start.offset;
@@ -15932,7 +15938,7 @@ function compileScript(sfc, options) {
15932
15938
  isUsedInTemplate
15933
15939
  };
15934
15940
  }
15935
- function processDefineProps(node) {
15941
+ function processDefineProps(node, declId) {
15936
15942
  if (!isCallOf(node, DEFINE_PROPS)) {
15937
15943
  return false;
15938
15944
  }
@@ -15954,17 +15960,63 @@ function compileScript(sfc, options) {
15954
15960
  `or a reference to an interface or literal type.`, propsTypeDeclRaw);
15955
15961
  }
15956
15962
  }
15963
+ if (declId) {
15964
+ if (enablePropsTransform && declId.type === 'ObjectPattern') {
15965
+ propsDestructureDecl = declId;
15966
+ // props destructure - handle compilation sugar
15967
+ for (const prop of declId.properties) {
15968
+ if (prop.type === 'ObjectProperty') {
15969
+ if (prop.computed) {
15970
+ error(`${DEFINE_PROPS}() destructure cannot use computed key.`, prop.key);
15971
+ }
15972
+ const propKey = prop.key.name;
15973
+ if (prop.value.type === 'AssignmentPattern') {
15974
+ // default value { foo = 123 }
15975
+ const { left, right } = prop.value;
15976
+ if (left.type !== 'Identifier') {
15977
+ error(`${DEFINE_PROPS}() destructure does not support nested patterns.`, left);
15978
+ }
15979
+ // store default value
15980
+ propsDestructuredBindings[propKey] = {
15981
+ local: left.name,
15982
+ default: right
15983
+ };
15984
+ }
15985
+ else if (prop.value.type === 'Identifier') {
15986
+ // simple destucture
15987
+ propsDestructuredBindings[propKey] = {
15988
+ local: prop.value.name
15989
+ };
15990
+ }
15991
+ else {
15992
+ error(`${DEFINE_PROPS}() destructure does not support nested patterns.`, prop.value);
15993
+ }
15994
+ }
15995
+ else {
15996
+ // rest spread
15997
+ propsDestructureRestId = prop.argument.name;
15998
+ }
15999
+ }
16000
+ }
16001
+ else {
16002
+ propsIdentifier = scriptSetup.content.slice(declId.start, declId.end);
16003
+ }
16004
+ }
15957
16005
  return true;
15958
16006
  }
15959
- function processWithDefaults(node) {
16007
+ function processWithDefaults(node, declId) {
15960
16008
  if (!isCallOf(node, WITH_DEFAULTS)) {
15961
16009
  return false;
15962
16010
  }
15963
- if (processDefineProps(node.arguments[0])) {
16011
+ if (processDefineProps(node.arguments[0], declId)) {
15964
16012
  if (propsRuntimeDecl) {
15965
16013
  error(`${WITH_DEFAULTS} can only be used with type-based ` +
15966
16014
  `${DEFINE_PROPS} declaration.`, node);
15967
16015
  }
16016
+ if (propsDestructureDecl) {
16017
+ error(`${WITH_DEFAULTS}() is unnecessary when using destructure with ${DEFINE_PROPS}().\n` +
16018
+ `Prefer using destructure default values, e.g. const { foo = 1 } = defineProps(...).`, node.callee);
16019
+ }
15968
16020
  propsRuntimeDefaults = node.arguments[1];
15969
16021
  if (!propsRuntimeDefaults ||
15970
16022
  propsRuntimeDefaults.type !== 'ObjectExpression') {
@@ -15976,7 +16028,7 @@ function compileScript(sfc, options) {
15976
16028
  }
15977
16029
  return true;
15978
16030
  }
15979
- function processDefineEmits(node) {
16031
+ function processDefineEmits(node, declId) {
15980
16032
  if (!isCallOf(node, DEFINE_EMITS)) {
15981
16033
  return false;
15982
16034
  }
@@ -15997,6 +16049,9 @@ function compileScript(sfc, options) {
15997
16049
  `a literal type with call signatures, or a reference to the above types.`, emitsTypeDeclRaw);
15998
16050
  }
15999
16051
  }
16052
+ if (declId) {
16053
+ emitIdentifier = scriptSetup.content.slice(declId.start, declId.end);
16054
+ }
16000
16055
  return true;
16001
16056
  }
16002
16057
  function resolveQualifiedType(node, qualifier) {
@@ -16048,7 +16103,7 @@ function compileScript(sfc, options) {
16048
16103
  if (setupBindings[id.name]) {
16049
16104
  error(`\`${method}()\` in <script setup> cannot reference locally ` +
16050
16105
  `declared variables because it will be hoisted outside of the ` +
16051
- `setup() function. If your component options requires initialization ` +
16106
+ `setup() function. If your component options require initialization ` +
16052
16107
  `in the module scope, use a separate normal <script> to export ` +
16053
16108
  `the options instead.`, id);
16054
16109
  }
@@ -16086,7 +16141,7 @@ function compileScript(sfc, options) {
16086
16141
  * static properties, we can directly generate more optimzied default
16087
16142
  * declarations. Otherwise we will have to fallback to runtime merging.
16088
16143
  */
16089
- function checkStaticDefaults() {
16144
+ function hasStaticWithDefaults() {
16090
16145
  return (propsRuntimeDefaults &&
16091
16146
  propsRuntimeDefaults.type === 'ObjectExpression' &&
16092
16147
  propsRuntimeDefaults.properties.every(node => (node.type === 'ObjectProperty' && !node.computed) ||
@@ -16097,13 +16152,17 @@ function compileScript(sfc, options) {
16097
16152
  if (!keys.length) {
16098
16153
  return ``;
16099
16154
  }
16100
- const hasStaticDefaults = checkStaticDefaults();
16155
+ const hasStaticDefaults = hasStaticWithDefaults();
16101
16156
  const scriptSetupSource = scriptSetup.content;
16102
16157
  let propsDecls = `{
16103
16158
  ${keys
16104
16159
  .map(key => {
16105
16160
  let defaultString;
16106
- if (hasStaticDefaults) {
16161
+ const destructured = genDestructuredDefaultValue(key);
16162
+ if (destructured) {
16163
+ defaultString = `default: ${destructured}`;
16164
+ }
16165
+ else if (hasStaticDefaults) {
16107
16166
  const prop = propsRuntimeDefaults.properties.find((node) => node.key.name === key);
16108
16167
  if (prop) {
16109
16168
  if (prop.type === 'ObjectProperty') {
@@ -16115,10 +16174,14 @@ function compileScript(sfc, options) {
16115
16174
  }
16116
16175
  }
16117
16176
  }
16118
- {
16177
+ if (!isProd) {
16119
16178
  const { type, required } = props[key];
16120
16179
  return `${key}: { type: ${toRuntimeTypeString(type)}, required: ${required}${defaultString ? `, ${defaultString}` : ``} }`;
16121
16180
  }
16181
+ else {
16182
+ // production: checks are useless
16183
+ return `${key}: ${defaultString ? `{ ${defaultString} }` : 'null'}`;
16184
+ }
16122
16185
  })
16123
16186
  .join(',\n ')}\n }`;
16124
16187
  if (propsRuntimeDefaults && !hasStaticDefaults) {
@@ -16126,9 +16189,17 @@ function compileScript(sfc, options) {
16126
16189
  }
16127
16190
  return `\n props: ${propsDecls},`;
16128
16191
  }
16192
+ function genDestructuredDefaultValue(key) {
16193
+ const destructured = propsDestructuredBindings[key];
16194
+ if (destructured && destructured.default) {
16195
+ const value = scriptSetup.content.slice(destructured.default.start, destructured.default.end);
16196
+ const isLiteral = destructured.default.type.endsWith('Literal');
16197
+ return isLiteral ? value : `() => ${value}`;
16198
+ }
16199
+ }
16129
16200
  function genSetupPropsType(node) {
16130
16201
  const scriptSetupSource = scriptSetup.content;
16131
- if (checkStaticDefaults()) {
16202
+ if (hasStaticWithDefaults()) {
16132
16203
  // if withDefaults() is used, we need to remove the optional flags
16133
16204
  // on props that have default values
16134
16205
  let res = `{ `;
@@ -16211,14 +16282,15 @@ function compileScript(sfc, options) {
16211
16282
  }
16212
16283
  else if ((node.type === 'VariableDeclaration' ||
16213
16284
  node.type === 'FunctionDeclaration' ||
16214
- node.type === 'ClassDeclaration') &&
16285
+ node.type === 'ClassDeclaration' ||
16286
+ node.type === 'TSEnumDeclaration') &&
16215
16287
  !node.declare) {
16216
16288
  walkDeclaration(node, scriptBindings, userImportAlias);
16217
16289
  }
16218
16290
  }
16219
16291
  // apply ref transform
16220
16292
  if (enableRefTransform && refTransform.shouldTransform(script.content)) {
16221
- const { rootVars, importedHelpers } = refTransform.transformAST(scriptAst, s, scriptStartOffset);
16293
+ const { rootRefs: rootVars, importedHelpers } = refTransform.transformAST(scriptAst, s, scriptStartOffset);
16222
16294
  refBindings = rootVars;
16223
16295
  for (const h of importedHelpers) {
16224
16296
  helperImports.add(h);
@@ -16325,14 +16397,9 @@ function compileScript(sfc, options) {
16325
16397
  const decl = node.declarations[i];
16326
16398
  if (decl.init) {
16327
16399
  // defineProps / defineEmits
16328
- const isDefineProps = processDefineProps(decl.init) || processWithDefaults(decl.init);
16329
- if (isDefineProps) {
16330
- propsIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
16331
- }
16332
- const isDefineEmits = processDefineEmits(decl.init);
16333
- if (isDefineEmits) {
16334
- emitIdentifier = scriptSetup.content.slice(decl.id.start, decl.id.end);
16335
- }
16400
+ const isDefineProps = processDefineProps(decl.init, decl.id) ||
16401
+ processWithDefaults(decl.init, decl.id);
16402
+ const isDefineEmits = processDefineEmits(decl.init, decl.id);
16336
16403
  if (isDefineProps || isDefineEmits) {
16337
16404
  if (left === 1) {
16338
16405
  s.remove(node.start + startOffset, node.end + startOffset);
@@ -16404,16 +16471,17 @@ function compileScript(sfc, options) {
16404
16471
  }
16405
16472
  }
16406
16473
  // 3. Apply ref sugar transform
16407
- if (enableRefTransform && refTransform.shouldTransform(scriptSetup.content)) {
16408
- const { rootVars, importedHelpers } = refTransform.transformAST(scriptSetupAst, s, startOffset, refBindings);
16409
- refBindings = refBindings ? [...refBindings, ...rootVars] : rootVars;
16474
+ if ((enableRefTransform && refTransform.shouldTransform(scriptSetup.content)) ||
16475
+ propsDestructureDecl) {
16476
+ const { rootRefs, importedHelpers } = refTransform.transformAST(scriptSetupAst, s, startOffset, refBindings, propsDestructuredBindings, !enableRefTransform);
16477
+ refBindings = refBindings ? [...refBindings, ...rootRefs] : rootRefs;
16410
16478
  for (const h of importedHelpers) {
16411
16479
  helperImports.add(h);
16412
16480
  }
16413
16481
  }
16414
16482
  // 4. extract runtime props/emits code from setup context type
16415
16483
  if (propsTypeDecl) {
16416
- extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes);
16484
+ extractRuntimeProps(propsTypeDecl, typeDeclaredProps, declaredTypes, isProd);
16417
16485
  }
16418
16486
  if (emitsTypeDecl) {
16419
16487
  extractRuntimeEmits(emitsTypeDecl, typeDeclaredEmits);
@@ -16422,6 +16490,7 @@ function compileScript(sfc, options) {
16422
16490
  // variables
16423
16491
  checkInvalidScopeReference(propsRuntimeDecl, DEFINE_PROPS);
16424
16492
  checkInvalidScopeReference(propsRuntimeDefaults, DEFINE_PROPS);
16493
+ checkInvalidScopeReference(propsDestructureDecl, DEFINE_PROPS);
16425
16494
  checkInvalidScopeReference(emitsRuntimeDecl, DEFINE_PROPS);
16426
16495
  // 6. remove non-script content
16427
16496
  if (script) {
@@ -16455,6 +16524,20 @@ function compileScript(sfc, options) {
16455
16524
  for (const key in typeDeclaredProps) {
16456
16525
  bindingMetadata[key] = "props" /* PROPS */;
16457
16526
  }
16527
+ // props aliases
16528
+ if (propsDestructureDecl) {
16529
+ if (propsDestructureRestId) {
16530
+ bindingMetadata[propsDestructureRestId] = "setup-const" /* SETUP_CONST */;
16531
+ }
16532
+ for (const key in propsDestructuredBindings) {
16533
+ const { local } = propsDestructuredBindings[key];
16534
+ if (local !== key) {
16535
+ bindingMetadata[local] = "props-aliased" /* PROPS_ALIASED */;
16536
+ (bindingMetadata.__propsAliases ||
16537
+ (bindingMetadata.__propsAliases = {}))[local] = key;
16538
+ }
16539
+ }
16540
+ }
16458
16541
  for (const [key, { isType, imported, source }] of Object.entries(userImports)) {
16459
16542
  if (isType)
16460
16543
  continue;
@@ -16479,7 +16562,7 @@ function compileScript(sfc, options) {
16479
16562
  if (cssVars.length) {
16480
16563
  helperImports.add(CSS_VARS_HELPER);
16481
16564
  helperImports.add('unref');
16482
- s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, !!options.isProd)}\n`);
16565
+ s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, isProd)}\n`);
16483
16566
  }
16484
16567
  // 9. finalize setup() argument signature
16485
16568
  let args = `__props`;
@@ -16493,12 +16576,15 @@ function compileScript(sfc, options) {
16493
16576
  // we use a default __props so that template expressions referencing props
16494
16577
  // can use it directly
16495
16578
  if (propsIdentifier) {
16496
- s.prependRight(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``}`);
16579
+ s.prependLeft(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``}\n`);
16580
+ }
16581
+ if (propsDestructureRestId) {
16582
+ s.prependLeft(startOffset, `\nconst ${propsDestructureRestId} = ${helper(`createPropsRestProxy`)}(__props, ${JSON.stringify(Object.keys(propsDestructuredBindings))})\n`);
16497
16583
  }
16498
16584
  // inject temp variables for async context preservation
16499
16585
  if (hasAwait) {
16500
16586
  const any = isTS ? `: any` : ``;
16501
- s.prependRight(startOffset, `\nlet __temp${any}, __restore${any}\n`);
16587
+ s.prependLeft(startOffset, `\nlet __temp${any}, __restore${any}\n`);
16502
16588
  }
16503
16589
  const destructureElements = hasDefineExposeCall || !options.inlineTemplate ? [`expose`] : [];
16504
16590
  if (emitIdentifier) {
@@ -16582,9 +16668,21 @@ function compileScript(sfc, options) {
16582
16668
  runtimeOptions += `\n __ssrInlineRender: true,`;
16583
16669
  }
16584
16670
  if (propsRuntimeDecl) {
16585
- runtimeOptions += `\n props: ${scriptSetup.content
16671
+ let declCode = scriptSetup.content
16586
16672
  .slice(propsRuntimeDecl.start, propsRuntimeDecl.end)
16587
- .trim()},`;
16673
+ .trim();
16674
+ if (propsDestructureDecl) {
16675
+ const defaults = [];
16676
+ for (const key in propsDestructuredBindings) {
16677
+ const d = genDestructuredDefaultValue(key);
16678
+ if (d)
16679
+ defaults.push(`${key}: ${d}`);
16680
+ }
16681
+ if (defaults.length) {
16682
+ declCode = `${helper(`mergeDefaults`)}(${declCode}, {\n ${defaults.join(',\n ')}\n})`;
16683
+ }
16684
+ }
16685
+ runtimeOptions += `\n props: ${declCode},`;
16588
16686
  }
16589
16687
  else if (propsTypeDecl) {
16590
16688
  runtimeOptions += genRuntimeProps(typeDeclaredProps);
@@ -16682,15 +16780,22 @@ function walkDeclaration(node, bindings, userImportAlias) {
16682
16780
  }
16683
16781
  registerBinding(bindings, id, bindingType);
16684
16782
  }
16685
- else if (id.type === 'ObjectPattern') {
16686
- walkObjectPattern(id, bindings, isConst, isDefineCall);
16687
- }
16688
- else if (id.type === 'ArrayPattern') {
16689
- walkArrayPattern(id, bindings, isConst, isDefineCall);
16783
+ else {
16784
+ if (isCallOf(init, DEFINE_PROPS)) {
16785
+ // skip walking props destructure
16786
+ return;
16787
+ }
16788
+ if (id.type === 'ObjectPattern') {
16789
+ walkObjectPattern(id, bindings, isConst, isDefineCall);
16790
+ }
16791
+ else if (id.type === 'ArrayPattern') {
16792
+ walkArrayPattern(id, bindings, isConst, isDefineCall);
16793
+ }
16690
16794
  }
16691
16795
  }
16692
16796
  }
16693
- else if (node.type === 'FunctionDeclaration' ||
16797
+ else if (node.type === 'TSEnumDeclaration' ||
16798
+ node.type === 'FunctionDeclaration' ||
16694
16799
  node.type === 'ClassDeclaration') {
16695
16800
  // export function foo() {} / export class Foo {}
16696
16801
  // export declarations must be named.
@@ -16771,13 +16876,13 @@ function recordType(node, declaredTypes) {
16771
16876
  recordType(node.declaration, declaredTypes);
16772
16877
  }
16773
16878
  }
16774
- function extractRuntimeProps(node, props, declaredTypes) {
16879
+ function extractRuntimeProps(node, props, declaredTypes, isProd) {
16775
16880
  const members = node.type === 'TSTypeLiteral' ? node.members : node.body;
16776
16881
  for (const m of members) {
16777
16882
  if ((m.type === 'TSPropertySignature' || m.type === 'TSMethodSignature') &&
16778
16883
  m.key.type === 'Identifier') {
16779
16884
  let type;
16780
- {
16885
+ if (!isProd) {
16781
16886
  if (m.type === 'TSMethodSignature') {
16782
16887
  type = ['Function'];
16783
16888
  }
@@ -169,9 +169,15 @@ export declare interface SFCScriptCompileOptions {
169
169
  /**
170
170
  * (Experimental) Enable syntax transform for using refs without `.value`
171
171
  * https://github.com/vuejs/rfcs/discussions/369
172
- * @default true
172
+ * @default false
173
173
  */
174
174
  refTransform?: boolean;
175
+ /**
176
+ * (Experimental) Enable syntax transform for destructuring from defineProps()
177
+ * https://github.com/vuejs/rfcs/discussions/394
178
+ * @default false
179
+ */
180
+ propsDestructureTransform?: boolean;
175
181
  /**
176
182
  * @deprecated use `refTransform` instead.
177
183
  */