@atlaspack/packager-js 2.14.11 → 2.15.0
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/CHANGELOG.md +21 -0
- package/lib/ScopeHoistingPackager.js +113 -48
- package/package.json +5 -5
- package/src/ScopeHoistingPackager.js +166 -72
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,26 @@
|
|
|
1
1
|
# @atlaspack/packager-js
|
|
2
2
|
|
|
3
|
+
## 2.15.0
|
|
4
|
+
|
|
5
|
+
### Minor Changes
|
|
6
|
+
|
|
7
|
+
- [#627](https://github.com/atlassian-labs/atlaspack/pull/627) [`85c52d3`](https://github.com/atlassian-labs/atlaspack/commit/85c52d3f7717b3c84a118d18ab98cfbfd71dcbd2) Thanks [@benjervis](https://github.com/benjervis)! - Expands the situations where scope hoisting may be applied to include assets with no dependencies, regardless of whether if they have a wrapped ancestor.
|
|
8
|
+
|
|
9
|
+
Can be enabled with the `applyScopeHoistingImprovement` feature flag.
|
|
10
|
+
|
|
11
|
+
### Patch Changes
|
|
12
|
+
|
|
13
|
+
- [#632](https://github.com/atlassian-labs/atlaspack/pull/632) [`10fbcfb`](https://github.com/atlassian-labs/atlaspack/commit/10fbcfbfa49c7a83da5d7c40983e36e87f524a75) Thanks [@marcins](https://github.com/marcins)! - Added a new feature flag `inlineConstOptimisationFix` which when enabled changes the behaviour for output of constant modules. This fixes two issues with constant modules:
|
|
14
|
+
|
|
15
|
+
- Previously constant modules, if they needed a namespace anywhere, would have a namespace everywhere, with this change they only have a namespace in the bundles where needed.
|
|
16
|
+
- Previously in the case of wrapped assets, a constant module dependnecy of that wrapped asset would be rendered after the module - which meant the minifier would not be able to inline the constants safely. With this flag all constant modules are rendered at the top of the bundle.
|
|
17
|
+
|
|
18
|
+
- Updated dependencies [[`10fbcfb`](https://github.com/atlassian-labs/atlaspack/commit/10fbcfbfa49c7a83da5d7c40983e36e87f524a75), [`85c52d3`](https://github.com/atlassian-labs/atlaspack/commit/85c52d3f7717b3c84a118d18ab98cfbfd71dcbd2), [`e39c6cf`](https://github.com/atlassian-labs/atlaspack/commit/e39c6cf05f7e95ce5420dbcea66f401b1cbd397c)]:
|
|
19
|
+
- @atlaspack/feature-flags@2.18.0
|
|
20
|
+
- @atlaspack/utils@2.15.0
|
|
21
|
+
- @atlaspack/types@2.15.2
|
|
22
|
+
- @atlaspack/plugin@2.14.12
|
|
23
|
+
|
|
3
24
|
## 2.14.11
|
|
4
25
|
|
|
5
26
|
### Patch Changes
|
|
@@ -115,7 +115,10 @@ class ScopeHoistingPackager {
|
|
|
115
115
|
}
|
|
116
116
|
async package() {
|
|
117
117
|
var _sourceMap;
|
|
118
|
-
let
|
|
118
|
+
let {
|
|
119
|
+
wrapped: wrappedAssets,
|
|
120
|
+
constant: constantAssets
|
|
121
|
+
} = await this.loadAssets();
|
|
119
122
|
this.buildExportedSymbols();
|
|
120
123
|
|
|
121
124
|
// If building a library, the target is actually another bundler rather
|
|
@@ -143,6 +146,14 @@ class ScopeHoistingPackager {
|
|
|
143
146
|
res += content + '\n';
|
|
144
147
|
lineCount += lines + 1;
|
|
145
148
|
};
|
|
149
|
+
if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix')) {
|
|
150
|
+
// Write out all constant modules used by this bundle
|
|
151
|
+
for (let asset of constantAssets) {
|
|
152
|
+
if (!this.seenAssets.has(asset.id)) {
|
|
153
|
+
processAsset(asset);
|
|
154
|
+
}
|
|
155
|
+
}
|
|
156
|
+
}
|
|
146
157
|
|
|
147
158
|
// Hoist wrapped asset to the top of the bundle to ensure that they are registered
|
|
148
159
|
// before they are used.
|
|
@@ -265,6 +276,7 @@ class ScopeHoistingPackager {
|
|
|
265
276
|
maxConcurrent: 32
|
|
266
277
|
});
|
|
267
278
|
let wrapped = [];
|
|
279
|
+
let constant = [];
|
|
268
280
|
this.bundle.traverseAssets(asset => {
|
|
269
281
|
queue.add(async () => {
|
|
270
282
|
let [code, map] = await Promise.all([asset.getCode(), this.bundle.env.sourceMap ? asset.getMapBuffer() : null]);
|
|
@@ -278,38 +290,76 @@ class ScopeHoistingPackager {
|
|
|
278
290
|
if (!asset.meta.isConstantModule || this.bundleGraph.getIncomingDependencies(asset).some(dep => dep.priority === 'lazy')) {
|
|
279
291
|
this.wrappedAssets.add(asset.id);
|
|
280
292
|
wrapped.push(asset);
|
|
293
|
+
} else if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') && asset.meta.isConstantModule) {
|
|
294
|
+
constant.push(asset);
|
|
281
295
|
}
|
|
282
296
|
}
|
|
283
297
|
});
|
|
284
|
-
|
|
285
|
-
|
|
286
|
-
|
|
287
|
-
|
|
288
|
-
|
|
289
|
-
|
|
290
|
-
|
|
291
|
-
|
|
292
|
-
|
|
293
|
-
|
|
294
|
-
|
|
295
|
-
|
|
296
|
-
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
}
|
|
302
|
-
|
|
303
|
-
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
298
|
+
if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
|
|
299
|
+
// Tracks which assets have been assigned to a wrap group
|
|
300
|
+
let assignedAssets = new Set();
|
|
301
|
+
for (let wrappedAsset of wrapped) {
|
|
302
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
303
|
+
if (asset === wrappedAsset) {
|
|
304
|
+
return;
|
|
305
|
+
}
|
|
306
|
+
if (this.wrappedAssets.has(asset.id)) {
|
|
307
|
+
actions.skipChildren();
|
|
308
|
+
return;
|
|
309
|
+
}
|
|
310
|
+
if (assignedAssets.has(asset) || this.isReExported(asset)) {
|
|
311
|
+
wrapped.push(asset);
|
|
312
|
+
this.wrappedAssets.add(asset.id);
|
|
313
|
+
actions.skipChildren();
|
|
314
|
+
return;
|
|
315
|
+
}
|
|
316
|
+
assignedAssets.add(asset);
|
|
317
|
+
}, wrappedAsset);
|
|
318
|
+
}
|
|
319
|
+
} else {
|
|
320
|
+
for (let wrappedAssetRoot of [...wrapped]) {
|
|
321
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
322
|
+
if (asset === wrappedAssetRoot) {
|
|
323
|
+
return;
|
|
324
|
+
}
|
|
325
|
+
if (this.wrappedAssets.has(asset.id)) {
|
|
326
|
+
actions.skipChildren();
|
|
327
|
+
return;
|
|
328
|
+
}
|
|
329
|
+
// This prevents children of a wrapped asset also being wrapped - it's an "unsafe" optimisation
|
|
330
|
+
// that should only be used when you know (or think you know) what you're doing.
|
|
331
|
+
//
|
|
332
|
+
// In particular this can force an async bundle to be scope hoisted where it previously would not be
|
|
333
|
+
// due to the entry asset being wrapped.
|
|
334
|
+
if (this.forceSkipWrapAssets.length > 0 && this.forceSkipWrapAssets.some(p => p === _path().default.relative(this.options.projectRoot, asset.filePath))) {
|
|
335
|
+
this.logger.verbose({
|
|
336
|
+
message: `Force skipping wrapping of ${_path().default.relative(this.options.projectRoot, asset.filePath)}`
|
|
337
|
+
});
|
|
338
|
+
actions.skipChildren();
|
|
339
|
+
return;
|
|
340
|
+
}
|
|
341
|
+
if (!asset.meta.isConstantModule) {
|
|
342
|
+
this.wrappedAssets.add(asset.id);
|
|
343
|
+
wrapped.push(asset);
|
|
344
|
+
}
|
|
345
|
+
}, wrappedAssetRoot);
|
|
346
|
+
}
|
|
310
347
|
}
|
|
311
348
|
this.assetOutputs = new Map(await queue.run());
|
|
312
|
-
return
|
|
349
|
+
return {
|
|
350
|
+
wrapped,
|
|
351
|
+
constant
|
|
352
|
+
};
|
|
353
|
+
}
|
|
354
|
+
isReExported(asset) {
|
|
355
|
+
let parentSymbols = this.bundleGraph.getIncomingDependencies(asset).map(dep => this.bundleGraph.getAssetWithDependency(dep)).flatMap(parent => {
|
|
356
|
+
if (parent == null) {
|
|
357
|
+
return [];
|
|
358
|
+
}
|
|
359
|
+
return this.bundleGraph.getExportedSymbols(parent, this.bundle);
|
|
360
|
+
});
|
|
361
|
+
let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
|
|
362
|
+
return assetSymbols.some(assetSymbol => parentSymbols.some(parentSymbol => parentSymbol.symbol === assetSymbol.symbol));
|
|
313
363
|
}
|
|
314
364
|
buildExportedSymbols() {
|
|
315
365
|
if (!this.bundle.env.isLibrary || this.bundle.env.outputFormat !== 'esmodule') {
|
|
@@ -489,13 +539,22 @@ class ScopeHoistingPackager {
|
|
|
489
539
|
// outside our parcelRequire.register wrapper. This is safe because all
|
|
490
540
|
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
491
541
|
// asset content where the import statement was.
|
|
492
|
-
if (
|
|
493
|
-
|
|
542
|
+
if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
|
|
543
|
+
if (!this.wrappedAssets.has(resolved.id)) {
|
|
544
|
+
let [depCode, depMap, depLines] = this.visitAsset(resolved);
|
|
545
|
+
res = depCode + '\n' + res;
|
|
546
|
+
lines += 1 + depLines;
|
|
547
|
+
map = depMap;
|
|
548
|
+
}
|
|
494
549
|
} else {
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
550
|
+
if (shouldWrap) {
|
|
551
|
+
depContent.push(this.visitAsset(resolved));
|
|
552
|
+
} else {
|
|
553
|
+
let [depCode, depMap, depLines] = this.visitAsset(resolved);
|
|
554
|
+
res = depCode + '\n' + res;
|
|
555
|
+
lines += 1 + depLines;
|
|
556
|
+
map = depMap;
|
|
557
|
+
}
|
|
499
558
|
}
|
|
500
559
|
}
|
|
501
560
|
|
|
@@ -874,20 +933,26 @@ ${code}
|
|
|
874
933
|
// If there's no __esModule flag, and default is a used symbol, we need
|
|
875
934
|
// to insert an interop helper.
|
|
876
935
|
let defaultInterop = asset.symbols.hasExportSymbol('*') && usedSymbols.has('default') && !asset.symbols.hasExportSymbol('__esModule');
|
|
877
|
-
let usedNamespace
|
|
878
|
-
|
|
879
|
-
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
883
|
-
|
|
884
|
-
|
|
885
|
-
|
|
886
|
-
|
|
887
|
-
|
|
888
|
-
|
|
889
|
-
|
|
890
|
-
|
|
936
|
+
let usedNamespace;
|
|
937
|
+
if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') && asset.meta.isConstantModule) {
|
|
938
|
+
// Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
|
|
939
|
+
usedNamespace = this.bundleGraph.getIncomingDependencies(asset).some(dep => this.bundle.hasDependency(dep) && (0, _nullthrows().default)(this.bundleGraph.getUsedSymbols(dep)).has('*'));
|
|
940
|
+
} else {
|
|
941
|
+
usedNamespace =
|
|
942
|
+
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
943
|
+
// The one case where this isn't true is in ESM library entries, where the only
|
|
944
|
+
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
945
|
+
// instead of the namespace object.
|
|
946
|
+
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('*'))) ||
|
|
947
|
+
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
948
|
+
// we fallback on the namespace object.
|
|
949
|
+
asset.symbols.hasExportSymbol('*') && [...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s)) ||
|
|
950
|
+
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
951
|
+
// include the namespace object for the default export.
|
|
952
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
953
|
+
// CommonJS library bundle entries always need a namespace.
|
|
954
|
+
this.bundle.env.isLibrary && this.bundle.env.outputFormat === 'commonjs' && asset === this.bundle.getMainEntry();
|
|
955
|
+
}
|
|
891
956
|
|
|
892
957
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
893
958
|
// or we need default interop, then we need to synthesize a namespace object for
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/packager-js",
|
|
3
|
-
"version": "2.
|
|
3
|
+
"version": "2.15.0",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -16,12 +16,12 @@
|
|
|
16
16
|
},
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@atlaspack/diagnostic": "2.14.1",
|
|
19
|
-
"@atlaspack/feature-flags": "2.
|
|
20
|
-
"@atlaspack/plugin": "2.14.
|
|
19
|
+
"@atlaspack/feature-flags": "2.18.0",
|
|
20
|
+
"@atlaspack/plugin": "2.14.12",
|
|
21
21
|
"@atlaspack/rust": "3.3.5",
|
|
22
22
|
"@parcel/source-map": "^2.1.1",
|
|
23
|
-
"@atlaspack/types": "2.15.
|
|
24
|
-
"@atlaspack/utils": "2.
|
|
23
|
+
"@atlaspack/types": "2.15.2",
|
|
24
|
+
"@atlaspack/utils": "2.15.0",
|
|
25
25
|
"globals": "^13.2.0",
|
|
26
26
|
"nullthrows": "^1.1.1"
|
|
27
27
|
},
|
|
@@ -134,7 +134,8 @@ export class ScopeHoistingPackager {
|
|
|
134
134
|
}
|
|
135
135
|
|
|
136
136
|
async package(): Promise<{|contents: string, map: ?SourceMap|}> {
|
|
137
|
-
let wrappedAssets
|
|
137
|
+
let {wrapped: wrappedAssets, constant: constantAssets} =
|
|
138
|
+
await this.loadAssets();
|
|
138
139
|
this.buildExportedSymbols();
|
|
139
140
|
|
|
140
141
|
// If building a library, the target is actually another bundler rather
|
|
@@ -168,6 +169,15 @@ export class ScopeHoistingPackager {
|
|
|
168
169
|
lineCount += lines + 1;
|
|
169
170
|
};
|
|
170
171
|
|
|
172
|
+
if (getFeatureFlag('inlineConstOptimisationFix')) {
|
|
173
|
+
// Write out all constant modules used by this bundle
|
|
174
|
+
for (let asset of constantAssets) {
|
|
175
|
+
if (!this.seenAssets.has(asset.id)) {
|
|
176
|
+
processAsset(asset);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
|
|
171
181
|
// Hoist wrapped asset to the top of the bundle to ensure that they are registered
|
|
172
182
|
// before they are used.
|
|
173
183
|
for (let asset of wrappedAssets) {
|
|
@@ -354,15 +364,20 @@ export class ScopeHoistingPackager {
|
|
|
354
364
|
return `$parcel$global.rwr(${params.join(', ')});`;
|
|
355
365
|
}
|
|
356
366
|
|
|
357
|
-
async loadAssets(): Promise<
|
|
367
|
+
async loadAssets(): Promise<{|
|
|
368
|
+
wrapped: Array<Asset>,
|
|
369
|
+
constant: Array<Asset>,
|
|
370
|
+
|}> {
|
|
358
371
|
let queue = new PromiseQueue({maxConcurrent: 32});
|
|
359
372
|
let wrapped = [];
|
|
373
|
+
let constant = [];
|
|
360
374
|
this.bundle.traverseAssets((asset) => {
|
|
361
375
|
queue.add(async () => {
|
|
362
376
|
let [code, map] = await Promise.all([
|
|
363
377
|
asset.getCode(),
|
|
364
378
|
this.bundle.env.sourceMap ? asset.getMapBuffer() : null,
|
|
365
379
|
]);
|
|
380
|
+
|
|
366
381
|
return [asset.id, {code, map}];
|
|
367
382
|
});
|
|
368
383
|
|
|
@@ -383,50 +398,103 @@ export class ScopeHoistingPackager {
|
|
|
383
398
|
) {
|
|
384
399
|
this.wrappedAssets.add(asset.id);
|
|
385
400
|
wrapped.push(asset);
|
|
401
|
+
} else if (
|
|
402
|
+
getFeatureFlag('inlineConstOptimisationFix') &&
|
|
403
|
+
asset.meta.isConstantModule
|
|
404
|
+
) {
|
|
405
|
+
constant.push(asset);
|
|
386
406
|
}
|
|
387
407
|
}
|
|
388
408
|
});
|
|
389
409
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
return;
|
|
394
|
-
}
|
|
410
|
+
if (getFeatureFlag('applyScopeHoistingImprovement')) {
|
|
411
|
+
// Tracks which assets have been assigned to a wrap group
|
|
412
|
+
let assignedAssets = new Set<Asset>();
|
|
395
413
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
this.
|
|
408
|
-
(
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
414
|
+
for (let wrappedAsset of wrapped) {
|
|
415
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
416
|
+
if (asset === wrappedAsset) {
|
|
417
|
+
return;
|
|
418
|
+
}
|
|
419
|
+
|
|
420
|
+
if (this.wrappedAssets.has(asset.id)) {
|
|
421
|
+
actions.skipChildren();
|
|
422
|
+
return;
|
|
423
|
+
}
|
|
424
|
+
|
|
425
|
+
if (assignedAssets.has(asset) || this.isReExported(asset)) {
|
|
426
|
+
wrapped.push(asset);
|
|
427
|
+
this.wrappedAssets.add(asset.id);
|
|
428
|
+
|
|
429
|
+
actions.skipChildren();
|
|
430
|
+
return;
|
|
431
|
+
}
|
|
432
|
+
|
|
433
|
+
assignedAssets.add(asset);
|
|
434
|
+
}, wrappedAsset);
|
|
435
|
+
}
|
|
436
|
+
} else {
|
|
437
|
+
for (let wrappedAssetRoot of [...wrapped]) {
|
|
438
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
439
|
+
if (asset === wrappedAssetRoot) {
|
|
440
|
+
return;
|
|
441
|
+
}
|
|
442
|
+
|
|
443
|
+
if (this.wrappedAssets.has(asset.id)) {
|
|
444
|
+
actions.skipChildren();
|
|
445
|
+
return;
|
|
446
|
+
}
|
|
447
|
+
// This prevents children of a wrapped asset also being wrapped - it's an "unsafe" optimisation
|
|
448
|
+
// that should only be used when you know (or think you know) what you're doing.
|
|
449
|
+
//
|
|
450
|
+
// In particular this can force an async bundle to be scope hoisted where it previously would not be
|
|
451
|
+
// due to the entry asset being wrapped.
|
|
452
|
+
if (
|
|
453
|
+
this.forceSkipWrapAssets.length > 0 &&
|
|
454
|
+
this.forceSkipWrapAssets.some(
|
|
455
|
+
(p) =>
|
|
456
|
+
p === path.relative(this.options.projectRoot, asset.filePath),
|
|
457
|
+
)
|
|
458
|
+
) {
|
|
459
|
+
this.logger.verbose({
|
|
460
|
+
message: `Force skipping wrapping of ${path.relative(
|
|
461
|
+
this.options.projectRoot,
|
|
462
|
+
asset.filePath,
|
|
463
|
+
)}`,
|
|
464
|
+
});
|
|
465
|
+
actions.skipChildren();
|
|
466
|
+
return;
|
|
467
|
+
}
|
|
468
|
+
if (!asset.meta.isConstantModule) {
|
|
469
|
+
this.wrappedAssets.add(asset.id);
|
|
470
|
+
wrapped.push(asset);
|
|
471
|
+
}
|
|
472
|
+
}, wrappedAssetRoot);
|
|
473
|
+
}
|
|
426
474
|
}
|
|
427
475
|
|
|
428
476
|
this.assetOutputs = new Map(await queue.run());
|
|
429
|
-
return wrapped;
|
|
477
|
+
return {wrapped, constant};
|
|
478
|
+
}
|
|
479
|
+
|
|
480
|
+
isReExported(asset: Asset): boolean {
|
|
481
|
+
let parentSymbols = this.bundleGraph
|
|
482
|
+
.getIncomingDependencies(asset)
|
|
483
|
+
.map((dep) => this.bundleGraph.getAssetWithDependency(dep))
|
|
484
|
+
.flatMap((parent) => {
|
|
485
|
+
if (parent == null) {
|
|
486
|
+
return [];
|
|
487
|
+
}
|
|
488
|
+
return this.bundleGraph.getExportedSymbols(parent, this.bundle);
|
|
489
|
+
});
|
|
490
|
+
|
|
491
|
+
let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
|
|
492
|
+
|
|
493
|
+
return assetSymbols.some((assetSymbol) =>
|
|
494
|
+
parentSymbols.some(
|
|
495
|
+
(parentSymbol) => parentSymbol.symbol === assetSymbol.symbol,
|
|
496
|
+
),
|
|
497
|
+
);
|
|
430
498
|
}
|
|
431
499
|
|
|
432
500
|
buildExportedSymbols() {
|
|
@@ -661,13 +729,24 @@ export class ScopeHoistingPackager {
|
|
|
661
729
|
// outside our parcelRequire.register wrapper. This is safe because all
|
|
662
730
|
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
663
731
|
// asset content where the import statement was.
|
|
664
|
-
if (
|
|
665
|
-
|
|
732
|
+
if (getFeatureFlag('applyScopeHoistingImprovement')) {
|
|
733
|
+
if (!this.wrappedAssets.has(resolved.id)) {
|
|
734
|
+
let [depCode, depMap, depLines] =
|
|
735
|
+
this.visitAsset(resolved);
|
|
736
|
+
res = depCode + '\n' + res;
|
|
737
|
+
lines += 1 + depLines;
|
|
738
|
+
map = depMap;
|
|
739
|
+
}
|
|
666
740
|
} else {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
741
|
+
if (shouldWrap) {
|
|
742
|
+
depContent.push(this.visitAsset(resolved));
|
|
743
|
+
} else {
|
|
744
|
+
let [depCode, depMap, depLines] =
|
|
745
|
+
this.visitAsset(resolved);
|
|
746
|
+
res = depCode + '\n' + res;
|
|
747
|
+
lines += 1 + depLines;
|
|
748
|
+
map = depMap;
|
|
749
|
+
}
|
|
671
750
|
}
|
|
672
751
|
}
|
|
673
752
|
|
|
@@ -1220,34 +1299,49 @@ ${code}
|
|
|
1220
1299
|
usedSymbols.has('default') &&
|
|
1221
1300
|
!asset.symbols.hasExportSymbol('__esModule');
|
|
1222
1301
|
|
|
1223
|
-
let usedNamespace
|
|
1224
|
-
|
|
1225
|
-
|
|
1226
|
-
|
|
1227
|
-
|
|
1228
|
-
|
|
1229
|
-
|
|
1230
|
-
|
|
1231
|
-
|
|
1232
|
-
|
|
1233
|
-
.
|
|
1234
|
-
.
|
|
1235
|
-
|
|
1236
|
-
|
|
1237
|
-
|
|
1238
|
-
|
|
1239
|
-
|
|
1240
|
-
|
|
1241
|
-
|
|
1242
|
-
|
|
1243
|
-
|
|
1244
|
-
|
|
1245
|
-
|
|
1246
|
-
|
|
1247
|
-
|
|
1248
|
-
|
|
1249
|
-
|
|
1250
|
-
|
|
1302
|
+
let usedNamespace;
|
|
1303
|
+
if (
|
|
1304
|
+
getFeatureFlag('inlineConstOptimisationFix') &&
|
|
1305
|
+
asset.meta.isConstantModule
|
|
1306
|
+
) {
|
|
1307
|
+
// Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
|
|
1308
|
+
usedNamespace = this.bundleGraph
|
|
1309
|
+
.getIncomingDependencies(asset)
|
|
1310
|
+
.some(
|
|
1311
|
+
(dep) =>
|
|
1312
|
+
this.bundle.hasDependency(dep) &&
|
|
1313
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1314
|
+
);
|
|
1315
|
+
} else {
|
|
1316
|
+
usedNamespace =
|
|
1317
|
+
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
1318
|
+
// The one case where this isn't true is in ESM library entries, where the only
|
|
1319
|
+
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
1320
|
+
// instead of the namespace object.
|
|
1321
|
+
(usedSymbols.has('*') &&
|
|
1322
|
+
(this.bundle.env.outputFormat !== 'esmodule' ||
|
|
1323
|
+
!this.bundle.env.isLibrary ||
|
|
1324
|
+
asset !== this.bundle.getMainEntry() ||
|
|
1325
|
+
this.bundleGraph
|
|
1326
|
+
.getIncomingDependencies(asset)
|
|
1327
|
+
.some(
|
|
1328
|
+
(dep) =>
|
|
1329
|
+
!dep.isEntry &&
|
|
1330
|
+
this.bundle.hasDependency(dep) &&
|
|
1331
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1332
|
+
))) ||
|
|
1333
|
+
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
1334
|
+
// we fallback on the namespace object.
|
|
1335
|
+
(asset.symbols.hasExportSymbol('*') &&
|
|
1336
|
+
[...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
|
|
1337
|
+
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
1338
|
+
// include the namespace object for the default export.
|
|
1339
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
1340
|
+
// CommonJS library bundle entries always need a namespace.
|
|
1341
|
+
(this.bundle.env.isLibrary &&
|
|
1342
|
+
this.bundle.env.outputFormat === 'commonjs' &&
|
|
1343
|
+
asset === this.bundle.getMainEntry());
|
|
1344
|
+
}
|
|
1251
1345
|
|
|
1252
1346
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
1253
1347
|
// or we need default interop, then we need to synthesize a namespace object for
|