@atlaspack/packager-js 2.22.0 → 2.22.2

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 CHANGED
@@ -1,5 +1,24 @@
1
1
  # @atlaspack/packager-js
2
2
 
3
+ ## 2.22.2
4
+
5
+ ### Patch Changes
6
+
7
+ - [#768](https://github.com/atlassian-labs/atlaspack/pull/768) [`58b9fb0`](https://github.com/atlassian-labs/atlaspack/commit/58b9fb037680a36a0b4af7890f2a03532095b88f) Thanks [@benjervis](https://github.com/benjervis)! - Fixes a small error in the scope hoisting V2 fixes that caused assets to be wrapped unnecessarily
8
+
9
+ ## 2.22.1
10
+
11
+ ### Patch Changes
12
+
13
+ - [#763](https://github.com/atlassian-labs/atlaspack/pull/763) [`830261d`](https://github.com/atlassian-labs/atlaspack/commit/830261dcf4a40293090b61cab52fd75d5683c73f) Thanks [@benjervis](https://github.com/benjervis)! - Fixes scope hoisting by iterating from the main entry asset of a bundle when packaging. Behind the feature flag `applyScopeHoistingImprovementsV2`.
14
+
15
+ - Updated dependencies [[`830261d`](https://github.com/atlassian-labs/atlaspack/commit/830261dcf4a40293090b61cab52fd75d5683c73f), [`53dd47b`](https://github.com/atlassian-labs/atlaspack/commit/53dd47bd6d23cd47f87297347f03a609ab38a03d)]:
16
+ - @atlaspack/feature-flags@2.24.1
17
+ - @atlaspack/rust@3.7.0
18
+ - @atlaspack/utils@2.19.1
19
+ - @atlaspack/plugin@2.14.29
20
+ - @atlaspack/types@2.15.19
21
+
3
22
  ## 2.22.0
4
23
 
5
24
  ### Minor Changes
@@ -105,9 +105,11 @@ class ScopeHoistingPackager {
105
105
  seenAssets = new Set();
106
106
  wrappedAssets = new Set();
107
107
  hoistedRequires = new Map();
108
+ seenHoistedRequires = new Set();
108
109
  needsPrelude = false;
109
110
  usedHelpers = new Set();
110
111
  externalAssets = new Set();
112
+ useBothScopeHoistingImprovements = (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2') || (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement');
111
113
  constructor(options, bundleGraph, bundle, parcelRequireName, useAsyncBundleRuntime, logger) {
112
114
  this.options = options;
113
115
  this.bundleGraph = bundleGraph;
@@ -145,7 +147,9 @@ class ScopeHoistingPackager {
145
147
  // @ts-expect-error TS7034
146
148
  let sourceMap = null;
147
149
  let processAsset = asset => {
150
+ this.seenHoistedRequires.clear();
148
151
  let [content, map, lines] = this.visitAsset(asset);
152
+
149
153
  // @ts-expect-error TS7005
150
154
  if (sourceMap && map) {
151
155
  sourceMap.addSourceMap(map, lineCount);
@@ -155,7 +159,7 @@ class ScopeHoistingPackager {
155
159
  res += content + '\n';
156
160
  lineCount += lines + 1;
157
161
  };
158
- if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
162
+ if ((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || this.useBothScopeHoistingImprovements) {
159
163
  // Write out all constant modules used by this bundle
160
164
  for (let asset of constantAssets) {
161
165
  if (!this.seenAssets.has(asset.id)) {
@@ -190,7 +194,7 @@ class ScopeHoistingPackager {
190
194
  let entries = this.bundle.getEntryAssets();
191
195
  let mainEntry = this.bundle.getMainEntry();
192
196
  if (this.isAsyncBundle) {
193
- if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement') || (0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
197
+ if (this.useBothScopeHoistingImprovements || (0, _featureFlags().getFeatureFlag)('supportWebpackChunkName')) {
194
198
  // Generally speaking, async bundles should not be executed on load, as
195
199
  // they're just collections of assets that other assets require.
196
200
  // However, there are some special cases where a runtime asset needs to be
@@ -317,25 +321,38 @@ class ScopeHoistingPackager {
317
321
  if (!asset.meta.isConstantModule || this.bundleGraph.getIncomingDependencies(asset).some(dep => dep.priority === 'lazy')) {
318
322
  this.wrappedAssets.add(asset.id);
319
323
  wrapped.push(asset);
320
- } else if (((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || (0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) && asset.meta.isConstantModule) {
324
+ } else if (((0, _featureFlags().getFeatureFlag)('inlineConstOptimisationFix') || this.useBothScopeHoistingImprovements) && asset.meta.isConstantModule) {
321
325
  constant.push(asset);
322
326
  }
323
327
  }
324
328
  });
325
- if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
326
- // Make all entry assets wrapped, to avoid any top level hoisting
327
- for (let entryAsset of this.bundle.getEntryAssets()) {
328
- if (!this.wrappedAssets.has(entryAsset.id)) {
329
- this.wrappedAssets.add(entryAsset.id);
330
- wrapped.push(entryAsset);
331
- }
332
- }
333
-
329
+ if (this.useBothScopeHoistingImprovements) {
334
330
  // Tracks which assets have been assigned to a wrap group
335
331
  let assignedAssets = new Set();
336
- for (let wrappedAsset of wrapped) {
332
+
333
+ // In V2 scope hoisting, we iterate from the main entry, rather than
334
+ // wrapping the entry assets
335
+ if (!(0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2')) {
336
+ // Make all entry assets wrapped, to avoid any top level hoisting
337
+ for (let entryAsset of this.bundle.getEntryAssets()) {
338
+ if (!this.wrappedAssets.has(entryAsset.id)) {
339
+ this.wrappedAssets.add(entryAsset.id);
340
+ wrapped.push(entryAsset);
341
+ }
342
+ }
343
+ }
344
+ let moduleGroupParents = [...wrapped];
345
+ if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2')) {
346
+ // The main entry needs to be check to find assets that would have gone in
347
+ // the top level scope
348
+ let mainEntry = this.bundle.getMainEntry();
349
+ if (mainEntry && !this.wrappedAssets.has(mainEntry.id)) {
350
+ moduleGroupParents.unshift(mainEntry);
351
+ }
352
+ }
353
+ for (let moduleGroupParentAsset of moduleGroupParents) {
337
354
  this.bundle.traverseAssets((asset, _, actions) => {
338
- if (asset === wrappedAsset) {
355
+ if (asset === moduleGroupParentAsset) {
339
356
  return;
340
357
  }
341
358
  if (this.wrappedAssets.has(asset.id)) {
@@ -345,11 +362,15 @@ class ScopeHoistingPackager {
345
362
  if (!asset.meta.isConstantModule && (assignedAssets.has(asset) || this.isReExported(asset))) {
346
363
  wrapped.push(asset);
347
364
  this.wrappedAssets.add(asset.id);
365
+
366
+ // This also needs to be added to the traversal so that we iterate
367
+ // it during this check.
368
+ moduleGroupParents.push(asset);
348
369
  actions.skipChildren();
349
370
  return;
350
371
  }
351
372
  assignedAssets.add(asset);
352
- }, wrappedAsset);
373
+ }, moduleGroupParentAsset);
353
374
  }
354
375
  } else {
355
376
  for (let wrappedAssetRoot of [...wrapped]) {
@@ -568,14 +589,18 @@ class ScopeHoistingPackager {
568
589
  // after the dependency is declared. This handles the case where the resulting asset
569
590
  // is wrapped, but the dependency in this asset is not marked as wrapped. This means
570
591
  // that it was imported/required at the top-level, so its side effects should run immediately.
571
- let [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
592
+ let res = '';
593
+ let lines = 0;
572
594
  let map;
595
+ if (!(0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2')) {
596
+ [res, lines] = this.getHoistedParcelRequires(asset, dep, resolved);
597
+ }
573
598
  if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved.id)) {
574
599
  // If this asset is wrapped, we need to hoist the code for the dependency
575
600
  // outside our parcelRequire.register wrapper. This is safe because all
576
601
  // assets referenced by this asset will also be wrapped. Otherwise, inline the
577
602
  // asset content where the import statement was.
578
- if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovement')) {
603
+ if (this.useBothScopeHoistingImprovements) {
579
604
  if (!resolved.meta.isConstantModule && !this.wrappedAssets.has(resolved.id)) {
580
605
  let [depCode, depMap, depLines] = this.visitAsset(resolved);
581
606
  if (_utils().debugTools['asset-file-names-in-output']) {
@@ -604,6 +629,13 @@ class ScopeHoistingPackager {
604
629
  }
605
630
  }
606
631
  }
632
+ if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2')) {
633
+ let [requiresCode, requiresLines] = this.getHoistedParcelRequires(asset, dep, resolved);
634
+ if (requiresCode) {
635
+ res = requiresCode + '\n' + res;
636
+ lines += requiresLines + 1;
637
+ }
638
+ }
607
639
 
608
640
  // Push this asset's source mappings down by the number of lines in the dependency
609
641
  // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
@@ -1020,8 +1052,17 @@ ${code}
1020
1052
  }
1021
1053
  if (hoisted) {
1022
1054
  this.needsPrelude = true;
1023
- res += '\n' + [...hoisted.values()].join('\n');
1024
- lineCount += hoisted.size;
1055
+ if ((0, _featureFlags().getFeatureFlag)('applyScopeHoistingImprovementV2')) {
1056
+ let hoistedValues = [...hoisted.values()].filter(val => !this.seenHoistedRequires.has(val));
1057
+ for (let val of hoistedValues) {
1058
+ this.seenHoistedRequires.add(val);
1059
+ }
1060
+ res += '\n' + hoistedValues.join('\n');
1061
+ lineCount += hoisted.size;
1062
+ } else {
1063
+ res += '\n' + [...hoisted.values()].join('\n');
1064
+ lineCount += hoisted.size;
1065
+ }
1025
1066
  }
1026
1067
  return [res, lineCount];
1027
1068
  }
@@ -28,10 +28,12 @@ export declare class ScopeHoistingPackager {
28
28
  seenAssets: Set<string>;
29
29
  wrappedAssets: Set<string>;
30
30
  hoistedRequires: Map<string, Map<string, string>>;
31
+ seenHoistedRequires: Set<string>;
31
32
  needsPrelude: boolean;
32
33
  usedHelpers: Set<string>;
33
34
  externalAssets: Set<Asset>;
34
35
  logger: PluginLogger;
36
+ useBothScopeHoistingImprovements: boolean;
35
37
  constructor(options: PluginOptions, bundleGraph: BundleGraph<NamedBundle>, bundle: NamedBundle, parcelRequireName: string, useAsyncBundleRuntime: boolean, logger: PluginLogger);
36
38
  package(): Promise<{
37
39
  contents: string;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/packager-js",
3
- "version": "2.22.0",
3
+ "version": "2.22.2",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -17,12 +17,12 @@
17
17
  },
18
18
  "dependencies": {
19
19
  "@atlaspack/diagnostic": "2.14.3",
20
- "@atlaspack/feature-flags": "2.24.0",
21
- "@atlaspack/plugin": "2.14.28",
22
- "@atlaspack/rust": "3.6.2",
20
+ "@atlaspack/feature-flags": "2.24.1",
21
+ "@atlaspack/plugin": "2.14.29",
22
+ "@atlaspack/rust": "3.7.0",
23
23
  "@parcel/source-map": "^2.1.1",
24
- "@atlaspack/types": "2.15.18",
25
- "@atlaspack/utils": "2.19.0",
24
+ "@atlaspack/types": "2.15.19",
25
+ "@atlaspack/utils": "2.19.1",
26
26
  "globals": "^13.2.0",
27
27
  "nullthrows": "^1.1.1",
28
28
  "outdent": "^0.8.0"
@@ -112,10 +112,14 @@ export class ScopeHoistingPackager {
112
112
  seenAssets: Set<string> = new Set();
113
113
  wrappedAssets: Set<string> = new Set();
114
114
  hoistedRequires: Map<string, Map<string, string>> = new Map();
115
+ seenHoistedRequires: Set<string> = new Set();
115
116
  needsPrelude: boolean = false;
116
117
  usedHelpers: Set<string> = new Set();
117
118
  externalAssets: Set<Asset> = new Set();
118
119
  logger: PluginLogger;
120
+ useBothScopeHoistingImprovements: boolean =
121
+ getFeatureFlag('applyScopeHoistingImprovementV2') ||
122
+ getFeatureFlag('applyScopeHoistingImprovement');
119
123
 
120
124
  constructor(
121
125
  options: PluginOptions,
@@ -173,7 +177,9 @@ export class ScopeHoistingPackager {
173
177
  // @ts-expect-error TS7034
174
178
  let sourceMap = null;
175
179
  let processAsset = (asset: Asset) => {
180
+ this.seenHoistedRequires.clear();
176
181
  let [content, map, lines] = this.visitAsset(asset);
182
+
177
183
  // @ts-expect-error TS7005
178
184
  if (sourceMap && map) {
179
185
  sourceMap.addSourceMap(map, lineCount);
@@ -187,7 +193,7 @@ export class ScopeHoistingPackager {
187
193
 
188
194
  if (
189
195
  getFeatureFlag('inlineConstOptimisationFix') ||
190
- getFeatureFlag('applyScopeHoistingImprovement')
196
+ this.useBothScopeHoistingImprovements
191
197
  ) {
192
198
  // Write out all constant modules used by this bundle
193
199
  for (let asset of constantAssets) {
@@ -227,7 +233,7 @@ export class ScopeHoistingPackager {
227
233
  let mainEntry = this.bundle.getMainEntry();
228
234
  if (this.isAsyncBundle) {
229
235
  if (
230
- getFeatureFlag('applyScopeHoistingImprovement') ||
236
+ this.useBothScopeHoistingImprovements ||
231
237
  getFeatureFlag('supportWebpackChunkName')
232
238
  ) {
233
239
  // Generally speaking, async bundles should not be executed on load, as
@@ -433,7 +439,7 @@ export class ScopeHoistingPackager {
433
439
  wrapped.push(asset);
434
440
  } else if (
435
441
  (getFeatureFlag('inlineConstOptimisationFix') ||
436
- getFeatureFlag('applyScopeHoistingImprovement')) &&
442
+ this.useBothScopeHoistingImprovements) &&
437
443
  asset.meta.isConstantModule
438
444
  ) {
439
445
  constant.push(asset);
@@ -441,21 +447,36 @@ export class ScopeHoistingPackager {
441
447
  }
442
448
  });
443
449
 
444
- if (getFeatureFlag('applyScopeHoistingImprovement')) {
445
- // Make all entry assets wrapped, to avoid any top level hoisting
446
- for (let entryAsset of this.bundle.getEntryAssets()) {
447
- if (!this.wrappedAssets.has(entryAsset.id)) {
448
- this.wrappedAssets.add(entryAsset.id);
449
- wrapped.push(entryAsset);
450
+ if (this.useBothScopeHoistingImprovements) {
451
+ // Tracks which assets have been assigned to a wrap group
452
+ let assignedAssets = new Set<Asset>();
453
+
454
+ // In V2 scope hoisting, we iterate from the main entry, rather than
455
+ // wrapping the entry assets
456
+ if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
457
+ // Make all entry assets wrapped, to avoid any top level hoisting
458
+ for (let entryAsset of this.bundle.getEntryAssets()) {
459
+ if (!this.wrappedAssets.has(entryAsset.id)) {
460
+ this.wrappedAssets.add(entryAsset.id);
461
+ wrapped.push(entryAsset);
462
+ }
450
463
  }
451
464
  }
452
465
 
453
- // Tracks which assets have been assigned to a wrap group
454
- let assignedAssets = new Set<Asset>();
466
+ let moduleGroupParents = [...wrapped];
455
467
 
456
- for (let wrappedAsset of wrapped) {
468
+ if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
469
+ // The main entry needs to be check to find assets that would have gone in
470
+ // the top level scope
471
+ let mainEntry = this.bundle.getMainEntry();
472
+ if (mainEntry && !this.wrappedAssets.has(mainEntry.id)) {
473
+ moduleGroupParents.unshift(mainEntry);
474
+ }
475
+ }
476
+
477
+ for (let moduleGroupParentAsset of moduleGroupParents) {
457
478
  this.bundle.traverseAssets((asset, _, actions) => {
458
- if (asset === wrappedAsset) {
479
+ if (asset === moduleGroupParentAsset) {
459
480
  return;
460
481
  }
461
482
 
@@ -471,12 +492,16 @@ export class ScopeHoistingPackager {
471
492
  wrapped.push(asset);
472
493
  this.wrappedAssets.add(asset.id);
473
494
 
495
+ // This also needs to be added to the traversal so that we iterate
496
+ // it during this check.
497
+ moduleGroupParents.push(asset);
498
+
474
499
  actions.skipChildren();
475
500
  return;
476
501
  }
477
502
 
478
503
  assignedAssets.add(asset);
479
- }, wrappedAsset);
504
+ }, moduleGroupParentAsset);
480
505
  }
481
506
  } else {
482
507
  for (let wrappedAssetRoot of [...wrapped]) {
@@ -752,12 +777,18 @@ export class ScopeHoistingPackager {
752
777
  // after the dependency is declared. This handles the case where the resulting asset
753
778
  // is wrapped, but the dependency in this asset is not marked as wrapped. This means
754
779
  // that it was imported/required at the top-level, so its side effects should run immediately.
755
- let [res, lines] = this.getHoistedParcelRequires(
756
- asset,
757
- dep,
758
- resolved,
759
- );
780
+ let res = '';
781
+ let lines = 0;
760
782
  let map;
783
+
784
+ if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
785
+ [res, lines] = this.getHoistedParcelRequires(
786
+ asset,
787
+ dep,
788
+ resolved,
789
+ );
790
+ }
791
+
761
792
  if (
762
793
  this.bundle.hasAsset(resolved) &&
763
794
  !this.seenAssets.has(resolved.id)
@@ -766,7 +797,7 @@ export class ScopeHoistingPackager {
766
797
  // outside our parcelRequire.register wrapper. This is safe because all
767
798
  // assets referenced by this asset will also be wrapped. Otherwise, inline the
768
799
  // asset content where the import statement was.
769
- if (getFeatureFlag('applyScopeHoistingImprovement')) {
800
+ if (this.useBothScopeHoistingImprovements) {
770
801
  if (
771
802
  !resolved.meta.isConstantModule &&
772
803
  !this.wrappedAssets.has(resolved.id)
@@ -801,6 +832,16 @@ export class ScopeHoistingPackager {
801
832
  }
802
833
  }
803
834
 
835
+ if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
836
+ let [requiresCode, requiresLines] =
837
+ this.getHoistedParcelRequires(asset, dep, resolved);
838
+
839
+ if (requiresCode) {
840
+ res = requiresCode + '\n' + res;
841
+ lines += requiresLines + 1;
842
+ }
843
+ }
844
+
804
845
  // Push this asset's source mappings down by the number of lines in the dependency
805
846
  // plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
806
847
  if (sourceMap) {
@@ -1369,8 +1410,22 @@ ${code}
1369
1410
 
1370
1411
  if (hoisted) {
1371
1412
  this.needsPrelude = true;
1372
- res += '\n' + [...hoisted.values()].join('\n');
1373
- lineCount += hoisted.size;
1413
+
1414
+ if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
1415
+ let hoistedValues = [...hoisted.values()].filter(
1416
+ (val) => !this.seenHoistedRequires.has(val),
1417
+ );
1418
+
1419
+ for (let val of hoistedValues) {
1420
+ this.seenHoistedRequires.add(val);
1421
+ }
1422
+
1423
+ res += '\n' + hoistedValues.join('\n');
1424
+ lineCount += hoisted.size;
1425
+ } else {
1426
+ res += '\n' + [...hoisted.values()].join('\n');
1427
+ lineCount += hoisted.size;
1428
+ }
1374
1429
  }
1375
1430
 
1376
1431
  return [res, lineCount];