@vue/compiler-sfc 2.7.0-alpha.9 → 2.7.0-beta.3

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.
@@ -200,7 +200,7 @@ declare type CompiledResult = {
200
200
  tips?: Array<string | WarningMessage>;
201
201
  };
202
202
 
203
- declare type CompilerOptions = {
203
+ export declare type CompilerOptions = {
204
204
  warn?: Function;
205
205
  modules?: Array<ModuleOptions>;
206
206
  directives?: {
@@ -234,13 +234,13 @@ declare type CompilerOptions = {
234
234
  * It requires the whole SFC descriptor because we need to handle and merge
235
235
  * normal `<script>` + `<script setup>` if both are present.
236
236
  */
237
- export declare function compileScript(sfc: SFCDescriptor, options?: ScriptCompileOptions): SFCScriptBlock;
237
+ export declare function compileScript(sfc: SFCDescriptor, options?: SFCScriptCompileOptions): SFCScriptBlock;
238
238
 
239
- export declare function compileStyle(options: StyleCompileOptions): StyleCompileResults;
239
+ export declare function compileStyle(options: SFCStyleCompileOptions): SFCStyleCompileResults;
240
240
 
241
- export declare function compileStyleAsync(options: StyleCompileOptions): Promise<StyleCompileResults>;
241
+ export declare function compileStyleAsync(options: SFCStyleCompileOptions): Promise<SFCStyleCompileResults>;
242
242
 
243
- export declare function compileTemplate(options: TemplateCompileOptions): TemplateCompileResult;
243
+ export declare function compileTemplate(options: SFCTemplateCompileOptions): SFCTemplateCompileResults;
244
244
 
245
245
  export declare function generateCodeFrame(source: string, start?: number, end?: number): string;
246
246
 
@@ -261,16 +261,7 @@ declare type ModuleOptions = {
261
261
  staticKeys?: Array<string>;
262
262
  };
263
263
 
264
- export declare function parse(options: ParseOptions): SFCDescriptor;
265
-
266
- declare interface ParseOptions {
267
- source: string;
268
- filename?: string;
269
- compiler?: VueTemplateCompiler;
270
- compilerParseOptions?: VueTemplateCompilerParseOptions;
271
- sourceRoot?: string;
272
- needMap?: boolean;
273
- }
264
+ export declare function parse(options: SFCParseOptions): SFCDescriptor;
274
265
 
275
266
  declare interface RawSourceMap extends StartOfSourceMap {
276
267
  version: string;
@@ -280,24 +271,14 @@ declare interface RawSourceMap extends StartOfSourceMap {
280
271
  mappings: string;
281
272
  }
282
273
 
283
- export declare interface ScriptCompileOptions {
284
- /**
285
- * Production mode. Used to determine whether to generate hashed CSS variables
286
- */
287
- isProd?: boolean;
288
- /**
289
- * Enable/disable source map. Defaults to true.
290
- */
291
- sourceMap?: boolean;
292
- /**
293
- * https://babeljs.io/docs/en/babel-parser#plugins
294
- */
295
- babelParserPlugins?: ParserPlugin[];
296
- }
274
+ /**
275
+ * Utility for rewriting `export default` in a script block into a variable
276
+ * declaration so that we can inject things into it
277
+ */
278
+ export declare function rewriteDefault(input: string, as: string, parserPlugins?: ParserPlugin[]): string;
297
279
 
298
280
  export declare interface SFCBlock extends SFCCustomBlock {
299
281
  lang?: string;
300
- src?: string;
301
282
  scoped?: boolean;
302
283
  module?: string | boolean;
303
284
  }
@@ -310,6 +291,7 @@ export declare interface SFCCustomBlock {
310
291
  };
311
292
  start: number;
312
293
  end: number;
294
+ src?: string;
313
295
  map?: RawSourceMap;
314
296
  }
315
297
 
@@ -321,7 +303,8 @@ export declare interface SFCDescriptor {
321
303
  scriptSetup: SFCScriptBlock | null;
322
304
  styles: SFCBlock[];
323
305
  customBlocks: SFCCustomBlock[];
324
- errors: WarningMessage[];
306
+ cssVars: string[];
307
+ errors: (string | WarningMessage)[];
325
308
  /**
326
309
  * compare with an existing descriptor to determine whether HMR should perform
327
310
  * a reload vs. re-render.
@@ -333,7 +316,20 @@ export declare interface SFCDescriptor {
333
316
  shouldForceReload: (prevImports: Record<string, ImportBinding>) => boolean;
334
317
  }
335
318
 
336
- declare interface SFCScriptBlock extends SFCBlock {
319
+ export declare interface SFCParseOptions {
320
+ source: string;
321
+ filename?: string;
322
+ compiler?: TemplateCompiler;
323
+ compilerParseOptions?: VueTemplateCompilerParseOptions;
324
+ sourceRoot?: string;
325
+ sourceMap?: boolean;
326
+ /**
327
+ * @deprecated use `sourceMap` instead.
328
+ */
329
+ needMap?: boolean;
330
+ }
331
+
332
+ export declare interface SFCScriptBlock extends SFCBlock {
337
333
  type: 'script';
338
334
  setup?: string | boolean;
339
335
  bindings?: BindingMetadata;
@@ -348,12 +344,27 @@ declare interface SFCScriptBlock extends SFCBlock {
348
344
  scriptSetupAst?: any[];
349
345
  }
350
346
 
351
- declare interface StartOfSourceMap {
352
- file?: string;
353
- sourceRoot?: string;
347
+ export declare interface SFCScriptCompileOptions {
348
+ /**
349
+ * Scope ID for prefixing injected CSS variables.
350
+ * This must be consistent with the `id` passed to `compileStyle`.
351
+ */
352
+ id: string;
353
+ /**
354
+ * Production mode. Used to determine whether to generate hashed CSS variables
355
+ */
356
+ isProd?: boolean;
357
+ /**
358
+ * Enable/disable source map. Defaults to true.
359
+ */
360
+ sourceMap?: boolean;
361
+ /**
362
+ * https://babeljs.io/docs/en/babel-parser#plugins
363
+ */
364
+ babelParserPlugins?: ParserPlugin[];
354
365
  }
355
366
 
356
- export declare interface StyleCompileOptions {
367
+ export declare interface SFCStyleCompileOptions {
357
368
  source: string;
358
369
  filename: string;
359
370
  id: string;
@@ -364,20 +375,21 @@ export declare interface StyleCompileOptions {
364
375
  preprocessOptions?: any;
365
376
  postcssOptions?: any;
366
377
  postcssPlugins?: any[];
378
+ isProd?: boolean;
367
379
  }
368
380
 
369
- export declare interface StyleCompileResults {
381
+ export declare interface SFCStyleCompileResults {
370
382
  code: string;
371
383
  map: any | void;
372
384
  rawResult: LazyResult | void;
373
385
  errors: string[];
374
386
  }
375
387
 
376
- export declare interface TemplateCompileOptions {
388
+ export declare interface SFCTemplateCompileOptions {
377
389
  source: string;
378
390
  filename: string;
379
- compiler?: VueTemplateCompiler;
380
- compilerOptions?: VueTemplateCompilerOptions;
391
+ compiler?: TemplateCompiler;
392
+ compilerOptions?: CompilerOptions;
381
393
  transformAssetUrls?: AssetURLOptions | boolean;
382
394
  transformAssetUrlsOptions?: TransformAssetUrlsOptions;
383
395
  preprocessLang?: string;
@@ -391,7 +403,7 @@ export declare interface TemplateCompileOptions {
391
403
  bindings?: BindingMetadata;
392
404
  }
393
405
 
394
- export declare interface TemplateCompileResult {
406
+ export declare interface SFCTemplateCompileResults {
395
407
  ast: Object | undefined;
396
408
  code: string;
397
409
  source: string;
@@ -399,31 +411,36 @@ export declare interface TemplateCompileResult {
399
411
  errors: (string | WarningMessage)[];
400
412
  }
401
413
 
414
+ declare interface StartOfSourceMap {
415
+ file?: string;
416
+ sourceRoot?: string;
417
+ }
418
+
419
+ export declare interface TemplateCompiler {
420
+ parseComponent(source: string, options?: any): SFCDescriptor;
421
+ compile(template: string, options: CompilerOptions): CompiledResult;
422
+ ssrCompile(template: string, options: CompilerOptions): CompiledResult;
423
+ }
424
+
402
425
  declare interface TransformAssetUrlsOptions {
403
426
  /**
404
427
  * If base is provided, instead of transforming relative asset urls into
405
428
  * imports, they will be directly rewritten to absolute urls.
406
429
  */
407
430
  base?: string;
431
+ /**
432
+ * If true, also processes absolute urls.
433
+ */
434
+ includeAbsolute?: boolean;
408
435
  }
409
436
 
410
- declare interface VueTemplateCompiler {
411
- parseComponent(source: string, options?: any): SFCDescriptor;
412
- compile(template: string, options: VueTemplateCompilerOptions): VueTemplateCompilerResults;
413
- ssrCompile(template: string, options: VueTemplateCompilerOptions): VueTemplateCompilerResults;
414
- }
415
-
416
- declare type VueTemplateCompilerOptions = CompilerOptions;
417
-
418
437
  declare interface VueTemplateCompilerParseOptions {
419
438
  pad?: 'line' | 'space' | boolean;
420
439
  deindent?: boolean;
421
440
  outputSourceRange?: boolean;
422
441
  }
423
442
 
424
- declare type VueTemplateCompilerResults = CompiledResult;
425
-
426
- declare type WarningMessage = {
443
+ export declare type WarningMessage = {
427
444
  msg: string;
428
445
  start?: number;
429
446
  end?: number;
@@ -658,6 +658,7 @@ function parseComponent(source, options = {}) {
658
658
  scriptSetup: null,
659
659
  styles: [],
660
660
  customBlocks: [],
661
+ cssVars: [],
661
662
  errors: [],
662
663
  shouldForceReload: null // attached in parse() by compiler-sfc
663
664
  };
@@ -690,6 +691,9 @@ function parseComponent(source, options = {}) {
690
691
  return cumulated;
691
692
  }, {})
692
693
  };
694
+ if (typeof currentBlock.attrs.src === 'string') {
695
+ currentBlock.src = currentBlock.attrs.src;
696
+ }
693
697
  if (isSpecialTag(tag)) {
694
698
  checkAttrs(currentBlock, attrs);
695
699
  if (tag === 'script') {
@@ -730,9 +734,6 @@ function parseComponent(source, options = {}) {
730
734
  if (attr.name === 'module') {
731
735
  block.module = attr.value || true;
732
736
  }
733
- if (attr.name === 'src') {
734
- block.src = attr.value;
735
- }
736
737
  }
737
738
  }
738
739
  function end(tag, start) {
@@ -7959,6 +7960,268 @@ function warn(msg) {
7959
7960
  console.warn(`\x1b[1m\x1b[33m[@vue/compiler-sfc]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
7960
7961
  }
7961
7962
 
7963
+ const doNotPrefix = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' +
7964
+ 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
7965
+ 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
7966
+ 'require,' + // for webpack
7967
+ 'arguments,' + // parsed as identifier but is a special keyword...
7968
+ '_c' // cached to save property access
7969
+ );
7970
+ /**
7971
+ * The input is expected to be a valid expression.
7972
+ */
7973
+ function prefixIdentifiers(source, isFunctional = false, isTS = false, babelOptions = {}, bindings) {
7974
+ const s = new MagicString(source);
7975
+ const plugins = [
7976
+ ...(isTS ? ['typescript'] : []),
7977
+ ...((babelOptions === null || babelOptions === void 0 ? void 0 : babelOptions.plugins) || [])
7978
+ ];
7979
+ const ast = parser$1.parseExpression(source, Object.assign(Object.assign({}, babelOptions), { plugins }));
7980
+ const isScriptSetup = bindings && bindings.__isScriptSetup !== false;
7981
+ walkIdentifiers(ast, ident => {
7982
+ const { name } = ident;
7983
+ if (doNotPrefix(name)) {
7984
+ return;
7985
+ }
7986
+ if (!isScriptSetup) {
7987
+ s.prependRight(ident.start, '_vm.');
7988
+ return;
7989
+ }
7990
+ s.overwrite(ident.start, ident.end, rewriteIdentifier(name, bindings));
7991
+ }, node => {
7992
+ if (node.type === 'WithStatement') {
7993
+ s.remove(node.start, node.body.start + 1);
7994
+ s.remove(node.end - 1, node.end);
7995
+ if (!isFunctional) {
7996
+ s.prependRight(node.start, `var _vm=this,_c=_vm._self._c${isScriptSetup ? `,_setup=_vm._self._setupProxy;` : `;`}`);
7997
+ }
7998
+ }
7999
+ });
8000
+ return s.toString();
8001
+ }
8002
+ function rewriteIdentifier(name, bindings) {
8003
+ const type = bindings[name];
8004
+ if (type && type.startsWith('setup')) {
8005
+ return `_setup.${name}`;
8006
+ }
8007
+ else {
8008
+ return `_vm.${name}`;
8009
+ }
8010
+ }
8011
+
8012
+ const CSS_VARS_HELPER = `useCssVars`;
8013
+ function genCssVarsFromList(vars, id, isProd, isSSR = false) {
8014
+ return `{\n ${vars
8015
+ .map(key => `"${isSSR ? `--` : ``}${genVarName(id, key, isProd)}": (${key})`)
8016
+ .join(',\n ')}\n}`;
8017
+ }
8018
+ function genVarName(id, raw, isProd) {
8019
+ if (isProd) {
8020
+ return hashSum(id + raw);
8021
+ }
8022
+ else {
8023
+ return `${id}-${raw.replace(/([^\w-])/g, '_')}`;
8024
+ }
8025
+ }
8026
+ function normalizeExpression(exp) {
8027
+ exp = exp.trim();
8028
+ if ((exp[0] === `'` && exp[exp.length - 1] === `'`) ||
8029
+ (exp[0] === `"` && exp[exp.length - 1] === `"`)) {
8030
+ return exp.slice(1, -1);
8031
+ }
8032
+ return exp;
8033
+ }
8034
+ const vBindRE = /v-bind\s*\(/g;
8035
+ function parseCssVars(sfc) {
8036
+ const vars = [];
8037
+ sfc.styles.forEach(style => {
8038
+ let match;
8039
+ // ignore v-bind() in comments /* ... */
8040
+ const content = style.content.replace(/\/\*([\s\S]*?)\*\//g, '');
8041
+ while ((match = vBindRE.exec(content))) {
8042
+ const start = match.index + match[0].length;
8043
+ const end = lexBinding(content, start);
8044
+ if (end !== null) {
8045
+ const variable = normalizeExpression(content.slice(start, end));
8046
+ if (!vars.includes(variable)) {
8047
+ vars.push(variable);
8048
+ }
8049
+ }
8050
+ }
8051
+ });
8052
+ return vars;
8053
+ }
8054
+ function lexBinding(content, start) {
8055
+ let state = 0 /* LexerState.inParens */;
8056
+ let parenDepth = 0;
8057
+ for (let i = start; i < content.length; i++) {
8058
+ const char = content.charAt(i);
8059
+ switch (state) {
8060
+ case 0 /* LexerState.inParens */:
8061
+ if (char === `'`) {
8062
+ state = 1 /* LexerState.inSingleQuoteString */;
8063
+ }
8064
+ else if (char === `"`) {
8065
+ state = 2 /* LexerState.inDoubleQuoteString */;
8066
+ }
8067
+ else if (char === `(`) {
8068
+ parenDepth++;
8069
+ }
8070
+ else if (char === `)`) {
8071
+ if (parenDepth > 0) {
8072
+ parenDepth--;
8073
+ }
8074
+ else {
8075
+ return i;
8076
+ }
8077
+ }
8078
+ break;
8079
+ case 1 /* LexerState.inSingleQuoteString */:
8080
+ if (char === `'`) {
8081
+ state = 0 /* LexerState.inParens */;
8082
+ }
8083
+ break;
8084
+ case 2 /* LexerState.inDoubleQuoteString */:
8085
+ if (char === `"`) {
8086
+ state = 0 /* LexerState.inParens */;
8087
+ }
8088
+ break;
8089
+ }
8090
+ }
8091
+ return null;
8092
+ }
8093
+ const cssVarsPlugin = opts => {
8094
+ const { id, isProd } = opts;
8095
+ return {
8096
+ postcssPlugin: 'vue-sfc-vars',
8097
+ Declaration(decl) {
8098
+ // rewrite CSS variables
8099
+ const value = decl.value;
8100
+ if (vBindRE.test(value)) {
8101
+ vBindRE.lastIndex = 0;
8102
+ let transformed = '';
8103
+ let lastIndex = 0;
8104
+ let match;
8105
+ while ((match = vBindRE.exec(value))) {
8106
+ const start = match.index + match[0].length;
8107
+ const end = lexBinding(value, start);
8108
+ if (end !== null) {
8109
+ const variable = normalizeExpression(value.slice(start, end));
8110
+ transformed +=
8111
+ value.slice(lastIndex, match.index) +
8112
+ `var(--${genVarName(id, variable, isProd)})`;
8113
+ lastIndex = end + 1;
8114
+ }
8115
+ }
8116
+ decl.value = transformed + value.slice(lastIndex);
8117
+ }
8118
+ }
8119
+ };
8120
+ };
8121
+ cssVarsPlugin.postcss = true;
8122
+ function genCssVarsCode(vars, bindings, id, isProd) {
8123
+ const varsExp = genCssVarsFromList(vars, id, isProd);
8124
+ return `_${CSS_VARS_HELPER}((_vm, _setup) => ${prefixIdentifiers(`(${varsExp})`, false, false, undefined, bindings)})`;
8125
+ }
8126
+ // <script setup> already gets the calls injected as part of the transform
8127
+ // this is only for single normal <script>
8128
+ function genNormalScriptCssVarsCode(cssVars, bindings, id, isProd) {
8129
+ return (`\nimport { ${CSS_VARS_HELPER} as _${CSS_VARS_HELPER} } from 'vue'\n` +
8130
+ `const __injectCSSVars__ = () => {\n${genCssVarsCode(cssVars, bindings, id, isProd)}}\n` +
8131
+ `const __setup__ = __default__.setup\n` +
8132
+ `__default__.setup = __setup__\n` +
8133
+ ` ? (props, ctx) => { __injectCSSVars__();return __setup__(props, ctx) }\n` +
8134
+ ` : __injectCSSVars__\n`);
8135
+ }
8136
+
8137
+ const defaultExportRE = /((?:^|\n|;)\s*)export(\s*)default/;
8138
+ const namedDefaultExportRE = /((?:^|\n|;)\s*)export(.+)(?:as)?(\s*)default/s;
8139
+ const exportDefaultClassRE = /((?:^|\n|;)\s*)export\s+default\s+class\s+([\w$]+)/;
8140
+ /**
8141
+ * Utility for rewriting `export default` in a script block into a variable
8142
+ * declaration so that we can inject things into it
8143
+ */
8144
+ function rewriteDefault(input, as, parserPlugins) {
8145
+ if (!hasDefaultExport(input)) {
8146
+ return input + `\nconst ${as} = {}`;
8147
+ }
8148
+ let replaced;
8149
+ const classMatch = input.match(exportDefaultClassRE);
8150
+ if (classMatch) {
8151
+ replaced =
8152
+ input.replace(exportDefaultClassRE, '$1class $2') +
8153
+ `\nconst ${as} = ${classMatch[2]}`;
8154
+ }
8155
+ else {
8156
+ replaced = input.replace(defaultExportRE, `$1const ${as} =`);
8157
+ }
8158
+ if (!hasDefaultExport(replaced)) {
8159
+ return replaced;
8160
+ }
8161
+ // if the script somehow still contains `default export`, it probably has
8162
+ // multi-line comments or template strings. fallback to a full parse.
8163
+ const s = new MagicString(input);
8164
+ const ast = parser$1.parse(input, {
8165
+ sourceType: 'module',
8166
+ plugins: parserPlugins
8167
+ }).program.body;
8168
+ ast.forEach(node => {
8169
+ if (node.type === 'ExportDefaultDeclaration') {
8170
+ s.overwrite(node.start, node.declaration.start, `const ${as} = `);
8171
+ }
8172
+ if (node.type === 'ExportNamedDeclaration') {
8173
+ for (const specifier of node.specifiers) {
8174
+ if (specifier.type === 'ExportSpecifier' &&
8175
+ specifier.exported.type === 'Identifier' &&
8176
+ specifier.exported.name === 'default') {
8177
+ if (node.source) {
8178
+ if (specifier.local.name === 'default') {
8179
+ const end = specifierEnd(input, specifier.local.end, node.end);
8180
+ s.prepend(`import { default as __VUE_DEFAULT__ } from '${node.source.value}'\n`);
8181
+ s.overwrite(specifier.start, end, ``);
8182
+ s.append(`\nconst ${as} = __VUE_DEFAULT__`);
8183
+ continue;
8184
+ }
8185
+ else {
8186
+ const end = specifierEnd(input, specifier.exported.end, node.end);
8187
+ s.prepend(`import { ${input.slice(specifier.local.start, specifier.local.end)} } from '${node.source.value}'\n`);
8188
+ s.overwrite(specifier.start, end, ``);
8189
+ s.append(`\nconst ${as} = ${specifier.local.name}`);
8190
+ continue;
8191
+ }
8192
+ }
8193
+ const end = specifierEnd(input, specifier.end, node.end);
8194
+ s.overwrite(specifier.start, end, ``);
8195
+ s.append(`\nconst ${as} = ${specifier.local.name}`);
8196
+ }
8197
+ }
8198
+ }
8199
+ });
8200
+ return s.toString();
8201
+ }
8202
+ function hasDefaultExport(input) {
8203
+ return defaultExportRE.test(input) || namedDefaultExportRE.test(input);
8204
+ }
8205
+ function specifierEnd(input, end, nodeEnd) {
8206
+ // export { default , foo } ...
8207
+ let hasCommas = false;
8208
+ let oldEnd = end;
8209
+ while (end < nodeEnd) {
8210
+ if (/\s/.test(input.charAt(end))) {
8211
+ end++;
8212
+ }
8213
+ else if (input.charAt(end) === ',') {
8214
+ end++;
8215
+ hasCommas = true;
8216
+ break;
8217
+ }
8218
+ else if (input.charAt(end) === '}') {
8219
+ break;
8220
+ }
8221
+ }
8222
+ return hasCommas ? end : oldEnd;
8223
+ }
8224
+
7962
8225
  // Special compiler macros
7963
8226
  const DEFINE_PROPS = 'defineProps';
7964
8227
  const DEFINE_EMITS = 'defineEmits';
@@ -7972,11 +8235,12 @@ const isBuiltInDir$1 = makeMap(`once,memo,if,for,else,else-if,slot,text,html,on,
7972
8235
  * It requires the whole SFC descriptor because we need to handle and merge
7973
8236
  * normal `<script>` + `<script setup>` if both are present.
7974
8237
  */
7975
- function compileScript(sfc, options = {}) {
8238
+ function compileScript(sfc, options = { id: '' }) {
7976
8239
  let { filename, script, scriptSetup, source } = sfc;
7977
8240
  const isProd = !!options.isProd;
7978
8241
  const genSourceMap = options.sourceMap !== false;
7979
- // const cssVars = sfc.cssVars
8242
+ const cssVars = sfc.cssVars;
8243
+ const scopeId = options.id ? options.id.replace(/^data-v-/, '') : '';
7980
8244
  const scriptLang = script && script.lang;
7981
8245
  const scriptSetupLang = scriptSetup && scriptSetup.lang;
7982
8246
  const isTS = scriptLang === 'ts' ||
@@ -8013,6 +8277,11 @@ function compileScript(sfc, options = {}) {
8013
8277
  sourceType: 'module'
8014
8278
  }).program;
8015
8279
  const bindings = analyzeScriptBindings(scriptAst.body);
8280
+ if (cssVars.length) {
8281
+ content = rewriteDefault(content, DEFAULT_VAR, plugins);
8282
+ content += genNormalScriptCssVarsCode(cssVars, bindings, scopeId, isProd);
8283
+ content += `\nexport default ${DEFAULT_VAR}`;
8284
+ }
8016
8285
  return Object.assign(Object.assign({}, script), { content,
8017
8286
  map,
8018
8287
  bindings, scriptAst: scriptAst.body });
@@ -8053,7 +8322,6 @@ function compileScript(sfc, options = {}) {
8053
8322
  let emitsTypeDecl;
8054
8323
  let emitsTypeDeclRaw;
8055
8324
  let emitIdentifier;
8056
- let hasAwait = false;
8057
8325
  // props/emits declared via types
8058
8326
  const typeDeclaredProps = {};
8059
8327
  const typeDeclaredEmits = new Set();
@@ -8233,33 +8501,6 @@ function compileScript(sfc, options = {}) {
8233
8501
  }
8234
8502
  });
8235
8503
  }
8236
- /**
8237
- * await foo()
8238
- * -->
8239
- * ;(
8240
- * ([__temp,__restore] = withAsyncContext(() => foo())),
8241
- * await __temp,
8242
- * __restore()
8243
- * )
8244
- *
8245
- * const a = await foo()
8246
- * -->
8247
- * const a = (
8248
- * ([__temp, __restore] = withAsyncContext(() => foo())),
8249
- * __temp = await __temp,
8250
- * __restore(),
8251
- * __temp
8252
- * )
8253
- */
8254
- function processAwait(node, needSemi, isStatement) {
8255
- const argumentStart = node.argument.extra && node.argument.extra.parenthesized
8256
- ? node.argument.extra.parenStart
8257
- : node.argument.start;
8258
- const argumentStr = source.slice(argumentStart + startOffset, node.argument.end + startOffset);
8259
- const containsNestedAwait = /\bawait\b/.test(argumentStr);
8260
- s.overwrite(node.start + startOffset, argumentStart + startOffset, `${needSemi ? `;` : ``}(\n ([__temp,__restore] = ${helper(`withAsyncContext`)}(${containsNestedAwait ? `async ` : ``}() => `);
8261
- s.appendLeft(node.end + startOffset, `)),\n ${isStatement ? `` : `__temp = `}await __temp,\n __restore()${isStatement ? `` : `,\n __temp`}\n)`);
8262
- }
8263
8504
  /**
8264
8505
  * check defaults. If the default object is an object literal with only
8265
8506
  * static properties, we can directly generate more optimized default
@@ -8614,18 +8855,7 @@ function compileScript(sfc, options = {}) {
8614
8855
  scope.push(child.body);
8615
8856
  }
8616
8857
  if (child.type === 'AwaitExpression') {
8617
- hasAwait = true;
8618
- // if the await expression is an expression statement and
8619
- // - is in the root scope
8620
- // - or is not the first statement in a nested block scope
8621
- // then it needs a semicolon before the generated code.
8622
- const currentScope = scope[scope.length - 1];
8623
- const needsSemi = currentScope.some((n, i) => {
8624
- return ((scope.length === 1 || i > 0) &&
8625
- n.type === 'ExpressionStatement' &&
8626
- n.start === child.start);
8627
- });
8628
- processAwait(child, needsSemi, parent.type === 'ExpressionStatement');
8858
+ error(`Vue 2 does not support top level await in <script setup>.`, child);
8629
8859
  }
8630
8860
  },
8631
8861
  exit(node) {
@@ -8752,7 +8982,10 @@ function compileScript(sfc, options = {}) {
8752
8982
  bindingMetadata[key] = setupBindings[key];
8753
8983
  }
8754
8984
  // 8. inject `useCssVars` calls
8755
- // Not backported in Vue 2
8985
+ if (cssVars.length) {
8986
+ helperImports.add(CSS_VARS_HELPER);
8987
+ s.prependRight(startOffset, `\n${genCssVarsCode(cssVars, bindingMetadata, scopeId, isProd)}\n`);
8988
+ }
8756
8989
  // 9. finalize setup() argument signature
8757
8990
  let args = `__props`;
8758
8991
  if (propsTypeDecl) {
@@ -8767,11 +9000,6 @@ function compileScript(sfc, options = {}) {
8767
9000
  if (propsIdentifier) {
8768
9001
  s.prependLeft(startOffset, `\nconst ${propsIdentifier} = __props${propsTypeDecl ? ` as ${genSetupPropsType(propsTypeDecl)}` : ``}\n`);
8769
9002
  }
8770
- // inject temp variables for async context preservation
8771
- if (hasAwait) {
8772
- const any = isTS ? `: any` : ``;
8773
- s.prependLeft(startOffset, `\nlet __temp${any}, __restore${any}\n`);
8774
- }
8775
9003
  const destructureElements = hasDefineExposeCall ? [`expose`] : [];
8776
9004
  if (emitIdentifier) {
8777
9005
  destructureElements.push(emitIdentifier === `emit` ? `emit` : `emit: ${emitIdentifier}`);
@@ -8826,7 +9054,7 @@ function compileScript(sfc, options = {}) {
8826
9054
  // user's TS setting should compile it down to proper targets
8827
9055
  // export default defineComponent({ ...__default__, ... })
8828
9056
  const def = defaultExport ? `\n ...${DEFAULT_VAR},` : ``;
8829
- s.prependLeft(startOffset, `\nexport default /*#__PURE__*/${helper(`defineComponent`)}({${def}${runtimeOptions}\n ${hasAwait ? `async ` : ``}setup(${args}) {\n`);
9057
+ s.prependLeft(startOffset, `\nexport default /*#__PURE__*/${helper(`defineComponent`)}({${def}${runtimeOptions}\n setup(${args}) {\n`);
8830
9058
  s.appendRight(endOffset, `})`);
8831
9059
  }
8832
9060
  else {
@@ -8834,12 +9062,11 @@ function compileScript(sfc, options = {}) {
8834
9062
  // without TS, can't rely on rest spread, so we use Object.assign
8835
9063
  // export default Object.assign(__default__, { ... })
8836
9064
  s.prependLeft(startOffset, `\nexport default /*#__PURE__*/Object.assign(${DEFAULT_VAR}, {${runtimeOptions}\n ` +
8837
- `${hasAwait ? `async ` : ``}setup(${args}) {\n`);
9065
+ `setup(${args}) {\n`);
8838
9066
  s.appendRight(endOffset, `})`);
8839
9067
  }
8840
9068
  else {
8841
- s.prependLeft(startOffset, `\nexport default {${runtimeOptions}\n ` +
8842
- `${hasAwait ? `async ` : ``}setup(${args}) {\n`);
9069
+ s.prependLeft(startOffset, `\nexport default {${runtimeOptions}\n setup(${args}) {\n`);
8843
9070
  s.appendRight(endOffset, `}`);
8844
9071
  }
8845
9072
  }
@@ -9377,7 +9604,7 @@ const cache = new lruCache(100);
9377
9604
  const splitRE = /\r?\n/g;
9378
9605
  const emptyRE = /^(?:\/\/)?\s*$/;
9379
9606
  function parse(options) {
9380
- const { source, filename = DEFAULT_FILENAME, compiler, compilerParseOptions = { pad: false }, sourceRoot = '', needMap = true } = options;
9607
+ const { source, filename = DEFAULT_FILENAME, compiler, compilerParseOptions = { pad: false }, sourceRoot = '', needMap = true, sourceMap = needMap } = options;
9381
9608
  const cacheKey = hashSum(filename + source + JSON.stringify(compilerParseOptions));
9382
9609
  let output = cache.get(cacheKey);
9383
9610
  if (output) {
@@ -9392,8 +9619,10 @@ function parse(options) {
9392
9619
  output = parseComponent(source, compilerParseOptions);
9393
9620
  }
9394
9621
  output.filename = filename;
9622
+ // parse CSS vars
9623
+ output.cssVars = parseCssVars(output);
9395
9624
  output.shouldForceReload = prevImports => hmrShouldReload(prevImports, output);
9396
- if (needMap) {
9625
+ if (sourceMap) {
9397
9626
  if (output.script && !output.script.src) {
9398
9627
  output.script.map = generateSourceMap(filename, source, output.script.content, sourceRoot, compilerParseOptions.pad);
9399
9628
  }
@@ -9444,6 +9673,9 @@ function urlToRequire(url, transformAssetUrlsOption = {}) {
9444
9673
  const secondChar = url.charAt(1);
9445
9674
  url = url.slice(secondChar === '/' ? 2 : 1);
9446
9675
  }
9676
+ if (isExternalUrl(url) || isDataUrl(url) || firstChar === '#') {
9677
+ return returnValue;
9678
+ }
9447
9679
  const uriParts = parseUriParts(url);
9448
9680
  if (transformAssetUrlsOption.base) {
9449
9681
  // explicit base - directly rewrite the url into absolute url
@@ -9456,7 +9688,10 @@ function urlToRequire(url, transformAssetUrlsOption = {}) {
9456
9688
  }
9457
9689
  return returnValue;
9458
9690
  }
9459
- if (firstChar === '.' || firstChar === '~' || firstChar === '@') {
9691
+ if (transformAssetUrlsOption.includeAbsolute ||
9692
+ firstChar === '.' ||
9693
+ firstChar === '~' ||
9694
+ firstChar === '@') {
9460
9695
  if (!uriParts.hash) {
9461
9696
  return `require("${url}")`;
9462
9697
  }
@@ -9486,6 +9721,14 @@ function parseUriParts(urlString) {
9486
9721
  }
9487
9722
  }
9488
9723
  return returnValue;
9724
+ }
9725
+ const externalRE = /^(https?:)?\/\//;
9726
+ function isExternalUrl(url) {
9727
+ return externalRE.test(url);
9728
+ }
9729
+ const dataUrlRE = /^\s*data:/i;
9730
+ function isDataUrl(url) {
9731
+ return dataUrlRE.test(url);
9489
9732
  }
9490
9733
 
9491
9734
  // vue compiler module for transforming `<tag>:<attribute>` to `require`
@@ -12912,57 +13155,6 @@ var _compiler = /*#__PURE__*/Object.freeze({
12912
13155
  generateCodeFrame: generateCodeFrame
12913
13156
  });
12914
13157
 
12915
- const doNotPrefix = makeMap('Infinity,undefined,NaN,isFinite,isNaN,' +
12916
- 'parseFloat,parseInt,decodeURI,decodeURIComponent,encodeURI,encodeURIComponent,' +
12917
- 'Math,Number,Date,Array,Object,Boolean,String,RegExp,Map,Set,JSON,Intl,' +
12918
- 'require,' + // for webpack
12919
- 'arguments,' + // parsed as identifier but is a special keyword...
12920
- '_c' // cached to save property access
12921
- );
12922
- /**
12923
- * The input is expected to be the render function code directly returned from
12924
- * `compile()` calls, e.g. `with(this){return ...}`
12925
- */
12926
- function prefixIdentifiers(source, fnName = '', isFunctional = false, isTS = false, babelOptions = {}, bindings) {
12927
- source = `function ${fnName}(${isFunctional ? `_c,_vm` : ``}){${source}\n}`;
12928
- const s = new MagicString(source);
12929
- const plugins = [
12930
- ...(isTS ? ['typescript'] : []),
12931
- ...((babelOptions === null || babelOptions === void 0 ? void 0 : babelOptions.plugins) || [])
12932
- ];
12933
- const ast = parser$1.parseExpression(source, Object.assign(Object.assign({}, babelOptions), { plugins }));
12934
- const isScriptSetup = bindings && bindings.__isScriptSetup !== false;
12935
- walkIdentifiers(ast, ident => {
12936
- const { name } = ident;
12937
- if (doNotPrefix(name)) {
12938
- return;
12939
- }
12940
- if (!isScriptSetup) {
12941
- s.prependRight(ident.start, '_vm.');
12942
- return;
12943
- }
12944
- s.overwrite(ident.start, ident.end, rewriteIdentifier(name, bindings));
12945
- }, node => {
12946
- if (node.type === 'WithStatement') {
12947
- s.remove(node.start, node.body.start + 1);
12948
- s.remove(node.end - 1, node.end);
12949
- if (!isFunctional) {
12950
- s.prependRight(node.start, `var _vm=this,_c=_vm._self._c${isScriptSetup ? `,_setup=_vm._setupProxy;` : `;`}`);
12951
- }
12952
- }
12953
- });
12954
- return s.toString();
12955
- }
12956
- function rewriteIdentifier(name, bindings) {
12957
- const type = bindings[name];
12958
- if (type && type.startsWith('setup')) {
12959
- return `_setup.${name}`;
12960
- }
12961
- else {
12962
- return `_vm.${name}`;
12963
- }
12964
- }
12965
-
12966
13158
  function compileTemplate(options) {
12967
13159
  const { preprocessLang } = options;
12968
13160
  const preprocessor = preprocessLang && consolidate[preprocessLang];
@@ -13037,8 +13229,8 @@ function actuallyCompile(options) {
13037
13229
  else {
13038
13230
  // transpile code with vue-template-es2015-compiler, which is a forked
13039
13231
  // version of Buble that applies ES2015 transforms + stripping `with` usage
13040
- let code = `var __render__ = ${prefixIdentifiers(render, `render`, isFunctional, isTS, transpileOptions, bindings)}\n` +
13041
- `var __staticRenderFns__ = [${staticRenderFns.map(code => prefixIdentifiers(code, ``, isFunctional, isTS, transpileOptions, bindings))}]` +
13232
+ let code = `var __render__ = ${prefixIdentifiers(`function render(${isFunctional ? `_c,_vm` : ``}){${render}\n}`, isFunctional, isTS, transpileOptions, bindings)}\n` +
13233
+ `var __staticRenderFns__ = [${staticRenderFns.map(code => prefixIdentifiers(`function (${isFunctional ? `_c,_vm` : ``}){${code}\n}`, isFunctional, isTS, transpileOptions, bindings))}]` +
13042
13234
  `\n`;
13043
13235
  // #23 we use __render__ to avoid `render` not being prefixed by the
13044
13236
  // transpiler when stripping with, but revert it back to `render` to
@@ -17310,9 +17502,8 @@ function processRule(id, rule) {
17310
17502
  });
17311
17503
  }).processSync(rule.selector);
17312
17504
  }
17313
- function rewriteSelector(id, selector, selectorRoot, slotted = false) {
17505
+ function rewriteSelector(id, selector, selectorRoot) {
17314
17506
  let node = null;
17315
- let shouldInject = true;
17316
17507
  // find the last child node to insert attribute selector
17317
17508
  selector.each(n => {
17318
17509
  // DEPRECATED ">>>" and "/deep/" combinator
@@ -17359,23 +17550,22 @@ function rewriteSelector(id, selector, selectorRoot, slotted = false) {
17359
17550
  }
17360
17551
  return false;
17361
17552
  }
17362
- // slot: use selector inside `::v-slotted` and inject [id + '-s']
17363
- // instead.
17553
+ // !!! Vue 2 does not have :slotted support
17364
17554
  // ::v-slotted(.foo) -> .foo[xxxxxxx-s]
17365
- if (value === ':slotted' || value === '::v-slotted') {
17366
- rewriteSelector(id, n.nodes[0], selectorRoot, true /* slotted */);
17367
- let last = n;
17368
- n.nodes[0].each(ss => {
17369
- selector.insertAfter(last, ss);
17370
- last = ss;
17371
- });
17372
- // selector.insertAfter(n, n.nodes[0])
17373
- selector.removeChild(n);
17374
- // since slotted attribute already scopes the selector there's no
17375
- // need for the non-slot attribute.
17376
- shouldInject = false;
17377
- return false;
17378
- }
17555
+ // if (value === ':slotted' || value === '::v-slotted') {
17556
+ // rewriteSelector(id, n.nodes[0], selectorRoot, true /* slotted */)
17557
+ // let last: selectorParser.Selector['nodes'][0] = n
17558
+ // n.nodes[0].each(ss => {
17559
+ // selector.insertAfter(last, ss)
17560
+ // last = ss
17561
+ // })
17562
+ // // selector.insertAfter(n, n.nodes[0])
17563
+ // selector.removeChild(n)
17564
+ // // since slotted attribute already scopes the selector there's no
17565
+ // // need for the non-slot attribute.
17566
+ // shouldInject = false
17567
+ // return false
17568
+ // }
17379
17569
  // global: replace with inner selector and do not inject [id].
17380
17570
  // ::v-global(.foo) -> .foo
17381
17571
  if (value === ':global' || value === '::v-global') {
@@ -17397,14 +17587,13 @@ function rewriteSelector(id, selector, selectorRoot, slotted = false) {
17397
17587
  // So all leading spaces must be eliminated to avoid problems.
17398
17588
  selector.first.spaces.before = '';
17399
17589
  }
17400
- if (shouldInject) {
17401
- const idToAdd = slotted ? id + '-s' : id;
17590
+ {
17402
17591
  selector.insertAfter(
17403
17592
  // If node is null it means we need to inject [id] at the start
17404
17593
  // insertAfter can handle `null` here
17405
17594
  node, selectorParser.attribute({
17406
- attribute: idToAdd,
17407
- value: idToAdd,
17595
+ attribute: id,
17596
+ value: id,
17408
17597
  raws: {},
17409
17598
  quoteMark: `"`
17410
17599
  }));
@@ -17577,12 +17766,13 @@ function compileStyleAsync(options) {
17577
17766
  return Promise.resolve(doCompileStyle(Object.assign(Object.assign({}, options), { isAsync: true })));
17578
17767
  }
17579
17768
  function doCompileStyle(options) {
17580
- const { filename, id, scoped = true, trim = true, preprocessLang, postcssOptions, postcssPlugins } = options;
17769
+ const { filename, id, scoped = true, trim = true, isProd = false, preprocessLang, postcssOptions, postcssPlugins } = options;
17581
17770
  const preprocessor = preprocessLang && processors[preprocessLang];
17582
17771
  const preProcessedSource = preprocessor && preprocess(options, preprocessor);
17583
17772
  const map = preProcessedSource ? preProcessedSource.map : options.map;
17584
17773
  const source = preProcessedSource ? preProcessedSource.code : options.source;
17585
17774
  const plugins = (postcssPlugins || []).slice();
17775
+ plugins.unshift(cssVarsPlugin({ id: id.replace(/^data-v-/, ''), isProd }));
17586
17776
  if (trim) {
17587
17777
  plugins.push(trimPlugin());
17588
17778
  }
@@ -17646,3 +17836,4 @@ exports.compileStyleAsync = compileStyleAsync;
17646
17836
  exports.compileTemplate = compileTemplate;
17647
17837
  exports.generateCodeFrame = generateCodeFrame;
17648
17838
  exports.parse = parse;
17839
+ exports.rewriteDefault = rewriteDefault;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@vue/compiler-sfc",
3
- "version": "2.7.0-alpha.9",
3
+ "version": "2.7.0-beta.3",
4
4
  "description": "compiler-sfc for Vue 2",
5
5
  "main": "dist/compiler-sfc.js",
6
6
  "types": "dist/compiler-sfc.d.ts",