@parcel/packager-js 2.7.0 → 2.8.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.
@@ -74,16 +74,14 @@ class DevPackager {
74
74
  let queue = new (_utils().PromiseQueue)({
75
75
  maxConcurrent: 32
76
76
  });
77
- this.bundle.traverse(node => {
78
- if (node.type === 'asset') {
79
- queue.add(async () => {
80
- let [code, mapBuffer] = await Promise.all([node.value.getCode(), this.bundle.env.sourceMap && node.value.getMapBuffer()]);
81
- return {
82
- code,
83
- mapBuffer
84
- };
85
- });
86
- }
77
+ this.bundle.traverseAssets(asset => {
78
+ queue.add(async () => {
79
+ let [code, mapBuffer] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap && asset.getMapBuffer()]);
80
+ return {
81
+ code,
82
+ mapBuffer
83
+ };
84
+ });
87
85
  });
88
86
  let results = await queue.run();
89
87
  let assets = '';
@@ -468,55 +468,60 @@ class ScopeHoistingPackager {
468
468
 
469
469
 
470
470
  if (d != null) {
471
- let dep = depMap.get(d);
471
+ let deps = depMap.get(d);
472
472
 
473
- if (!dep) {
473
+ if (!deps) {
474
474
  return m;
475
475
  }
476
476
 
477
- let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
478
- let skipped = this.bundleGraph.isDependencySkipped(dep);
479
-
480
- if (resolved && !skipped) {
481
- // Hoist variable declarations for the referenced parcelRequire dependencies
482
- // after the dependency is declared. This handles the case where the resulting asset
483
- // is wrapped, but the dependency in this asset is not marked as wrapped. This means
484
- // that it was imported/required at the top-level, so its side effects should run immediately.
485
- let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
486
- let map;
487
-
488
- if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
489
- // If this asset is wrapped, we need to hoist the code for the dependency
490
- // outside our parcelRequire.register wrapper. This is safe because all
491
- // assets referenced by this asset will also be wrapped. Otherwise, inline the
492
- // asset content where the import statement was.
493
- if (shouldWrap) {
494
- depContent.push(this.visitAsset(resolved));
495
- } else {
496
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
497
- res = depCode + '\n' + res;
498
- lines += 1 + depLines;
499
- map = depMap;
500
- }
501
- } // Push this asset's source mappings down by the number of lines in the dependency
502
- // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
477
+ let replacement = ''; // A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
478
+ // reexports.
479
+
480
+ for (let dep of deps) {
481
+ let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
482
+ let skipped = this.bundleGraph.isDependencySkipped(dep);
483
+
484
+ if (resolved && !skipped) {
485
+ // Hoist variable declarations for the referenced parcelRequire dependencies
486
+ // after the dependency is declared. This handles the case where the resulting asset
487
+ // is wrapped, but the dependency in this asset is not marked as wrapped. This means
488
+ // that it was imported/required at the top-level, so its side effects should run immediately.
489
+ let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
490
+ let map;
491
+
492
+ if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
493
+ // If this asset is wrapped, we need to hoist the code for the dependency
494
+ // outside our parcelRequire.register wrapper. This is safe because all
495
+ // assets referenced by this asset will also be wrapped. Otherwise, inline the
496
+ // asset content where the import statement was.
497
+ if (shouldWrap) {
498
+ depContent.push(this.visitAsset(resolved));
499
+ } else {
500
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
501
+ res = depCode + '\n' + res;
502
+ lines += 1 + depLines;
503
+ map = depMap;
504
+ }
505
+ } // Push this asset's source mappings down by the number of lines in the dependency
506
+ // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
503
507
 
504
508
 
505
- if (sourceMap) {
506
- if (lines > 0) {
507
- sourceMap.offsetLines(lineCount + 1, lines);
508
- }
509
+ if (sourceMap) {
510
+ if (lines > 0) {
511
+ sourceMap.offsetLines(lineCount + 1, lines);
512
+ }
509
513
 
510
- if (map) {
511
- sourceMap.addSourceMap(map, lineCount);
514
+ if (map) {
515
+ sourceMap.addSourceMap(map, lineCount);
516
+ }
512
517
  }
513
- }
514
518
 
515
- lineCount += lines;
516
- return res;
519
+ replacement += res;
520
+ lineCount += lines;
521
+ }
517
522
  }
518
523
 
519
- return '';
524
+ return replacement;
520
525
  } // If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
521
526
 
522
527
 
@@ -571,12 +576,12 @@ ${code}
571
576
  (0, _assert().default)(typeof assetId === 'string'); // Build two maps: one of import specifiers, and one of imported symbols to replace.
572
577
  // These will be used to build a regex below.
573
578
 
574
- let depMap = new Map();
579
+ let depMap = new (_utils().DefaultMap)(() => []);
575
580
  let replacements = new Map();
576
581
 
577
582
  for (let dep of deps) {
578
583
  let specifierType = dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
579
- depMap.set(`${assetId}:${(0, _utils2.getSpecifier)(dep)}${!dep.meta.placeholder ? specifierType : ''}`, dep);
584
+ depMap.get(`${assetId}:${(0, _utils2.getSpecifier)(dep)}${!dep.meta.placeholder ? specifierType : ''}`).push(dep);
580
585
  let asyncResolution = this.bundleGraph.resolveAsyncDependency(dep, this.bundle);
581
586
  let resolved = (asyncResolution === null || asyncResolution === void 0 ? void 0 : asyncResolution.type) === 'asset' ? // Prefer the underlying asset over a runtime to load it. It will
582
587
  // be wrapped in Promise.resolve() later.
@@ -850,44 +855,9 @@ ${code}
850
855
  prepend += `\n$parcel$defineInteropFlag($${assetId}$exports);\n`;
851
856
  prependLineCount += 2;
852
857
  this.usedHelpers.add('$parcel$defineInteropFlag');
853
- } // Find the used exports of this module. This is based on the used symbols of
854
- // incoming dependencies rather than the asset's own used exports so that we include
855
- // re-exported symbols rather than only symbols declared in this asset.
856
-
857
-
858
- let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
859
- let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
860
- if (symbol === '*') {
861
- return false;
862
- } // If we need default interop, then all symbols are needed because the `default`
863
- // symbol really maps to the whole namespace.
864
-
865
-
866
- if (defaultInterop) {
867
- return true;
868
- }
869
-
870
- let unused = incomingDeps.every(d => {
871
- let symbols = (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(d));
872
- return !symbols.has(symbol) && !symbols.has('*');
873
- });
874
- return !unused;
875
- });
876
-
877
- if (usedExports.length > 0) {
878
- // Insert $parcel$export calls for each of the used exports. This creates a getter/setter
879
- // for the symbol so that when the value changes the object property also changes. This is
880
- // required to simulate ESM live bindings. It's easier to do it this way rather than inserting
881
- // additional assignments after each mutation of the original binding.
882
- prepend += `\n${usedExports.map(exp => {
883
- let resolved = this.getSymbolResolution(asset, asset, exp);
884
- let get = this.buildFunctionExpression([], resolved);
885
- let set = asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`) : '';
886
- return `$parcel$export($${assetId}$exports, ${JSON.stringify(exp)}, ${get}${set});`;
887
- }).join('\n')}\n`;
888
- this.usedHelpers.add('$parcel$export');
889
- prependLineCount += 1 + usedExports.length;
890
- } // Find wildcard re-export dependencies, and make sure their exports are also included in ours.
858
+ } // Find wildcard re-export dependencies, and make sure their exports are also included in
859
+ // ours. Importantly, add them before the asset's own exports so that wildcard exports get
860
+ // correctly overwritten by own exports of the same name.
891
861
 
892
862
 
893
863
  for (let dep of deps) {
@@ -936,6 +906,43 @@ ${code}
936
906
  }
937
907
  }
938
908
  }
909
+ } // Find the used exports of this module. This is based on the used symbols of
910
+ // incoming dependencies rather than the asset's own used exports so that we include
911
+ // re-exported symbols rather than only symbols declared in this asset.
912
+
913
+
914
+ let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
915
+ let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
916
+ if (symbol === '*') {
917
+ return false;
918
+ } // If we need default interop, then all symbols are needed because the `default`
919
+ // symbol really maps to the whole namespace.
920
+
921
+
922
+ if (defaultInterop) {
923
+ return true;
924
+ }
925
+
926
+ let unused = incomingDeps.every(d => {
927
+ let symbols = (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(d));
928
+ return !symbols.has(symbol) && !symbols.has('*');
929
+ });
930
+ return !unused;
931
+ });
932
+
933
+ if (usedExports.length > 0) {
934
+ // Insert $parcel$export calls for each of the used exports. This creates a getter/setter
935
+ // for the symbol so that when the value changes the object property also changes. This is
936
+ // required to simulate ESM live bindings. It's easier to do it this way rather than inserting
937
+ // additional assignments after each mutation of the original binding.
938
+ prepend += `\n${usedExports.map(exp => {
939
+ let resolved = this.getSymbolResolution(asset, asset, exp);
940
+ let get = this.buildFunctionExpression([], resolved);
941
+ let set = asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`) : '';
942
+ return `$parcel$export($${assetId}$exports, ${JSON.stringify(exp)}, ${get}${set});`;
943
+ }).join('\n')}\n`;
944
+ this.usedHelpers.add('$parcel$export');
945
+ prependLineCount += 1 + usedExports.length;
939
946
  }
940
947
  }
941
948
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@parcel/packager-js",
3
- "version": "2.7.0",
3
+ "version": "2.8.1",
4
4
  "license": "MIT",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,16 +17,16 @@
17
17
  "source": "src/index.js",
18
18
  "engines": {
19
19
  "node": ">= 12.0.0",
20
- "parcel": "^2.7.0"
20
+ "parcel": "^2.8.1"
21
21
  },
22
22
  "dependencies": {
23
- "@parcel/diagnostic": "2.7.0",
24
- "@parcel/hash": "2.7.0",
25
- "@parcel/plugin": "2.7.0",
26
- "@parcel/source-map": "^2.0.0",
27
- "@parcel/utils": "2.7.0",
23
+ "@parcel/diagnostic": "2.8.1",
24
+ "@parcel/hash": "2.8.1",
25
+ "@parcel/plugin": "2.8.1",
26
+ "@parcel/source-map": "^2.1.1",
27
+ "@parcel/utils": "2.8.1",
28
28
  "globals": "^13.2.0",
29
29
  "nullthrows": "^1.1.1"
30
30
  },
31
- "gitHead": "9e5d05586577e89991ccf90400f2c741dca11aa3"
31
+ "gitHead": "f8d3fc30ca5b33d8f8674525f2a741d662c5986a"
32
32
  }
