@vue/compiler-sfc 3.0.7 → 3.0.11

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.
package/README.md CHANGED
@@ -4,10 +4,6 @@
4
4
 
5
5
  This package contains lower level utilities that you can use if you are writing a plugin / transform for a bundler or module system that compiles Vue Single File Components (SFCs) into JavaScript. It is used in [vue-loader](https://github.com/vuejs/vue-loader), [rollup-plugin-vue](https://github.com/vuejs/rollup-plugin-vue) and [vite](https://github.com/vitejs/vite).
6
6
 
7
- ## Browser Build Notes
8
-
9
- The browser build relies on a browser-bundled build of `postcss` to be available under the global `postcss` (since it can't be properly bundled by Rollup).
10
-
11
7
  ## API
12
8
 
13
9
  The API is intentionally low-level due to the various considerations when integrating Vue SFCs in a build system:
@@ -123,6 +123,10 @@ function warn(msg) {
123
123
  console.warn(`\x1b[1m\x1b[33m[@vue/compiler-sfc]\x1b[0m\x1b[33m ${msg}\x1b[0m\n`);
124
124
  }
125
125
  function warnExperimental(feature, rfcId) {
126
+ // eslint-disable-next-line
127
+ if (typeof window !== 'undefined') {
128
+ return;
129
+ }
126
130
  warnOnce(`${feature} is still an experimental proposal.\n` +
127
131
  `Follow its status at https://github.com/vuejs/rfcs/pull/${rfcId}.`);
128
132
  warnOnce(`When using experimental features,\n` +
@@ -145,7 +149,8 @@ function parse(source, { sourceMap = true, filename = 'anonymous.vue', sourceRoo
145
149
  scriptSetup: null,
146
150
  styles: [],
147
151
  customBlocks: [],
148
- cssVars: []
152
+ cssVars: [],
153
+ slotted: false
149
154
  };
150
155
  const errors = [];
151
156
  const ast = compiler.parse(source, {
@@ -245,6 +250,9 @@ function parse(source, { sourceMap = true, filename = 'anonymous.vue', sourceRoo
245
250
  if (descriptor.cssVars.length) {
246
251
  warnExperimental(`v-bind() CSS variable injection`, 231);
247
252
  }
253
+ // check if the SFC uses :slotted
254
+ const slottedRE = /(?:::v-|:)slotted\(/;
255
+ descriptor.slotted = descriptor.styles.some(s => s.scoped && slottedRE.test(s.content));
248
256
  const result = {
249
257
  descriptor,
250
258
  errors
@@ -529,17 +537,23 @@ const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
529
537
  .split(' ', 2);
530
538
  return { url, descriptor };
531
539
  });
532
- // for data url need recheck url
540
+ // data urls contains comma after the ecoding so we need to re-merge
541
+ // them
533
542
  for (let i = 0; i < imageCandidates.length; i++) {
534
- if (imageCandidates[i].url.trim().startsWith('data:')) {
543
+ const { url } = imageCandidates[i];
544
+ if (isDataUrl(url)) {
535
545
  imageCandidates[i + 1].url =
536
- imageCandidates[i].url + ',' + imageCandidates[i + 1].url;
546
+ url + ',' + imageCandidates[i + 1].url;
537
547
  imageCandidates.splice(i, 1);
538
548
  }
539
549
  }
540
- // When srcset does not contain any relative URLs, skip transforming
541
- if (!options.includeAbsolute &&
542
- !imageCandidates.some(({ url }) => isRelativeUrl(url))) {
550
+ const hasQualifiedUrl = imageCandidates.some(({ url }) => {
551
+ return (!isExternalUrl(url) &&
552
+ !isDataUrl(url) &&
553
+ (options.includeAbsolute || isRelativeUrl(url)));
554
+ });
555
+ // When srcset does not contain any qualified URLs, skip transforming
556
+ if (!hasQualifiedUrl) {
543
557
  return;
544
558
  }
545
559
  if (options.base) {
@@ -582,10 +596,10 @@ const transformSrcset = (node, context, options = defaultAssetUrlOptions) => {
582
596
  }
583
597
  const isNotLast = imageCandidates.length - 1 > index;
584
598
  if (descriptor && isNotLast) {
585
- compoundExpression.children.push(` + '${descriptor}, ' + `);
599
+ compoundExpression.children.push(` + ' ${descriptor}, ' + `);
586
600
  }
587
601
  else if (descriptor) {
588
- compoundExpression.children.push(` + '${descriptor}'`);
602
+ compoundExpression.children.push(` + ' ${descriptor}'`);
589
603
  }
590
604
  else if (isNotLast) {
591
605
  compoundExpression.children.push(` + ', ' + `);
@@ -662,7 +676,7 @@ function compileTemplate(options) {
662
676
  return doCompileTemplate(options);
663
677
  }
664
678
  }
665
- function doCompileTemplate({ filename, id, scoped, inMap, source, ssr = false, ssrCssVars, isProd = false, compiler = ssr ? CompilerSSR__namespace : CompilerDOM__namespace, compilerOptions = {}, transformAssetUrls }) {
679
+ function doCompileTemplate({ filename, id, scoped, slotted, inMap, source, ssr = false, ssrCssVars, isProd = false, compiler = ssr ? CompilerSSR__namespace : CompilerDOM__namespace, compilerOptions = {}, transformAssetUrls }) {
666
680
  const errors = [];
667
681
  let nodeTransforms = [];
668
682
  if (shared.isObject(transformAssetUrls)) {
@@ -694,6 +708,7 @@ function doCompileTemplate({ filename, id, scoped, inMap, source, ssr = false, s
694
708
  ? genCssVarsFromList(ssrCssVars, shortId, isProd)
695
709
  : '',
696
710
  scopeId: scoped ? longId : undefined,
711
+ slotted,
697
712
  ...compilerOptions,
698
713
  nodeTransforms: nodeTransforms.concat(compilerOptions.nodeTransforms || []),
699
714
  filename,
@@ -848,7 +863,10 @@ const scopedPlugin = (id = '') => {
848
863
  };
849
864
  const processedRules = new WeakSet();
850
865
  function processRule(id, rule) {
851
- if (processedRules.has(rule)) {
866
+ if (processedRules.has(rule) ||
867
+ (rule.parent &&
868
+ rule.parent.type === 'atrule' &&
869
+ /-?keyframes$/.test(rule.parent.name))) {
852
870
  return;
853
871
  }
854
872
  processedRules.add(rule);
@@ -1402,12 +1420,12 @@ function compileScript(sfc, options) {
1402
1420
  }
1403
1421
  const typeArg = node.typeParameters.params[0];
1404
1422
  if (typeArg.type === 'TSFunctionType' ||
1405
- typeArg.type === 'TSUnionType') {
1423
+ typeArg.type === 'TSTypeLiteral') {
1406
1424
  emitTypeDecl = typeArg;
1407
1425
  }
1408
1426
  else {
1409
1427
  error(`type argument passed to ${DEFINE_EMIT}() must be a function type ` +
1410
- `or a union of function types.`, typeArg);
1428
+ `or a literal type with call signatures.`, typeArg);
1411
1429
  }
1412
1430
  }
1413
1431
  return true;
@@ -2230,17 +2248,19 @@ function toRuntimeTypeString(types) {
2230
2248
  : types[0];
2231
2249
  }
2232
2250
  function extractRuntimeEmits(node, emits) {
2233
- if (node.type === 'TSUnionType') {
2234
- for (let t of node.types) {
2235
- if (t.type === 'TSParenthesizedType')
2236
- t = t.typeAnnotation;
2237
- if (t.type === 'TSFunctionType') {
2238
- extractRuntimeEmits(t, emits);
2251
+ if (node.type === 'TSTypeLiteral') {
2252
+ for (let t of node.members) {
2253
+ if (t.type === 'TSCallSignatureDeclaration') {
2254
+ extractEventNames(t.parameters[0], emits);
2239
2255
  }
2240
2256
  }
2241
2257
  return;
2242
2258
  }
2243
- const eventName = node.parameters[0];
2259
+ else {
2260
+ extractEventNames(node.parameters[0], emits);
2261
+ }
2262
+ }
2263
+ function extractEventNames(eventName, emits) {
2244
2264
  if (eventName.type === 'Identifier' &&
2245
2265
  eventName.typeAnnotation &&
2246
2266
  eventName.typeAnnotation.type === 'TSTypeAnnotation') {
@@ -2264,6 +2284,19 @@ function genRuntimeEmits(emits) {
2264
2284
  .join(', ')}] as unknown as undefined,`
2265
2285
  : ``;
2266
2286
  }
2287
+ function markScopeIdentifier(node, child, knownIds) {
2288
+ const { name } = child;
2289
+ if (node.scopeIds && node.scopeIds.has(name)) {
2290
+ return;
2291
+ }
2292
+ if (name in knownIds) {
2293
+ knownIds[name]++;
2294
+ }
2295
+ else {
2296
+ knownIds[name] = 1;
2297
+ }
2298
+ (node.scopeIds || (node.scopeIds = new Set())).add(name);
2299
+ }
2267
2300
  /**
2268
2301
  * Walk an AST and find identifiers that are variable references.
2269
2302
  * This is largely the same logic with `transformExpressions` in compiler-core
@@ -2283,6 +2316,19 @@ function walkIdentifiers(root, onIdentifier) {
2283
2316
  }
2284
2317
  }
2285
2318
  else if (isFunction(node)) {
2319
+ // #3445
2320
+ // should not rewrite local variables sharing a name with a top-level ref
2321
+ if (node.body.type === 'BlockStatement') {
2322
+ node.body.body.forEach(p => {
2323
+ if (p.type === 'VariableDeclaration') {
2324
+ for (const decl of p.declarations) {
2325
+ extractIdentifiers(decl.id).forEach(id => {
2326
+ markScopeIdentifier(node, id, knownIds);
2327
+ });
2328
+ }
2329
+ }
2330
+ });
2331
+ }
2286
2332
  // walk function expressions and add its arguments to known identifiers
2287
2333
  // so that we don't prefix them
2288
2334
  node.params.forEach(p => estreeWalker.walk(p, {
@@ -2295,17 +2341,7 @@ function walkIdentifiers(root, onIdentifier) {
2295
2341
  !(parent &&
2296
2342
  parent.type === 'AssignmentPattern' &&
2297
2343
  parent.right === child)) {
2298
- const { name } = child;
2299
- if (node.scopeIds && node.scopeIds.has(name)) {
2300
- return;
2301
- }
2302
- if (name in knownIds) {
2303
- knownIds[name]++;
2304
- }
2305
- else {
2306
- knownIds[name] = 1;
2307
- }
2308
- (node.scopeIds || (node.scopeIds = new Set())).add(name);
2344
+ markScopeIdentifier(node, child, knownIds);
2309
2345
  }
2310
2346
  }
2311
2347
  }));
@@ -2440,6 +2476,12 @@ function analyzeScriptBindings(ast) {
2440
2476
  }
2441
2477
  function analyzeBindingsFromOptions(node) {
2442
2478
  const bindings = {};
2479
+ // #3270, #3275
2480
+ // mark non-script-setup so we don't resolve components/directives from these
2481
+ Object.defineProperty(bindings, '__isScriptSetup', {
2482
+ enumerable: false,
2483
+ value: false
2484
+ });
2443
2485
  for (const property of node.properties) {
2444
2486
  if (property.type === 'ObjectProperty' &&
2445
2487
  !property.computed &&
@@ -2527,12 +2569,53 @@ function getObjectOrArrayExpressionKeys(value) {
2527
2569
  return getObjectExpressionKeys(value);
2528
2570
  }
2529
2571
  return [];
2572
+ }
2573
+ function extractIdentifiers(param, nodes = []) {
2574
+ switch (param.type) {
2575
+ case 'Identifier':
2576
+ nodes.push(param);
2577
+ break;
2578
+ case 'MemberExpression':
2579
+ let object = param;
2580
+ while (object.type === 'MemberExpression') {
2581
+ object = object.object;
2582
+ }
2583
+ nodes.push(object);
2584
+ break;
2585
+ case 'ObjectPattern':
2586
+ param.properties.forEach(prop => {
2587
+ if (prop.type === 'RestElement') {
2588
+ extractIdentifiers(prop.argument, nodes);
2589
+ }
2590
+ else {
2591
+ extractIdentifiers(prop.value, nodes);
2592
+ }
2593
+ });
2594
+ break;
2595
+ case 'ArrayPattern':
2596
+ param.elements.forEach(element => {
2597
+ if (element)
2598
+ extractIdentifiers(element, nodes);
2599
+ });
2600
+ break;
2601
+ case 'RestElement':
2602
+ extractIdentifiers(param.argument, nodes);
2603
+ break;
2604
+ case 'AssignmentPattern':
2605
+ extractIdentifiers(param.left, nodes);
2606
+ break;
2607
+ }
2608
+ return nodes;
2530
2609
  }
2531
2610
 
2532
2611
  exports.generateCodeFrame = compilerCore.generateCodeFrame;
2612
+ exports.MagicString = MagicString__default;
2613
+ exports.babelParse = parser.parse;
2614
+ exports.walk = estreeWalker.walk;
2533
2615
  exports.compileScript = compileScript;
2534
2616
  exports.compileStyle = compileStyle;
2535
2617
  exports.compileStyleAsync = compileStyleAsync;
2536
2618
  exports.compileTemplate = compileTemplate;
2537
2619
  exports.parse = parse;
2538
2620
  exports.rewriteDefault = rewriteDefault;
2621
+ exports.walkIdentifiers = walkIdentifiers;
@@ -1,10 +1,14 @@
1
+ import { parse as babelParse } from '@babel/parser';
1
2
  import { BindingMetadata } from '@vue/compiler-core';
2
3
  import { CodegenResult } from '@vue/compiler-core';
3
4
  import { CompilerError } from '@vue/compiler-core';
4
5
  import { CompilerOptions } from '@vue/compiler-core';
5
6
  import { ElementNode } from '@vue/compiler-core';
6
7
  import { generateCodeFrame } from '@vue/compiler-core';
8
+ import { Identifier } from '@babel/types';
7
9
  import { LazyResult } from 'postcss';
10
+ import MagicString from 'magic-string';
11
+ import { Node as Node_2 } from '@babel/types';
8
12
  import { ParserOptions } from '@vue/compiler-core';
9
13
  import { ParserPlugin } from '@babel/parser';
10
14
  import { RawSourceMap } from 'source-map';
@@ -12,6 +16,7 @@ import { Result } from 'postcss';
12
16
  import { RootNode } from '@vue/compiler-core';
13
17
  import { SourceLocation } from '@vue/compiler-core';
14
18
  import { Statement } from '@babel/types';
19
+ import { walk } from 'estree-walker';
15
20
 
16
21
  declare interface AssetURLOptions {
17
22
  /**
@@ -29,6 +34,7 @@ declare interface AssetURLOptions {
29
34
  declare interface AssetURLTagConfig {
30
35
  [name: string]: string[];
31
36
  }
37
+ export { babelParse }
32
38
  export { BindingMetadata }
33
39
  export { CompilerError }
34
40
  export { CompilerOptions }
@@ -59,6 +65,7 @@ declare interface CSSModulesOptions {
59
65
  globalModulePaths?: string[];
60
66
  }
61
67
  export { generateCodeFrame }
68
+ export { MagicString }
62
69
 
63
70
  export declare function parse(source: string, { sourceMap, filename, sourceRoot, pad, compiler }?: SFCParseOptions): SFCParseResult;
64
71
 
@@ -95,6 +102,7 @@ export declare interface SFCDescriptor {
95
102
  styles: SFCStyleBlock[];
96
103
  customBlocks: SFCBlock[];
97
104
  cssVars: string[];
105
+ slotted: boolean;
98
106
  }
99
107
 
100
108
  export declare interface SFCParseOptions {
@@ -193,6 +201,7 @@ export declare interface SFCTemplateCompileOptions {
193
201
  filename: string;
194
202
  id: string;
195
203
  scoped?: boolean;
204
+ slotted?: boolean;
196
205
  isProd?: boolean;
197
206
  ssr?: boolean;
198
207
  ssrCssVars?: string[];
@@ -228,5 +237,14 @@ export declare interface TemplateCompiler {
228
237
  compile(template: string, options: CompilerOptions): CodegenResult;
229
238
  parse(template: string, options: ParserOptions): RootNode;
230
239
  }
240
+ export { walk }
241
+
242
+ /**
243
+ * Walk an AST and find identifiers that are variable references.
244
+ * This is largely the same logic with `transformExpressions` in compiler-core
245
+ * but with some subtle differences as this needs to handle a wider range of
246
+ * possible syntax.
247
+ */
248
+ export declare function walkIdentifiers(root: Node_2, onIdentifier: (node: Identifier, parent: Node_2, parentStack: Node_2[]) => void): void;
231
249
 
232
250
  export { }