@parcel/packager-js 2.0.0-dev.1424 → 2.0.0-dev.1426
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/lib/ESMOutputFormat.js +8 -1
- package/lib/ScopeHoistingPackager.js +105 -51
- package/lib/index.js +16 -17
- package/lib/utils.js +17 -0
- package/package.json +8 -8
- package/src/ESMOutputFormat.js +8 -1
- package/src/ScopeHoistingPackager.js +156 -59
- package/src/index.js +19 -14
- package/src/utils.js +17 -0
package/lib/ESMOutputFormat.js
CHANGED
|
@@ -4,6 +4,7 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.ESMOutputFormat = void 0;
|
|
7
|
+
var _utils = require("./utils");
|
|
7
8
|
class ESMOutputFormat {
|
|
8
9
|
constructor(packager) {
|
|
9
10
|
this.packager = packager;
|
|
@@ -22,6 +23,9 @@ class ESMOutputFormat {
|
|
|
22
23
|
namespaceSpecifier = `* as ${symbol}`;
|
|
23
24
|
} else {
|
|
24
25
|
let specifier = imported;
|
|
26
|
+
if (!(0, _utils.isValidIdentifier)(specifier)) {
|
|
27
|
+
specifier = JSON.stringify(specifier);
|
|
28
|
+
}
|
|
25
29
|
if (symbol !== imported) {
|
|
26
30
|
specifier += ` as ${symbol}`;
|
|
27
31
|
}
|
|
@@ -78,7 +82,10 @@ class ESMOutputFormat {
|
|
|
78
82
|
}
|
|
79
83
|
for (let as of exportAs) {
|
|
80
84
|
let specifier = local;
|
|
81
|
-
if (
|
|
85
|
+
if (as !== local) {
|
|
86
|
+
if (!(0, _utils.isValidIdentifier)(as)) {
|
|
87
|
+
as = JSON.stringify(as);
|
|
88
|
+
}
|
|
82
89
|
specifier += ` as ${as}`;
|
|
83
90
|
}
|
|
84
91
|
exportSpecifiers.push(specifier);
|
|
@@ -61,11 +61,6 @@ var _utils2 = require("./utils");
|
|
|
61
61
|
function _getRequireWildcardCache(e) { if ("function" != typeof WeakMap) return null; var r = new WeakMap(), t = new WeakMap(); return (_getRequireWildcardCache = function (e) { return e ? t : r; })(e); }
|
|
62
62
|
function _interopRequireWildcard(e, r) { if (!r && e && e.__esModule) return e; if (null === e || "object" != typeof e && "function" != typeof e) return { default: e }; var t = _getRequireWildcardCache(r); if (t && t.has(e)) return t.get(e); var n = { __proto__: null }, a = Object.defineProperty && Object.getOwnPropertyDescriptor; for (var u in e) if ("default" !== u && Object.prototype.hasOwnProperty.call(e, u)) { var i = a ? Object.getOwnPropertyDescriptor(e, u) : null; i && (i.get || i.set) ? Object.defineProperty(n, u, i) : n[u] = e[u]; } return n.default = e, t && t.set(e, n), n; }
|
|
63
63
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
64
|
-
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
|
|
65
|
-
const IDENTIFIER_RE = /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u;
|
|
66
|
-
const ID_START_RE = /^[$_\p{ID_Start}]/u;
|
|
67
|
-
const NON_ID_CONTINUE_RE = /[^$_\u200C\u200D\p{ID_Continue}]/gu;
|
|
68
|
-
|
|
69
64
|
// General regex used to replace imports with the resolved code, references with resolutions,
|
|
70
65
|
// and count the number of newlines in the file for source maps.
|
|
71
66
|
const REPLACEMENT_RE = /\n|import\s+"([0-9a-f]{16}:.+?)";|(?:\$[0-9a-f]{16}\$exports)|(?:\$[0-9a-f]{16}\$(?:import|importAsync|require)\$[0-9a-f]+(?:\$[0-9a-f]+)?)/g;
|
|
@@ -116,23 +111,10 @@ class ScopeHoistingPackager {
|
|
|
116
111
|
// of each bundle group pointing at the sibling bundles. These can be
|
|
117
112
|
// picked up by another bundler later at which point runtimes will be added.
|
|
118
113
|
if (this.bundle.env.isLibrary || this.bundle.env.outputFormat === 'commonjs') {
|
|
119
|
-
for (let b of this.bundleGraph.getReferencedBundles(this.bundle
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
this.externalAssets.add(entry);
|
|
124
|
-
let usedSymbols = this.bundleGraph.getUsedSymbols(entry) || new Set();
|
|
125
|
-
for (let s of usedSymbols) {
|
|
126
|
-
// If the referenced bundle is ESM, and we are importing '*', use 'default' instead.
|
|
127
|
-
// This matches the logic below in buildExportedSymbols.
|
|
128
|
-
let imported = s;
|
|
129
|
-
if (imported === '*' && b.env.outputFormat === 'esmodule') {
|
|
130
|
-
imported = 'default';
|
|
131
|
-
}
|
|
132
|
-
symbols.set(imported, this.getSymbolResolution(entry, entry, s));
|
|
133
|
-
}
|
|
134
|
-
}
|
|
135
|
-
this.externals.set((0, _utils().relativeBundlePath)(this.bundle, b), symbols);
|
|
114
|
+
for (let b of this.bundleGraph.getReferencedBundles(this.bundle, {
|
|
115
|
+
recursive: false
|
|
116
|
+
})) {
|
|
117
|
+
this.externals.set((0, _utils().relativeBundlePath)(this.bundle, b), new Map());
|
|
136
118
|
}
|
|
137
119
|
}
|
|
138
120
|
let res = '';
|
|
@@ -256,7 +238,7 @@ class ScopeHoistingPackager {
|
|
|
256
238
|
map
|
|
257
239
|
}];
|
|
258
240
|
});
|
|
259
|
-
if (asset.meta.shouldWrap || this.
|
|
241
|
+
if (asset.meta.shouldWrap || this.bundle.env.sourceType === 'script' || this.bundleGraph.isAssetReferenced(this.bundle, asset) || this.bundleGraph.getIncomingDependencies(asset).some(dep => dep.meta.shouldWrap && dep.specifierType !== 'url')) {
|
|
260
242
|
if (!asset.meta.isConstantModule) {
|
|
261
243
|
this.wrappedAssets.add(asset.id);
|
|
262
244
|
wrapped.push(asset);
|
|
@@ -282,13 +264,14 @@ class ScopeHoistingPackager {
|
|
|
282
264
|
return wrapped;
|
|
283
265
|
}
|
|
284
266
|
buildExportedSymbols() {
|
|
285
|
-
if (
|
|
267
|
+
if (!this.bundle.env.isLibrary || this.bundle.env.outputFormat !== 'esmodule') {
|
|
286
268
|
return;
|
|
287
269
|
}
|
|
288
270
|
|
|
289
271
|
// TODO: handle ESM exports of wrapped entry assets...
|
|
290
272
|
let entry = this.bundle.getMainEntry();
|
|
291
273
|
if (entry && !this.wrappedAssets.has(entry.id)) {
|
|
274
|
+
let hasNamespace = entry.symbols.hasExportSymbol('*');
|
|
292
275
|
for (let {
|
|
293
276
|
asset,
|
|
294
277
|
exportAs,
|
|
@@ -297,6 +280,12 @@ class ScopeHoistingPackager {
|
|
|
297
280
|
} of this.bundleGraph.getExportedSymbols(entry)) {
|
|
298
281
|
if (typeof symbol === 'string') {
|
|
299
282
|
var _this$exportedSymbols, _entry$symbols$get2;
|
|
283
|
+
// If the module has a namespace (e.g. commonjs), and this is not an entry, only export the namespace
|
|
284
|
+
// as default, without individual exports. This mirrors the importing logic in addExternal, avoiding
|
|
285
|
+
// extra unused exports and potential for non-identifier export names.
|
|
286
|
+
if (hasNamespace && this.isAsyncBundle && exportAs !== '*') {
|
|
287
|
+
continue;
|
|
288
|
+
}
|
|
300
289
|
let symbols = (_this$exportedSymbols = this.exportedSymbols.get(symbol === '*' ? (0, _nullthrows().default)((_entry$symbols$get2 = entry.symbols.get('*')) === null || _entry$symbols$get2 === void 0 ? void 0 : _entry$symbols$get2.local) : symbol)) === null || _this$exportedSymbols === void 0 ? void 0 : _this$exportedSymbols.exportAs;
|
|
301
290
|
if (!symbols) {
|
|
302
291
|
symbols = [];
|
|
@@ -331,8 +320,8 @@ class ScopeHoistingPackager {
|
|
|
331
320
|
}
|
|
332
321
|
}
|
|
333
322
|
getTopLevelName(name) {
|
|
334
|
-
name =
|
|
335
|
-
if (
|
|
323
|
+
name = (0, _utils2.makeValidIdentifier)(name);
|
|
324
|
+
if (this.globalNames.has(name)) {
|
|
336
325
|
name = '_' + name;
|
|
337
326
|
}
|
|
338
327
|
let count = this.topLevelNames.get(name);
|
|
@@ -344,7 +333,7 @@ class ScopeHoistingPackager {
|
|
|
344
333
|
return name + count;
|
|
345
334
|
}
|
|
346
335
|
getPropertyAccess(obj, property) {
|
|
347
|
-
if (
|
|
336
|
+
if ((0, _utils2.isValidIdentifier)(property)) {
|
|
348
337
|
return `${obj}.${property}`;
|
|
349
338
|
}
|
|
350
339
|
return `${obj}[${JSON.stringify(property)}]`;
|
|
@@ -401,7 +390,7 @@ class ScopeHoistingPackager {
|
|
|
401
390
|
code = code.replace('$parcel$filenameReplace', relPath);
|
|
402
391
|
}
|
|
403
392
|
let [depMap, replacements] = this.buildReplacements(asset, deps);
|
|
404
|
-
let [prepend, prependLines, append] = this.buildAssetPrelude(asset, deps);
|
|
393
|
+
let [prepend, prependLines, append] = this.buildAssetPrelude(asset, deps, replacements);
|
|
405
394
|
if (prependLines > 0) {
|
|
406
395
|
sourceMap === null || sourceMap === void 0 || sourceMap.offsetLines(1, prependLines);
|
|
407
396
|
code = prepend + code;
|
|
@@ -543,6 +532,16 @@ ${code}
|
|
|
543
532
|
if (!resolved) {
|
|
544
533
|
continue;
|
|
545
534
|
}
|
|
535
|
+
|
|
536
|
+
// Handle imports from other bundles in libraries.
|
|
537
|
+
if (this.bundle.env.isLibrary && !this.bundle.hasAsset(resolved)) {
|
|
538
|
+
let referencedBundle = this.bundleGraph.getReferencedBundle(dep, this.bundle);
|
|
539
|
+
if (referencedBundle && referencedBundle.getMainEntry() === resolved && referencedBundle.type === 'js' && !this.bundleGraph.isAssetReferenced(referencedBundle, resolved)) {
|
|
540
|
+
this.addExternal(dep, replacements, referencedBundle);
|
|
541
|
+
this.externalAssets.add(resolved);
|
|
542
|
+
continue;
|
|
543
|
+
}
|
|
544
|
+
}
|
|
546
545
|
for (let [imported, {
|
|
547
546
|
local
|
|
548
547
|
}] of dep.symbols) {
|
|
@@ -575,7 +574,7 @@ ${code}
|
|
|
575
574
|
}
|
|
576
575
|
return [depMap, replacements];
|
|
577
576
|
}
|
|
578
|
-
addExternal(dep, replacements) {
|
|
577
|
+
addExternal(dep, replacements, referencedBundle) {
|
|
579
578
|
if (this.bundle.env.outputFormat === 'global') {
|
|
580
579
|
throw new (_diagnostic().default)({
|
|
581
580
|
diagnostic: {
|
|
@@ -587,12 +586,16 @@ ${code}
|
|
|
587
586
|
}
|
|
588
587
|
});
|
|
589
588
|
}
|
|
589
|
+
let specifier = dep.specifier;
|
|
590
|
+
if (referencedBundle) {
|
|
591
|
+
specifier = (0, _utils().relativeBundlePath)(this.bundle, referencedBundle);
|
|
592
|
+
}
|
|
590
593
|
|
|
591
594
|
// Map of DependencySpecifier -> Map<ExportedSymbol, Identifier>>
|
|
592
|
-
let external = this.externals.get(
|
|
595
|
+
let external = this.externals.get(specifier);
|
|
593
596
|
if (!external) {
|
|
594
597
|
external = new Map();
|
|
595
|
-
this.externals.set(
|
|
598
|
+
this.externals.set(specifier, external);
|
|
596
599
|
}
|
|
597
600
|
for (let [imported, {
|
|
598
601
|
local
|
|
@@ -609,7 +612,13 @@ ${code}
|
|
|
609
612
|
if (this.bundle.env.outputFormat === 'commonjs') {
|
|
610
613
|
renamed = external.get('*');
|
|
611
614
|
if (!renamed) {
|
|
612
|
-
|
|
615
|
+
if (referencedBundle) {
|
|
616
|
+
var _entry$symbols$get$lo, _entry$symbols$get3;
|
|
617
|
+
let entry = (0, _nullthrows().default)(referencedBundle.getMainEntry());
|
|
618
|
+
renamed = (_entry$symbols$get$lo = (_entry$symbols$get3 = entry.symbols.get('*')) === null || _entry$symbols$get3 === void 0 ? void 0 : _entry$symbols$get3.local) !== null && _entry$symbols$get$lo !== void 0 ? _entry$symbols$get$lo : `$${String(entry.meta.id)}$exports`;
|
|
619
|
+
} else {
|
|
620
|
+
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${specifier}`);
|
|
621
|
+
}
|
|
613
622
|
external.set('*', renamed);
|
|
614
623
|
}
|
|
615
624
|
if (local !== '*' && replacements) {
|
|
@@ -625,19 +634,55 @@ ${code}
|
|
|
625
634
|
replacements.set(local, replacement);
|
|
626
635
|
}
|
|
627
636
|
} else {
|
|
637
|
+
let property;
|
|
638
|
+
if (referencedBundle) {
|
|
639
|
+
let entry = (0, _nullthrows().default)(referencedBundle.getMainEntry());
|
|
640
|
+
if (entry.symbols.hasExportSymbol('*')) {
|
|
641
|
+
// If importing * and the referenced module has a * export (e.g. CJS), use default instead.
|
|
642
|
+
// This mirrors the logic in buildExportedSymbols.
|
|
643
|
+
property = imported;
|
|
644
|
+
imported = (referencedBundle === null || referencedBundle === void 0 ? void 0 : referencedBundle.env.outputFormat) === 'esmodule' ? 'default' : '*';
|
|
645
|
+
} else {
|
|
646
|
+
if (imported === '*') {
|
|
647
|
+
let exportedSymbols = this.bundleGraph.getExportedSymbols(entry);
|
|
648
|
+
if (local === '*') {
|
|
649
|
+
// Re-export all symbols.
|
|
650
|
+
for (let exported of exportedSymbols) {
|
|
651
|
+
if (exported.symbol) {
|
|
652
|
+
external.set(exported.exportSymbol, exported.symbol);
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
continue;
|
|
656
|
+
}
|
|
657
|
+
}
|
|
658
|
+
renamed = this.bundleGraph.getSymbolResolution(entry, imported, this.bundle).symbol;
|
|
659
|
+
}
|
|
660
|
+
}
|
|
661
|
+
|
|
628
662
|
// Rename the specifier so that multiple local imports of the same imported specifier
|
|
629
663
|
// are deduplicated. We have to prefix the imported name with the bundle id so that
|
|
630
664
|
// local variables do not shadow it.
|
|
631
|
-
if (
|
|
632
|
-
|
|
633
|
-
|
|
634
|
-
|
|
635
|
-
|
|
636
|
-
|
|
665
|
+
if (!renamed) {
|
|
666
|
+
if (this.exportedSymbols.has(local)) {
|
|
667
|
+
renamed = local;
|
|
668
|
+
} else if (imported === 'default' || imported === '*') {
|
|
669
|
+
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${specifier}`);
|
|
670
|
+
} else {
|
|
671
|
+
renamed = this.getTopLevelName(`$${this.bundle.publicId}$${imported}`);
|
|
672
|
+
}
|
|
637
673
|
}
|
|
638
674
|
external.set(imported, renamed);
|
|
639
675
|
if (local !== '*' && replacements) {
|
|
640
|
-
|
|
676
|
+
let replacement = renamed;
|
|
677
|
+
if (property === '*') {
|
|
678
|
+
replacement = renamed;
|
|
679
|
+
} else if (property === 'default') {
|
|
680
|
+
replacement = `($parcel$interopDefault(${renamed}))`;
|
|
681
|
+
this.usedHelpers.add('$parcel$interopDefault');
|
|
682
|
+
} else if (property) {
|
|
683
|
+
replacement = this.getPropertyAccess(renamed, property);
|
|
684
|
+
}
|
|
685
|
+
replacements.set(local, replacement);
|
|
641
686
|
}
|
|
642
687
|
}
|
|
643
688
|
}
|
|
@@ -649,8 +694,7 @@ ${code}
|
|
|
649
694
|
}
|
|
650
695
|
return !this.bundle.hasAsset(resolved) && !this.externalAssets.has(resolved) || this.wrappedAssets.has(resolved.id) && resolved !== parentAsset;
|
|
651
696
|
}
|
|
652
|
-
getSymbolResolution(parentAsset, resolved, imported, dep) {
|
|
653
|
-
var _resolvedAsset$symbol;
|
|
697
|
+
getSymbolResolution(parentAsset, resolved, imported, dep, replacements) {
|
|
654
698
|
let {
|
|
655
699
|
asset: resolvedAsset,
|
|
656
700
|
exportSymbol,
|
|
@@ -696,9 +740,17 @@ ${code}
|
|
|
696
740
|
// namespace export symbol.
|
|
697
741
|
let assetId = resolvedAsset.meta.id;
|
|
698
742
|
(0, _assert().default)(typeof assetId === 'string');
|
|
699
|
-
let obj
|
|
700
|
-
|
|
701
|
-
|
|
743
|
+
let obj;
|
|
744
|
+
if (isWrapped && (!dep || dep !== null && dep !== void 0 && dep.meta.shouldWrap)) {
|
|
745
|
+
// Wrap in extra parenthesis to not change semantics, e.g.`new (parcelRequire("..."))()`.
|
|
746
|
+
obj = `(parcelRequire(${JSON.stringify(publicId)}))`;
|
|
747
|
+
} else if (isWrapped && dep) {
|
|
748
|
+
obj = `$${publicId}`;
|
|
749
|
+
} else {
|
|
750
|
+
var _resolvedAsset$symbol;
|
|
751
|
+
obj = ((_resolvedAsset$symbol = resolvedAsset.symbols.get('*')) === null || _resolvedAsset$symbol === void 0 ? void 0 : _resolvedAsset$symbol.local) || `$${assetId}$exports`;
|
|
752
|
+
obj = (replacements === null || replacements === void 0 ? void 0 : replacements.get(obj)) || obj;
|
|
753
|
+
}
|
|
702
754
|
if (imported === '*' || exportSymbol === '*' || isDefaultInterop) {
|
|
703
755
|
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
|
|
704
756
|
if (parentAsset === resolvedAsset && this.wrappedAssets.has(resolvedAsset.id)) {
|
|
@@ -722,7 +774,7 @@ ${code}
|
|
|
722
774
|
} else if (!symbol) {
|
|
723
775
|
(0, _assert().default)(false, 'Asset was skipped or not found.');
|
|
724
776
|
} else {
|
|
725
|
-
return symbol;
|
|
777
|
+
return (replacements === null || replacements === void 0 ? void 0 : replacements.get(symbol)) || symbol;
|
|
726
778
|
}
|
|
727
779
|
}
|
|
728
780
|
getHoistedParcelRequires(parentAsset, dep, resolved) {
|
|
@@ -749,7 +801,7 @@ ${code}
|
|
|
749
801
|
}
|
|
750
802
|
return [res, lineCount];
|
|
751
803
|
}
|
|
752
|
-
buildAssetPrelude(asset, deps) {
|
|
804
|
+
buildAssetPrelude(asset, deps, replacements) {
|
|
753
805
|
let prepend = '';
|
|
754
806
|
let prependLineCount = 0;
|
|
755
807
|
let append = '';
|
|
@@ -767,13 +819,15 @@ ${code}
|
|
|
767
819
|
// The one case where this isn't true is in ESM library entries, where the only
|
|
768
820
|
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
769
821
|
// instead of the namespace object.
|
|
770
|
-
usedSymbols.has('*') && (this.bundle.env.outputFormat !== 'esmodule' || !this.bundle.env.isLibrary || asset !== this.bundle.getMainEntry() || this.bundleGraph.getIncomingDependencies(asset).some(dep => !dep.isEntry && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'))) ||
|
|
822
|
+
usedSymbols.has('*') && (this.bundle.env.outputFormat !== 'esmodule' || !this.bundle.env.isLibrary || asset !== this.bundle.getMainEntry() || this.bundleGraph.getIncomingDependencies(asset).some(dep => !dep.isEntry && this.bundle.hasDependency(dep) && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'))) ||
|
|
771
823
|
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
772
824
|
// we fallback on the namespace object.
|
|
773
825
|
asset.symbols.hasExportSymbol('*') && [...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s)) ||
|
|
774
826
|
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
775
827
|
// include the namespace object for the default export.
|
|
776
|
-
this.exportedSymbols.has(`$${assetId}$exports`)
|
|
828
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
829
|
+
// CommonJS library bundle entries always need a namespace.
|
|
830
|
+
this.bundle.env.isLibrary && this.bundle.env.outputFormat === 'commonjs' && asset === this.bundle.getMainEntry();
|
|
777
831
|
|
|
778
832
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
779
833
|
// or we need default interop, then we need to synthesize a namespace object for
|
|
@@ -824,7 +878,7 @@ ${code}
|
|
|
824
878
|
if (isWrapped || resolved.meta.staticExports === false || (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(resolved)).has('*') ||
|
|
825
879
|
// an empty asset
|
|
826
880
|
!resolved.meta.hasCJSExports && resolved.symbols.hasExportSymbol('*')) {
|
|
827
|
-
let obj = this.getSymbolResolution(asset, resolved, '*', dep);
|
|
881
|
+
let obj = this.getSymbolResolution(asset, resolved, '*', dep, replacements);
|
|
828
882
|
append += `$parcel$exportWildcard($${assetId}$exports, ${obj});\n`;
|
|
829
883
|
this.usedHelpers.add('$parcel$exportWildcard');
|
|
830
884
|
} else {
|
|
@@ -834,7 +888,7 @@ ${code}
|
|
|
834
888
|
symbol === '__esModule') {
|
|
835
889
|
continue;
|
|
836
890
|
}
|
|
837
|
-
let resolvedSymbol = this.getSymbolResolution(asset, resolved, symbol);
|
|
891
|
+
let resolvedSymbol = this.getSymbolResolution(asset, resolved, symbol, undefined, replacements);
|
|
838
892
|
let get = this.buildFunctionExpression([], resolvedSymbol);
|
|
839
893
|
let set = asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolvedSymbol} = v`) : '';
|
|
840
894
|
prepend += `$parcel$export($${assetId}$exports, ${JSON.stringify(symbol)}, ${get}${set});\n`;
|
|
@@ -873,7 +927,7 @@ ${code}
|
|
|
873
927
|
// additional assignments after each mutation of the original binding.
|
|
874
928
|
prepend += `\n${usedExports.map(exp => {
|
|
875
929
|
var _asset$symbols$get2;
|
|
876
|
-
let resolved = this.getSymbolResolution(asset, asset, exp);
|
|
930
|
+
let resolved = this.getSymbolResolution(asset, asset, exp, undefined, replacements);
|
|
877
931
|
let get = this.buildFunctionExpression([], resolved);
|
|
878
932
|
let isEsmExport = !!((_asset$symbols$get2 = asset.symbols.get(exp)) !== null && _asset$symbols$get2 !== void 0 && (_asset$symbols$get2 = _asset$symbols$get2.meta) !== null && _asset$symbols$get2 !== void 0 && _asset$symbols$get2.isEsm);
|
|
879
933
|
let set = !isEsmExport && asset.meta.hasCJSExports ? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`) : '';
|
package/lib/index.js
CHANGED
|
@@ -32,13 +32,6 @@ function _rust() {
|
|
|
32
32
|
};
|
|
33
33
|
return data;
|
|
34
34
|
}
|
|
35
|
-
function _path() {
|
|
36
|
-
const data = _interopRequireDefault(require("path"));
|
|
37
|
-
_path = function () {
|
|
38
|
-
return data;
|
|
39
|
-
};
|
|
40
|
-
return data;
|
|
41
|
-
}
|
|
42
35
|
function _nullthrows() {
|
|
43
36
|
const data = _interopRequireDefault(require("nullthrows"));
|
|
44
37
|
_nullthrows = function () {
|
|
@@ -63,23 +56,29 @@ var _default = exports.default = new (_plugin().Packager)({
|
|
|
63
56
|
config,
|
|
64
57
|
options
|
|
65
58
|
}) {
|
|
66
|
-
var
|
|
67
|
-
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
68
|
-
// This allows multiple parcel builds to coexist on the same page.
|
|
69
|
-
let pkg = await config.getConfigFrom(_path().default.join(options.projectRoot, 'index'), ['package.json']);
|
|
59
|
+
var _packageName$contents, _packageName$contents2, _conf$contents;
|
|
70
60
|
let packageKey = '@parcel/packager-js';
|
|
71
|
-
|
|
61
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
62
|
+
packageKey
|
|
63
|
+
});
|
|
64
|
+
if (conf !== null && conf !== void 0 && conf.contents) {
|
|
72
65
|
_utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
|
|
73
|
-
data:
|
|
74
|
-
source: await options.inputFS.readFile(
|
|
75
|
-
filePath:
|
|
66
|
+
data: conf === null || conf === void 0 ? void 0 : conf.contents,
|
|
67
|
+
source: await options.inputFS.readFile(conf.filePath, 'utf8'),
|
|
68
|
+
filePath: conf.filePath,
|
|
76
69
|
prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)(packageKey)}`
|
|
77
70
|
}, packageKey, `Invalid config for ${packageKey}`);
|
|
78
71
|
}
|
|
79
|
-
|
|
72
|
+
|
|
73
|
+
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
74
|
+
// This allows multiple parcel builds to coexist on the same page.
|
|
75
|
+
let packageName = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
76
|
+
packageKey: 'name'
|
|
77
|
+
});
|
|
78
|
+
let name = (_packageName$contents = packageName === null || packageName === void 0 || (_packageName$contents2 = packageName.contents) === null || _packageName$contents2 === void 0 ? void 0 : _packageName$contents2.name) !== null && _packageName$contents !== void 0 ? _packageName$contents : '';
|
|
80
79
|
return {
|
|
81
80
|
parcelRequireName: 'parcelRequire' + (0, _rust().hashString)(name).slice(-4),
|
|
82
|
-
unstable_asyncBundleRuntime: Boolean(
|
|
81
|
+
unstable_asyncBundleRuntime: Boolean(conf === null || conf === void 0 || (_conf$contents = conf.contents) === null || _conf$contents === void 0 ? void 0 : _conf$contents.unstable_asyncBundleRuntime)
|
|
83
82
|
};
|
|
84
83
|
},
|
|
85
84
|
async package({
|
package/lib/utils.js
CHANGED
|
@@ -4,6 +4,8 @@ Object.defineProperty(exports, "__esModule", {
|
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
6
|
exports.getSpecifier = getSpecifier;
|
|
7
|
+
exports.isValidIdentifier = isValidIdentifier;
|
|
8
|
+
exports.makeValidIdentifier = makeValidIdentifier;
|
|
7
9
|
exports.replaceScriptDependencies = replaceScriptDependencies;
|
|
8
10
|
function _nullthrows() {
|
|
9
11
|
const data = _interopRequireDefault(require("nullthrows"));
|
|
@@ -48,4 +50,19 @@ function getSpecifier(dep) {
|
|
|
48
50
|
return dep.meta.placeholder;
|
|
49
51
|
}
|
|
50
52
|
return dep.specifier;
|
|
53
|
+
}
|
|
54
|
+
|
|
55
|
+
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
|
|
56
|
+
const IDENTIFIER_RE = /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u;
|
|
57
|
+
const ID_START_RE = /^[$_\p{ID_Start}]/u;
|
|
58
|
+
const NON_ID_CONTINUE_RE = /[^$_\u200C\u200D\p{ID_Continue}]/gu;
|
|
59
|
+
function isValidIdentifier(id) {
|
|
60
|
+
return IDENTIFIER_RE.test(id);
|
|
61
|
+
}
|
|
62
|
+
function makeValidIdentifier(name) {
|
|
63
|
+
name = name.replace(NON_ID_CONTINUE_RE, '');
|
|
64
|
+
if (!ID_START_RE.test(name)) {
|
|
65
|
+
name = '_' + name;
|
|
66
|
+
}
|
|
67
|
+
return name;
|
|
51
68
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/packager-js",
|
|
3
|
-
"version": "2.0.0-dev.
|
|
3
|
+
"version": "2.0.0-dev.1426+2369415b7",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"source": "src/index.js",
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">= 12.0.0",
|
|
20
|
-
"parcel": "^2.0.0-dev.
|
|
20
|
+
"parcel": "^2.0.0-dev.1424+2369415b7"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@parcel/diagnostic": "2.0.0-dev.
|
|
24
|
-
"@parcel/plugin": "2.0.0-dev.
|
|
25
|
-
"@parcel/rust": "2.12.1-dev.
|
|
23
|
+
"@parcel/diagnostic": "2.0.0-dev.1426+2369415b7",
|
|
24
|
+
"@parcel/plugin": "2.0.0-dev.1426+2369415b7",
|
|
25
|
+
"@parcel/rust": "2.12.1-dev.3263+2369415b7",
|
|
26
26
|
"@parcel/source-map": "^2.1.1",
|
|
27
|
-
"@parcel/types": "2.0.0-dev.
|
|
28
|
-
"@parcel/utils": "2.0.0-dev.
|
|
27
|
+
"@parcel/types": "2.0.0-dev.1426+2369415b7",
|
|
28
|
+
"@parcel/utils": "2.0.0-dev.1426+2369415b7",
|
|
29
29
|
"globals": "^13.2.0",
|
|
30
30
|
"nullthrows": "^1.1.1"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "2369415b703a85196b2e76d18cf748bad349932b"
|
|
33
33
|
}
|
package/src/ESMOutputFormat.js
CHANGED
|
@@ -3,6 +3,7 @@ import type {
|
|
|
3
3
|
ScopeHoistingPackager,
|
|
4
4
|
OutputFormat,
|
|
5
5
|
} from './ScopeHoistingPackager';
|
|
6
|
+
import {isValidIdentifier} from './utils';
|
|
6
7
|
|
|
7
8
|
export class ESMOutputFormat implements OutputFormat {
|
|
8
9
|
packager: ScopeHoistingPackager;
|
|
@@ -25,6 +26,9 @@ export class ESMOutputFormat implements OutputFormat {
|
|
|
25
26
|
namespaceSpecifier = `* as ${symbol}`;
|
|
26
27
|
} else {
|
|
27
28
|
let specifier = imported;
|
|
29
|
+
if (!isValidIdentifier(specifier)) {
|
|
30
|
+
specifier = JSON.stringify(specifier);
|
|
31
|
+
}
|
|
28
32
|
if (symbol !== imported) {
|
|
29
33
|
specifier += ` as ${symbol}`;
|
|
30
34
|
}
|
|
@@ -93,7 +97,10 @@ export class ESMOutputFormat implements OutputFormat {
|
|
|
93
97
|
|
|
94
98
|
for (let as of exportAs) {
|
|
95
99
|
let specifier = local;
|
|
96
|
-
if (
|
|
100
|
+
if (as !== local) {
|
|
101
|
+
if (!isValidIdentifier(as)) {
|
|
102
|
+
as = JSON.stringify(as);
|
|
103
|
+
}
|
|
97
104
|
specifier += ` as ${as}`;
|
|
98
105
|
}
|
|
99
106
|
|
|
@@ -28,12 +28,12 @@ import {ESMOutputFormat} from './ESMOutputFormat';
|
|
|
28
28
|
import {CJSOutputFormat} from './CJSOutputFormat';
|
|
29
29
|
import {GlobalOutputFormat} from './GlobalOutputFormat';
|
|
30
30
|
import {prelude, helpers, bundleQueuePrelude, fnExpr} from './helpers';
|
|
31
|
-
import {
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
31
|
+
import {
|
|
32
|
+
replaceScriptDependencies,
|
|
33
|
+
getSpecifier,
|
|
34
|
+
isValidIdentifier,
|
|
35
|
+
makeValidIdentifier,
|
|
36
|
+
} from './utils';
|
|
37
37
|
|
|
38
38
|
// General regex used to replace imports with the resolved code, references with resolutions,
|
|
39
39
|
// and count the number of newlines in the file for source maps.
|
|
@@ -134,25 +134,10 @@ export class ScopeHoistingPackager {
|
|
|
134
134
|
this.bundle.env.isLibrary ||
|
|
135
135
|
this.bundle.env.outputFormat === 'commonjs'
|
|
136
136
|
) {
|
|
137
|
-
for (let b of this.bundleGraph.getReferencedBundles(this.bundle
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
this.externalAssets.add(entry);
|
|
142
|
-
|
|
143
|
-
let usedSymbols = this.bundleGraph.getUsedSymbols(entry) || new Set();
|
|
144
|
-
for (let s of usedSymbols) {
|
|
145
|
-
// If the referenced bundle is ESM, and we are importing '*', use 'default' instead.
|
|
146
|
-
// This matches the logic below in buildExportedSymbols.
|
|
147
|
-
let imported = s;
|
|
148
|
-
if (imported === '*' && b.env.outputFormat === 'esmodule') {
|
|
149
|
-
imported = 'default';
|
|
150
|
-
}
|
|
151
|
-
symbols.set(imported, this.getSymbolResolution(entry, entry, s));
|
|
152
|
-
}
|
|
153
|
-
}
|
|
154
|
-
|
|
155
|
-
this.externals.set(relativeBundlePath(this.bundle, b), symbols);
|
|
137
|
+
for (let b of this.bundleGraph.getReferencedBundles(this.bundle, {
|
|
138
|
+
recursive: false,
|
|
139
|
+
})) {
|
|
140
|
+
this.externals.set(relativeBundlePath(this.bundle, b), new Map());
|
|
156
141
|
}
|
|
157
142
|
}
|
|
158
143
|
|
|
@@ -324,7 +309,6 @@ export class ScopeHoistingPackager {
|
|
|
324
309
|
|
|
325
310
|
if (
|
|
326
311
|
asset.meta.shouldWrap ||
|
|
327
|
-
this.isAsyncBundle ||
|
|
328
312
|
this.bundle.env.sourceType === 'script' ||
|
|
329
313
|
this.bundleGraph.isAssetReferenced(this.bundle, asset) ||
|
|
330
314
|
this.bundleGraph
|
|
@@ -361,7 +345,6 @@ export class ScopeHoistingPackager {
|
|
|
361
345
|
|
|
362
346
|
buildExportedSymbols() {
|
|
363
347
|
if (
|
|
364
|
-
this.isAsyncBundle ||
|
|
365
348
|
!this.bundle.env.isLibrary ||
|
|
366
349
|
this.bundle.env.outputFormat !== 'esmodule'
|
|
367
350
|
) {
|
|
@@ -371,6 +354,8 @@ export class ScopeHoistingPackager {
|
|
|
371
354
|
// TODO: handle ESM exports of wrapped entry assets...
|
|
372
355
|
let entry = this.bundle.getMainEntry();
|
|
373
356
|
if (entry && !this.wrappedAssets.has(entry.id)) {
|
|
357
|
+
let hasNamespace = entry.symbols.hasExportSymbol('*');
|
|
358
|
+
|
|
374
359
|
for (let {
|
|
375
360
|
asset,
|
|
376
361
|
exportAs,
|
|
@@ -378,6 +363,13 @@ export class ScopeHoistingPackager {
|
|
|
378
363
|
exportSymbol,
|
|
379
364
|
} of this.bundleGraph.getExportedSymbols(entry)) {
|
|
380
365
|
if (typeof symbol === 'string') {
|
|
366
|
+
// If the module has a namespace (e.g. commonjs), and this is not an entry, only export the namespace
|
|
367
|
+
// as default, without individual exports. This mirrors the importing logic in addExternal, avoiding
|
|
368
|
+
// extra unused exports and potential for non-identifier export names.
|
|
369
|
+
if (hasNamespace && this.isAsyncBundle && exportAs !== '*') {
|
|
370
|
+
continue;
|
|
371
|
+
}
|
|
372
|
+
|
|
381
373
|
let symbols = this.exportedSymbols.get(
|
|
382
374
|
symbol === '*' ? nullthrows(entry.symbols.get('*')?.local) : symbol,
|
|
383
375
|
)?.exportAs;
|
|
@@ -418,8 +410,8 @@ export class ScopeHoistingPackager {
|
|
|
418
410
|
}
|
|
419
411
|
|
|
420
412
|
getTopLevelName(name: string): string {
|
|
421
|
-
name = name
|
|
422
|
-
if (
|
|
413
|
+
name = makeValidIdentifier(name);
|
|
414
|
+
if (this.globalNames.has(name)) {
|
|
423
415
|
name = '_' + name;
|
|
424
416
|
}
|
|
425
417
|
|
|
@@ -434,7 +426,7 @@ export class ScopeHoistingPackager {
|
|
|
434
426
|
}
|
|
435
427
|
|
|
436
428
|
getPropertyAccess(obj: string, property: string): string {
|
|
437
|
-
if (
|
|
429
|
+
if (isValidIdentifier(property)) {
|
|
438
430
|
return `${obj}.${property}`;
|
|
439
431
|
}
|
|
440
432
|
|
|
@@ -511,7 +503,11 @@ export class ScopeHoistingPackager {
|
|
|
511
503
|
}
|
|
512
504
|
|
|
513
505
|
let [depMap, replacements] = this.buildReplacements(asset, deps);
|
|
514
|
-
let [prepend, prependLines, append] = this.buildAssetPrelude(
|
|
506
|
+
let [prepend, prependLines, append] = this.buildAssetPrelude(
|
|
507
|
+
asset,
|
|
508
|
+
deps,
|
|
509
|
+
replacements,
|
|
510
|
+
);
|
|
515
511
|
if (prependLines > 0) {
|
|
516
512
|
sourceMap?.offsetLines(1, prependLines);
|
|
517
513
|
code = prepend + code;
|
|
@@ -703,6 +699,24 @@ ${code}
|
|
|
703
699
|
continue;
|
|
704
700
|
}
|
|
705
701
|
|
|
702
|
+
// Handle imports from other bundles in libraries.
|
|
703
|
+
if (this.bundle.env.isLibrary && !this.bundle.hasAsset(resolved)) {
|
|
704
|
+
let referencedBundle = this.bundleGraph.getReferencedBundle(
|
|
705
|
+
dep,
|
|
706
|
+
this.bundle,
|
|
707
|
+
);
|
|
708
|
+
if (
|
|
709
|
+
referencedBundle &&
|
|
710
|
+
referencedBundle.getMainEntry() === resolved &&
|
|
711
|
+
referencedBundle.type === 'js' &&
|
|
712
|
+
!this.bundleGraph.isAssetReferenced(referencedBundle, resolved)
|
|
713
|
+
) {
|
|
714
|
+
this.addExternal(dep, replacements, referencedBundle);
|
|
715
|
+
this.externalAssets.add(resolved);
|
|
716
|
+
continue;
|
|
717
|
+
}
|
|
718
|
+
}
|
|
719
|
+
|
|
706
720
|
for (let [imported, {local}] of dep.symbols) {
|
|
707
721
|
if (local === '*') {
|
|
708
722
|
continue;
|
|
@@ -748,7 +762,11 @@ ${code}
|
|
|
748
762
|
return [depMap, replacements];
|
|
749
763
|
}
|
|
750
764
|
|
|
751
|
-
addExternal(
|
|
765
|
+
addExternal(
|
|
766
|
+
dep: Dependency,
|
|
767
|
+
replacements?: Map<string, string>,
|
|
768
|
+
referencedBundle?: NamedBundle,
|
|
769
|
+
) {
|
|
752
770
|
if (this.bundle.env.outputFormat === 'global') {
|
|
753
771
|
throw new ThrowableDiagnostic({
|
|
754
772
|
diagnostic: {
|
|
@@ -766,11 +784,16 @@ ${code}
|
|
|
766
784
|
});
|
|
767
785
|
}
|
|
768
786
|
|
|
787
|
+
let specifier = dep.specifier;
|
|
788
|
+
if (referencedBundle) {
|
|
789
|
+
specifier = relativeBundlePath(this.bundle, referencedBundle);
|
|
790
|
+
}
|
|
791
|
+
|
|
769
792
|
// Map of DependencySpecifier -> Map<ExportedSymbol, Identifier>>
|
|
770
|
-
let external = this.externals.get(
|
|
793
|
+
let external = this.externals.get(specifier);
|
|
771
794
|
if (!external) {
|
|
772
795
|
external = new Map();
|
|
773
|
-
this.externals.set(
|
|
796
|
+
this.externals.set(specifier, external);
|
|
774
797
|
}
|
|
775
798
|
|
|
776
799
|
for (let [imported, {local}] of dep.symbols) {
|
|
@@ -786,9 +809,16 @@ ${code}
|
|
|
786
809
|
if (this.bundle.env.outputFormat === 'commonjs') {
|
|
787
810
|
renamed = external.get('*');
|
|
788
811
|
if (!renamed) {
|
|
789
|
-
|
|
790
|
-
|
|
791
|
-
|
|
812
|
+
if (referencedBundle) {
|
|
813
|
+
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
814
|
+
renamed =
|
|
815
|
+
entry.symbols.get('*')?.local ??
|
|
816
|
+
`$${String(entry.meta.id)}$exports`;
|
|
817
|
+
} else {
|
|
818
|
+
renamed = this.getTopLevelName(
|
|
819
|
+
`$${this.bundle.publicId}$${specifier}`,
|
|
820
|
+
);
|
|
821
|
+
}
|
|
792
822
|
|
|
793
823
|
external.set('*', renamed);
|
|
794
824
|
}
|
|
@@ -807,24 +837,67 @@ ${code}
|
|
|
807
837
|
replacements.set(local, replacement);
|
|
808
838
|
}
|
|
809
839
|
} else {
|
|
840
|
+
let property;
|
|
841
|
+
if (referencedBundle) {
|
|
842
|
+
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
843
|
+
if (entry.symbols.hasExportSymbol('*')) {
|
|
844
|
+
// If importing * and the referenced module has a * export (e.g. CJS), use default instead.
|
|
845
|
+
// This mirrors the logic in buildExportedSymbols.
|
|
846
|
+
property = imported;
|
|
847
|
+
imported =
|
|
848
|
+
referencedBundle?.env.outputFormat === 'esmodule'
|
|
849
|
+
? 'default'
|
|
850
|
+
: '*';
|
|
851
|
+
} else {
|
|
852
|
+
if (imported === '*') {
|
|
853
|
+
let exportedSymbols = this.bundleGraph.getExportedSymbols(entry);
|
|
854
|
+
if (local === '*') {
|
|
855
|
+
// Re-export all symbols.
|
|
856
|
+
for (let exported of exportedSymbols) {
|
|
857
|
+
if (exported.symbol) {
|
|
858
|
+
external.set(exported.exportSymbol, exported.symbol);
|
|
859
|
+
}
|
|
860
|
+
}
|
|
861
|
+
continue;
|
|
862
|
+
}
|
|
863
|
+
}
|
|
864
|
+
renamed = this.bundleGraph.getSymbolResolution(
|
|
865
|
+
entry,
|
|
866
|
+
imported,
|
|
867
|
+
this.bundle,
|
|
868
|
+
).symbol;
|
|
869
|
+
}
|
|
870
|
+
}
|
|
871
|
+
|
|
810
872
|
// Rename the specifier so that multiple local imports of the same imported specifier
|
|
811
873
|
// are deduplicated. We have to prefix the imported name with the bundle id so that
|
|
812
874
|
// local variables do not shadow it.
|
|
813
|
-
if (
|
|
814
|
-
|
|
815
|
-
|
|
816
|
-
|
|
817
|
-
|
|
818
|
-
|
|
819
|
-
|
|
820
|
-
|
|
821
|
-
|
|
822
|
-
|
|
875
|
+
if (!renamed) {
|
|
876
|
+
if (this.exportedSymbols.has(local)) {
|
|
877
|
+
renamed = local;
|
|
878
|
+
} else if (imported === 'default' || imported === '*') {
|
|
879
|
+
renamed = this.getTopLevelName(
|
|
880
|
+
`$${this.bundle.publicId}$${specifier}`,
|
|
881
|
+
);
|
|
882
|
+
} else {
|
|
883
|
+
renamed = this.getTopLevelName(
|
|
884
|
+
`$${this.bundle.publicId}$${imported}`,
|
|
885
|
+
);
|
|
886
|
+
}
|
|
823
887
|
}
|
|
824
888
|
|
|
825
889
|
external.set(imported, renamed);
|
|
826
890
|
if (local !== '*' && replacements) {
|
|
827
|
-
|
|
891
|
+
let replacement = renamed;
|
|
892
|
+
if (property === '*') {
|
|
893
|
+
replacement = renamed;
|
|
894
|
+
} else if (property === 'default') {
|
|
895
|
+
replacement = `($parcel$interopDefault(${renamed}))`;
|
|
896
|
+
this.usedHelpers.add('$parcel$interopDefault');
|
|
897
|
+
} else if (property) {
|
|
898
|
+
replacement = this.getPropertyAccess(renamed, property);
|
|
899
|
+
}
|
|
900
|
+
replacements.set(local, replacement);
|
|
828
901
|
}
|
|
829
902
|
}
|
|
830
903
|
}
|
|
@@ -849,6 +922,7 @@ ${code}
|
|
|
849
922
|
resolved: Asset,
|
|
850
923
|
imported: string,
|
|
851
924
|
dep?: Dependency,
|
|
925
|
+
replacements?: Map<string, string>,
|
|
852
926
|
): string {
|
|
853
927
|
let {
|
|
854
928
|
asset: resolvedAsset,
|
|
@@ -922,13 +996,16 @@ ${code}
|
|
|
922
996
|
// namespace export symbol.
|
|
923
997
|
let assetId = resolvedAsset.meta.id;
|
|
924
998
|
invariant(typeof assetId === 'string');
|
|
925
|
-
let obj
|
|
926
|
-
|
|
927
|
-
|
|
928
|
-
|
|
929
|
-
|
|
930
|
-
|
|
931
|
-
|
|
999
|
+
let obj;
|
|
1000
|
+
if (isWrapped && (!dep || dep?.meta.shouldWrap)) {
|
|
1001
|
+
// Wrap in extra parenthesis to not change semantics, e.g.`new (parcelRequire("..."))()`.
|
|
1002
|
+
obj = `(parcelRequire(${JSON.stringify(publicId)}))`;
|
|
1003
|
+
} else if (isWrapped && dep) {
|
|
1004
|
+
obj = `$${publicId}`;
|
|
1005
|
+
} else {
|
|
1006
|
+
obj = resolvedAsset.symbols.get('*')?.local || `$${assetId}$exports`;
|
|
1007
|
+
obj = replacements?.get(obj) || obj;
|
|
1008
|
+
}
|
|
932
1009
|
|
|
933
1010
|
if (imported === '*' || exportSymbol === '*' || isDefaultInterop) {
|
|
934
1011
|
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
|
|
@@ -963,7 +1040,7 @@ ${code}
|
|
|
963
1040
|
} else if (!symbol) {
|
|
964
1041
|
invariant(false, 'Asset was skipped or not found.');
|
|
965
1042
|
} else {
|
|
966
|
-
return symbol;
|
|
1043
|
+
return replacements?.get(symbol) || symbol;
|
|
967
1044
|
}
|
|
968
1045
|
}
|
|
969
1046
|
|
|
@@ -1010,6 +1087,7 @@ ${code}
|
|
|
1010
1087
|
buildAssetPrelude(
|
|
1011
1088
|
asset: Asset,
|
|
1012
1089
|
deps: Array<Dependency>,
|
|
1090
|
+
replacements: Map<string, string>,
|
|
1013
1091
|
): [string, number, string] {
|
|
1014
1092
|
let prepend = '';
|
|
1015
1093
|
let prependLineCount = 0;
|
|
@@ -1042,6 +1120,7 @@ ${code}
|
|
|
1042
1120
|
.some(
|
|
1043
1121
|
dep =>
|
|
1044
1122
|
!dep.isEntry &&
|
|
1123
|
+
this.bundle.hasDependency(dep) &&
|
|
1045
1124
|
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1046
1125
|
))) ||
|
|
1047
1126
|
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
@@ -1050,7 +1129,11 @@ ${code}
|
|
|
1050
1129
|
[...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s))) ||
|
|
1051
1130
|
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
1052
1131
|
// include the namespace object for the default export.
|
|
1053
|
-
this.exportedSymbols.has(`$${assetId}$exports`)
|
|
1132
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
1133
|
+
// CommonJS library bundle entries always need a namespace.
|
|
1134
|
+
(this.bundle.env.isLibrary &&
|
|
1135
|
+
this.bundle.env.outputFormat === 'commonjs' &&
|
|
1136
|
+
asset === this.bundle.getMainEntry());
|
|
1054
1137
|
|
|
1055
1138
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
1056
1139
|
// or we need default interop, then we need to synthesize a namespace object for
|
|
@@ -1117,7 +1200,13 @@ ${code}
|
|
|
1117
1200
|
(!resolved.meta.hasCJSExports &&
|
|
1118
1201
|
resolved.symbols.hasExportSymbol('*'))
|
|
1119
1202
|
) {
|
|
1120
|
-
let obj = this.getSymbolResolution(
|
|
1203
|
+
let obj = this.getSymbolResolution(
|
|
1204
|
+
asset,
|
|
1205
|
+
resolved,
|
|
1206
|
+
'*',
|
|
1207
|
+
dep,
|
|
1208
|
+
replacements,
|
|
1209
|
+
);
|
|
1121
1210
|
append += `$parcel$exportWildcard($${assetId}$exports, ${obj});\n`;
|
|
1122
1211
|
this.usedHelpers.add('$parcel$exportWildcard');
|
|
1123
1212
|
} else {
|
|
@@ -1135,6 +1224,8 @@ ${code}
|
|
|
1135
1224
|
asset,
|
|
1136
1225
|
resolved,
|
|
1137
1226
|
symbol,
|
|
1227
|
+
undefined,
|
|
1228
|
+
replacements,
|
|
1138
1229
|
);
|
|
1139
1230
|
let get = this.buildFunctionExpression([], resolvedSymbol);
|
|
1140
1231
|
let set = asset.meta.hasCJSExports
|
|
@@ -1181,7 +1272,13 @@ ${code}
|
|
|
1181
1272
|
// additional assignments after each mutation of the original binding.
|
|
1182
1273
|
prepend += `\n${usedExports
|
|
1183
1274
|
.map(exp => {
|
|
1184
|
-
let resolved = this.getSymbolResolution(
|
|
1275
|
+
let resolved = this.getSymbolResolution(
|
|
1276
|
+
asset,
|
|
1277
|
+
asset,
|
|
1278
|
+
exp,
|
|
1279
|
+
undefined,
|
|
1280
|
+
replacements,
|
|
1281
|
+
);
|
|
1185
1282
|
let get = this.buildFunctionExpression([], resolved);
|
|
1186
1283
|
let isEsmExport = !!asset.symbols.get(exp)?.meta?.isEsm;
|
|
1187
1284
|
let set =
|
package/src/index.js
CHANGED
|
@@ -10,7 +10,6 @@ import {
|
|
|
10
10
|
} from '@parcel/utils';
|
|
11
11
|
import {encodeJSONKeyComponent} from '@parcel/diagnostic';
|
|
12
12
|
import {hashString} from '@parcel/rust';
|
|
13
|
-
import path from 'path';
|
|
14
13
|
import nullthrows from 'nullthrows';
|
|
15
14
|
import {DevPackager} from './DevPackager';
|
|
16
15
|
import {ScopeHoistingPackager} from './ScopeHoistingPackager';
|
|
@@ -32,22 +31,18 @@ const CONFIG_SCHEMA: SchemaEntity = {
|
|
|
32
31
|
|
|
33
32
|
export default (new Packager({
|
|
34
33
|
async loadConfig({config, options}): Promise<JSPackagerConfig> {
|
|
35
|
-
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
36
|
-
// This allows multiple parcel builds to coexist on the same page.
|
|
37
|
-
let pkg = await config.getConfigFrom(
|
|
38
|
-
path.join(options.projectRoot, 'index'),
|
|
39
|
-
['package.json'],
|
|
40
|
-
);
|
|
41
|
-
|
|
42
34
|
let packageKey = '@parcel/packager-js';
|
|
35
|
+
let conf = await config.getConfigFrom(options.projectRoot + '/index', [], {
|
|
36
|
+
packageKey,
|
|
37
|
+
});
|
|
43
38
|
|
|
44
|
-
if (
|
|
39
|
+
if (conf?.contents) {
|
|
45
40
|
validateSchema.diagnostic(
|
|
46
41
|
CONFIG_SCHEMA,
|
|
47
42
|
{
|
|
48
|
-
data:
|
|
49
|
-
source: await options.inputFS.readFile(
|
|
50
|
-
filePath:
|
|
43
|
+
data: conf?.contents,
|
|
44
|
+
source: await options.inputFS.readFile(conf.filePath, 'utf8'),
|
|
45
|
+
filePath: conf.filePath,
|
|
51
46
|
prependKey: `/${encodeJSONKeyComponent(packageKey)}`,
|
|
52
47
|
},
|
|
53
48
|
packageKey,
|
|
@@ -55,11 +50,21 @@ export default (new Packager({
|
|
|
55
50
|
);
|
|
56
51
|
}
|
|
57
52
|
|
|
58
|
-
|
|
53
|
+
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
54
|
+
// This allows multiple parcel builds to coexist on the same page.
|
|
55
|
+
let packageName = await config.getConfigFrom(
|
|
56
|
+
options.projectRoot + '/index',
|
|
57
|
+
[],
|
|
58
|
+
{
|
|
59
|
+
packageKey: 'name',
|
|
60
|
+
},
|
|
61
|
+
);
|
|
62
|
+
|
|
63
|
+
let name = packageName?.contents?.name ?? '';
|
|
59
64
|
return {
|
|
60
65
|
parcelRequireName: 'parcelRequire' + hashString(name).slice(-4),
|
|
61
66
|
unstable_asyncBundleRuntime: Boolean(
|
|
62
|
-
|
|
67
|
+
conf?.contents?.unstable_asyncBundleRuntime,
|
|
63
68
|
),
|
|
64
69
|
};
|
|
65
70
|
},
|
package/src/utils.js
CHANGED
|
@@ -55,3 +55,20 @@ export function getSpecifier(dep: Dependency): string {
|
|
|
55
55
|
|
|
56
56
|
return dep.specifier;
|
|
57
57
|
}
|
|
58
|
+
|
|
59
|
+
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
|
|
60
|
+
const IDENTIFIER_RE = /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u;
|
|
61
|
+
const ID_START_RE = /^[$_\p{ID_Start}]/u;
|
|
62
|
+
const NON_ID_CONTINUE_RE = /[^$_\u200C\u200D\p{ID_Continue}]/gu;
|
|
63
|
+
|
|
64
|
+
export function isValidIdentifier(id: string): boolean {
|
|
65
|
+
return IDENTIFIER_RE.test(id);
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
export function makeValidIdentifier(name: string): string {
|
|
69
|
+
name = name.replace(NON_ID_CONTINUE_RE, '');
|
|
70
|
+
if (!ID_START_RE.test(name)) {
|
|
71
|
+
name = '_' + name;
|
|
72
|
+
}
|
|
73
|
+
return name;
|
|
74
|
+
}
|