@@ -39,16 +39,14 @@ export class DevPackager {
39
39
  async package(): Promise<{|contents: string, map: ?SourceMap|}> {
40
40
  // Load assets
41
41
  let queue = new PromiseQueue({maxConcurrent: 32});
42
- this.bundle.traverse(node => {
43
- if (node.type === 'asset') {
44
- queue.add(async () => {
45
- let [code, mapBuffer] = await Promise.all([
46
- node.value.getCode(),
47
- this.bundle.env.sourceMap && node.value.getMapBuffer(),
48
- ]);
49
- return {code, mapBuffer};
50
- });
51
- }
42
+ this.bundle.traverseAssets(asset => {
43
+ queue.add(async () => {
44
+ let [code, mapBuffer] = await Promise.all([
45
+ asset.getCode(),
46
+ this.bundle.env.sourceMap && asset.getMapBuffer(),
47
+ ]);
48
+ return {code, mapBuffer};
49
+ });
52
50
  });
53
51
 
54
52
  let results = await queue.run();
@@ -9,6 +9,7 @@ import type {
9
9
  } from '@parcel/types';
10
10
 
11
11
  import {
12
+ DefaultMap,
12
13
  PromiseQueue,
13
14
  relativeBundlePath,
14
15
  countLines,
@@ -472,59 +473,64 @@ export class ScopeHoistingPackager {
472
473
 
473
474
  // If we matched an import, replace with the source code for the dependency.
474
475
  if (d != null) {
475
- let dep = depMap.get(d);
476
- if (!dep) {
476
+ let deps = depMap.get(d);
477
+ if (!deps) {
477
478
  return m;
478
479
  }
479
480
 
480
- let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
481
- let skipped = this.bundleGraph.isDependencySkipped(dep);
482
- if (resolved && !skipped) {
483
- // Hoist variable declarations for the referenced parcelRequire dependencies
484
- // after the dependency is declared. This handles the case where the resulting asset
485
- // is wrapped, but the dependency in this asset is not marked as wrapped. This means
486
- // that it was imported/required at the top-level, so its side effects should run immediately.
487
- let [res, lines] = this.getHoistedParcelRequires(
488
- asset,
489
- dep,
490
- resolved,
491
- );
492
- let map;
493
- if (
494
- this.bundle.hasAsset(resolved) &&
495
- !this.seenAssets.has(resolved.id)
496
- ) {
497
- // If this asset is wrapped, we need to hoist the code for the dependency
498
- // outside our parcelRequire.register wrapper. This is safe because all
499
- // assets referenced by this asset will also be wrapped. Otherwise, inline the
500
- // asset content where the import statement was.
501
- if (shouldWrap) {
502
- depContent.push(this.visitAsset(resolved));
503
- } else {
504
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
505
- res = depCode + '\n' + res;
506
- lines += 1 + depLines;
507
- map = depMap;
481
+ let replacement = '';
482
+
483
+ // A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
484
+ // reexports.
485
+ for (let dep of deps) {
486
+ let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
487
+ let skipped = this.bundleGraph.isDependencySkipped(dep);
488
+ if (resolved && !skipped) {
489
+ // Hoist variable declarations for the referenced parcelRequire dependencies
490
+ // after the dependency is declared. This handles the case where the resulting asset
491
+ // is wrapped, but the dependency in this asset is not marked as wrapped. This means
492
+ // that it was imported/required at the top-level, so its side effects should run immediately.
493
+ let [res, lines] = this.getHoistedParcelRequires(
494
+ asset,
495
+ dep,
496
+ resolved,
497
+ );
498
+ let map;
499
+ if (
500
+ this.bundle.hasAsset(resolved) &&
501
+ !this.seenAssets.has(resolved.id)
502
+ ) {
503
+ // If this asset is wrapped, we need to hoist the code for the dependency
504
+ // outside our parcelRequire.register wrapper. This is safe because all
505
+ // assets referenced by this asset will also be wrapped. Otherwise, inline the
506
+ // asset content where the import statement was.
507
+ if (shouldWrap) {
508
+ depContent.push(this.visitAsset(resolved));
509
+ } else {
510
+ let [depCode, depMap, depLines] = this.visitAsset(resolved);
511
+ res = depCode + '\n' + res;
512
+ lines += 1 + depLines;
513
+ map = depMap;
514
+ }
508
515
  }
509
- }
510
516
 
511
- // Push this asset's source mappings down by the number of lines in the dependency
512
- // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
513
- if (sourceMap) {
514
- if (lines > 0) {
515
- sourceMap.offsetLines(lineCount + 1, lines);
516
- }
517
+ // Push this asset's source mappings down by the number of lines in the dependency
518
+ // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
519
+ if (sourceMap) {
520
+ if (lines > 0) {
521
+ sourceMap.offsetLines(lineCount + 1, lines);
522
+ }
517
523
 
518
- if (map) {
519
- sourceMap.addSourceMap(map, lineCount);
524
+ if (map) {
525
+ sourceMap.addSourceMap(map, lineCount);
526
+ }
520
527
  }
521
- }
522
528
 
523
- lineCount += lines;
524
- return res;
529
+ replacement += res;
530
+ lineCount += lines;
531
+ }
525
532
  }
526
-
527
- return '';
533
+ return replacement;
528
534
  }
529
535
 
530
536
  // If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
@@ -580,23 +586,24 @@ ${code}
580
586
  buildReplacements(
581
587
  asset: Asset,
582
588
  deps: Array<Dependency>,
583
- ): [Map<string, Dependency>, Map<string, string>] {
589
+ ): [Map<string, Array<Dependency>>, Map<string, string>] {
584
590
  let assetId = asset.meta.id;
585
591
  invariant(typeof assetId === 'string');
586
592
 
587
593
  // Build two maps: one of import specifiers, and one of imported symbols to replace.
588
594
  // These will be used to build a regex below.
589
- let depMap = new Map();
595
+ let depMap = new DefaultMap<string, Array<Dependency>>(() => []);
590
596
  let replacements = new Map();
591
597
  for (let dep of deps) {
592
598
  let specifierType =
593
599
  dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
594
- depMap.set(
595
- `${assetId}:${getSpecifier(dep)}${
596
- !dep.meta.placeholder ? specifierType : ''
597
- }`,
598
- dep,
599
- );
600
+ depMap
601
+ .get(
602
+ `${assetId}:${getSpecifier(dep)}${
603
+ !dep.meta.placeholder ? specifierType : ''
604
+ }`,
605
+ )
606
+ .push(dep);
600
607
 
601
608
  let asyncResolution = this.bundleGraph.resolveAsyncDependency(
602
609
  dep,
@@ -989,50 +996,9 @@ ${code}
989
996
  this.usedHelpers.add('$parcel$defineInteropFlag');
990
997
  }
991
998
 
992
- // Find the used exports of this module. This is based on the used symbols of
993
- // incoming dependencies rather than the asset's own used exports so that we include
994
- // re-exported symbols rather than only symbols declared in this asset.
995
- let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
996
- let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
997
- if (symbol === '*') {
998
- return false;
999
- }
1000
-
1001
- // If we need default interop, then all symbols are needed because the `default`
1002
- // symbol really maps to the whole namespace.
1003
- if (defaultInterop) {
1004
- return true;
1005
- }
1006
-
1007
- let unused = incomingDeps.every(d => {
1008
- let symbols = nullthrows(this.bundleGraph.getUsedSymbols(d));
1009
- return !symbols.has(symbol) && !symbols.has('*');
1010
- });
1011
- return !unused;
1012
- });
1013
-
1014
- if (usedExports.length > 0) {
1015
- // Insert $parcel$export calls for each of the used exports. This creates a getter/setter
1016
- // for the symbol so that when the value changes the object property also changes. This is
1017
- // required to simulate ESM live bindings. It's easier to do it this way rather than inserting
1018
- // additional assignments after each mutation of the original binding.
1019
- prepend += `\n${usedExports
1020
- .map(exp => {
1021
- let resolved = this.getSymbolResolution(asset, asset, exp);
1022
- let get = this.buildFunctionExpression([], resolved);
1023
- let set = asset.meta.hasCJSExports
1024
- ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`)
1025
- : '';
1026
- return `$parcel$export($${assetId}$exports, ${JSON.stringify(
1027
- exp,
1028
- )}, ${get}${set});`;
1029
- })
1030
- .join('\n')}\n`;
1031
- this.usedHelpers.add('$parcel$export');
1032
- prependLineCount += 1 + usedExports.length;
1033
- }
1034
-
1035
- // Find wildcard re-export dependencies, and make sure their exports are also included in ours.
999
+ // Find wildcard re-export dependencies, and make sure their exports are also included in
1000
+ // ours. Importantly, add them before the asset's own exports so that wildcard exports get
1001
+ // correctly overwritten by own exports of the same name.
1036
1002
  for (let dep of deps) {
1037
1003
  let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
1038
1004
  if (dep.isOptional || this.bundleGraph.isDependencySkipped(dep)) {
@@ -1098,6 +1064,49 @@ ${code}
1098
1064
  }
1099
1065
  }
1100
1066
  }
1067
+
1068
+ // Find the used exports of this module. This is based on the used symbols of
1069
+ // incoming dependencies rather than the asset's own used exports so that we include
1070
+ // re-exported symbols rather than only symbols declared in this asset.
1071
+ let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
1072
+ let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
1073
+ if (symbol === '*') {
1074
+ return false;
1075
+ }
1076
+
1077
+ // If we need default interop, then all symbols are needed because the `default`
1078
+ // symbol really maps to the whole namespace.
1079
+ if (defaultInterop) {
1080
+ return true;
1081
+ }
1082
+
1083
+ let unused = incomingDeps.every(d => {
1084
+ let symbols = nullthrows(this.bundleGraph.getUsedSymbols(d));
1085
+ return !symbols.has(symbol) && !symbols.has('*');
1086
+ });
1087
+ return !unused;
1088
+ });
1089
+
1090
+ if (usedExports.length > 0) {
1091
+ // Insert $parcel$export calls for each of the used exports. This creates a getter/setter
1092
+ // for the symbol so that when the value changes the object property also changes. This is
1093
+ // required to simulate ESM live bindings. It's easier to do it this way rather than inserting
1094
+ // additional assignments after each mutation of the original binding.
1095
+ prepend += `\n${usedExports
1096
+ .map(exp => {
1097
+ let resolved = this.getSymbolResolution(asset, asset, exp);
1098
+ let get = this.buildFunctionExpression([], resolved);
1099
+ let set = asset.meta.hasCJSExports
1100
+ ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`)
1101
+ : '';
1102
+ return `$parcel$export($${assetId}$exports, ${JSON.stringify(
1103
+ exp,
1104
+ )}, ${get}${set});`;
1105
+ })
1106
+ .join('\n')}\n`;
1107
+ this.usedHelpers.add('$parcel$export');
1108
+ prependLineCount += 1 + usedExports.length;
1109
+ }
1101
1110
  }
1102
1111
 
1103
1112
  return [prepend, prependLineCount, append];