@atlaspack/packager-js 2.14.5-canary.18 → 2.14.5-canary.180

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.
@@ -1,5 +1,3 @@
1
- // @flow
2
-
3
1
  import type {
4
2
  Asset,
5
3
  BundleGraph,
@@ -15,6 +13,7 @@ import {
15
13
  relativeBundlePath,
16
14
  countLines,
17
15
  normalizeSeparators,
16
+ debugTools,
18
17
  } from '@atlaspack/utils';
19
18
  import SourceMap from '@parcel/source-map';
20
19
  import nullthrows from 'nullthrows';
@@ -25,11 +24,18 @@ import ThrowableDiagnostic, {
25
24
  import globals from 'globals';
26
25
  import path from 'path';
27
26
  import {getFeatureFlag} from '@atlaspack/feature-flags';
27
+ import {outdent} from 'outdent';
28
28
 
29
29
  import {ESMOutputFormat} from './ESMOutputFormat';
30
30
  import {CJSOutputFormat} from './CJSOutputFormat';
31
31
  import {GlobalOutputFormat} from './GlobalOutputFormat';
32
- import {prelude, helpers, bundleQueuePrelude, fnExpr} from './helpers';
32
+ import {
33
+ preludeOld,
34
+ preludeNew,
35
+ helpers,
36
+ bundleQueuePrelude,
37
+ fnExpr,
38
+ } from './helpers';
33
39
  import {
34
40
  replaceScriptDependencies,
35
41
  getSpecifier,
@@ -39,7 +45,6 @@ import {
39
45
 
40
46
  // General regex used to replace imports with the resolved code, references with resolutions,
41
47
  // and count the number of newlines in the file for source maps.
42
- //
43
48
  // For conditional bundling the only difference in this regex is adding `importCond` where we have `importAsync` etc..
44
49
  const REPLACEMENT_RE_CONDITIONAL =
45
50
  /\n|import\s+"([0-9a-f]{16,20}:.+?)";|(?:\$[0-9a-f]{16,20}\$exports)|(?:\$[0-9a-f]{16,20}\$(?:import|importAsync|require|importCond)\$[0-9a-f]+(?:\$[0-9a-f]+)?)/g;
@@ -55,6 +60,7 @@ const GLOBALS_BY_CONTEXT = {
55
60
  ...Object.keys(globals.serviceworker),
56
61
  ]),
57
62
  worklet: new Set([...BUILTINS]),
63
+ tesseract: new Set([...BUILTINS, ...Object.keys(globals.worker)]),
58
64
  node: new Set([...BUILTINS, ...Object.keys(globals.node)]),
59
65
  'electron-main': new Set([...BUILTINS, ...Object.keys(globals.node)]),
60
66
  'electron-renderer': new Set([
@@ -62,13 +68,13 @@ const GLOBALS_BY_CONTEXT = {
62
68
  ...Object.keys(globals.node),
63
69
  ...Object.keys(globals.browser),
64
70
  ]),
65
- };
71
+ } as const;
66
72
 
67
73
  const OUTPUT_FORMATS = {
68
74
  esmodule: ESMOutputFormat,
69
75
  commonjs: CJSOutputFormat,
70
76
  global: GlobalOutputFormat,
71
- };
77
+ } as const;
72
78
 
73
79
  export interface OutputFormat {
74
80
  buildBundlePrelude(): [string, number];
@@ -83,27 +89,37 @@ export class ScopeHoistingPackager {
83
89
  useAsyncBundleRuntime: boolean;
84
90
  outputFormat: OutputFormat;
85
91
  isAsyncBundle: boolean;
86
- globalNames: $ReadOnlySet<string>;
87
- assetOutputs: Map<string, {|code: string, map: ?Buffer|}>;
92
+ globalNames: ReadonlySet<string>;
93
+ // @ts-expect-error TS2564
94
+ assetOutputs: Map<
95
+ string,
96
+ {
97
+ code: string;
98
+ map: Buffer | null | undefined;
99
+ }
100
+ >;
88
101
  exportedSymbols: Map<
89
102
  string,
90
- {|
91
- asset: Asset,
92
- exportSymbol: string,
93
- local: string,
94
- exportAs: Array<string>,
95
- |},
103
+ {
104
+ asset: Asset;
105
+ exportSymbol: string;
106
+ local: string;
107
+ exportAs: Array<string>;
108
+ }
96
109
  > = new Map();
97
110
  externals: Map<string, Map<string, string>> = new Map();
98
111
  topLevelNames: Map<string, number> = new Map();
99
112
  seenAssets: Set<string> = new Set();
100
113
  wrappedAssets: Set<string> = new Set();
101
114
  hoistedRequires: Map<string, Map<string, string>> = new Map();
115
+ seenHoistedRequires: Set<string> = new Set();
102
116
  needsPrelude: boolean = false;
103
117
  usedHelpers: Set<string> = new Set();
104
118
  externalAssets: Set<Asset> = new Set();
105
- forceSkipWrapAssets: Array<string> = [];
106
119
  logger: PluginLogger;
120
+ useBothScopeHoistingImprovements: boolean =
121
+ getFeatureFlag('applyScopeHoistingImprovementV2') ||
122
+ getFeatureFlag('applyScopeHoistingImprovement');
107
123
 
108
124
  constructor(
109
125
  options: PluginOptions,
@@ -111,7 +127,6 @@ export class ScopeHoistingPackager {
111
127
  bundle: NamedBundle,
112
128
  parcelRequireName: string,
113
129
  useAsyncBundleRuntime: boolean,
114
- forceSkipWrapAssets: Array<string>,
115
130
  logger: PluginLogger,
116
131
  ) {
117
132
  this.options = options;
@@ -119,7 +134,6 @@ export class ScopeHoistingPackager {
119
134
  this.bundle = bundle;
120
135
  this.parcelRequireName = parcelRequireName;
121
136
  this.useAsyncBundleRuntime = useAsyncBundleRuntime;
122
- this.forceSkipWrapAssets = forceSkipWrapAssets ?? [];
123
137
  this.logger = logger;
124
138
 
125
139
  let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
@@ -128,13 +142,18 @@ export class ScopeHoistingPackager {
128
142
  this.isAsyncBundle =
129
143
  this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') &&
130
144
  !this.bundle.env.isIsolated() &&
131
- this.bundle.bundleBehavior !== 'isolated';
145
+ this.bundle.bundleBehavior !== 'isolated' &&
146
+ this.bundle.bundleBehavior !== 'inlineIsolated';
132
147
 
133
148
  this.globalNames = GLOBALS_BY_CONTEXT[bundle.env.context];
134
149
  }
135
150
 
136
- async package(): Promise<{|contents: string, map: ?SourceMap|}> {
137
- let wrappedAssets = await this.loadAssets();
151
+ async package(): Promise<{
152
+ contents: string;
153
+ map: SourceMap | null | undefined;
154
+ }> {
155
+ let {wrapped: wrappedAssets, constant: constantAssets} =
156
+ await this.loadAssets();
138
157
  this.buildExportedSymbols();
139
158
 
140
159
  // If building a library, the target is actually another bundler rather
@@ -155,9 +174,13 @@ export class ScopeHoistingPackager {
155
174
 
156
175
  let res = '';
157
176
  let lineCount = 0;
177
+ // @ts-expect-error TS7034
158
178
  let sourceMap = null;
159
- let processAsset = (asset) => {
179
+ let processAsset = (asset: Asset) => {
180
+ this.seenHoistedRequires.clear();
160
181
  let [content, map, lines] = this.visitAsset(asset);
182
+
183
+ // @ts-expect-error TS7005
161
184
  if (sourceMap && map) {
162
185
  sourceMap.addSourceMap(map, lineCount);
163
186
  } else if (this.bundle.env.sourceMap) {
@@ -168,6 +191,18 @@ export class ScopeHoistingPackager {
168
191
  lineCount += lines + 1;
169
192
  };
170
193
 
194
+ if (
195
+ getFeatureFlag('inlineConstOptimisationFix') ||
196
+ this.useBothScopeHoistingImprovements
197
+ ) {
198
+ // Write out all constant modules used by this bundle
199
+ for (let asset of constantAssets) {
200
+ if (!this.seenAssets.has(asset.id)) {
201
+ processAsset(asset);
202
+ }
203
+ }
204
+ }
205
+
171
206
  // Hoist wrapped asset to the top of the bundle to ensure that they are registered
172
207
  // before they are used.
173
208
  for (let asset of wrappedAssets) {
@@ -191,14 +226,28 @@ export class ScopeHoistingPackager {
191
226
  let [prelude, preludeLines] = this.buildBundlePrelude();
192
227
  res = prelude + res;
193
228
  lineCount += preludeLines;
229
+ // @ts-expect-error TS2339
194
230
  sourceMap?.offsetLines(1, preludeLines);
195
231
 
196
232
  let entries = this.bundle.getEntryAssets();
197
233
  let mainEntry = this.bundle.getMainEntry();
198
234
  if (this.isAsyncBundle) {
199
- // In async bundles we don't want the main entry to execute until we require it
200
- // as there might be dependencies in a sibling bundle that hasn't loaded yet.
201
- entries = entries.filter((a) => a.id !== mainEntry?.id);
235
+ if (
236
+ this.useBothScopeHoistingImprovements ||
237
+ getFeatureFlag('supportWebpackChunkName')
238
+ ) {
239
+ // Generally speaking, async bundles should not be executed on load, as
240
+ // they're just collections of assets that other assets require.
241
+ // However, there are some special cases where a runtime asset needs to be
242
+ // injected, but no other asset will require it (mostly the bundle
243
+ // manifest).
244
+ // In this case, those assets need to be required on load.
245
+ entries = entries.filter(
246
+ (a) => a.meta?.runtimeAssetRequiringExecutionOnLoad,
247
+ );
248
+ } else {
249
+ entries = entries.filter((a) => a.id !== mainEntry?.id);
250
+ }
202
251
  mainEntry = null;
203
252
  }
204
253
 
@@ -211,17 +260,20 @@ export class ScopeHoistingPackager {
211
260
  this.bundleGraph.getAssetPublicId(entry),
212
261
  )});\n`;
213
262
 
263
+ // @ts-expect-error TS2345
214
264
  let entryExports = entry.symbols.get('*')?.local;
215
265
 
216
266
  if (
217
267
  entryExports &&
218
268
  entry === mainEntry &&
269
+ // @ts-expect-error TS2345
219
270
  this.exportedSymbols.has(entryExports)
220
271
  ) {
221
272
  invariant(
222
273
  !needsBundleQueue,
223
274
  'Entry exports are not yet compaitble with async bundles',
224
275
  );
276
+ // @ts-expect-error TS2731
225
277
  res += `\nvar ${entryExports} = ${parcelRequire}`;
226
278
  } else {
227
279
  if (needsBundleQueue) {
@@ -265,6 +317,7 @@ export class ScopeHoistingPackager {
265
317
  this.parcelRequireName,
266
318
  );
267
319
  if (sourceMap && map) {
320
+ // @ts-expect-error TS2339
268
321
  sourceMap.addSourceMap(map, lineCount);
269
322
  }
270
323
  }
@@ -281,10 +334,7 @@ export class ScopeHoistingPackager {
281
334
 
282
335
  let hasConditionalReference = false;
283
336
  let isConditionalBundle = false;
284
- if (
285
- getFeatureFlag('conditionalBundlingApi') &&
286
- getFeatureFlag('conditionalBundlingAsyncRuntime')
287
- ) {
337
+ if (getFeatureFlag('conditionalBundlingApi')) {
288
338
  // If the bundle has a conditional bundle reference (has an importCond)
289
339
  hasConditionalReference =
290
340
  this.bundleGraph.getReferencedConditionalBundles(bundle).length > 0;
@@ -296,6 +346,7 @@ export class ScopeHoistingPackager {
296
346
  this.useAsyncBundleRuntime &&
297
347
  bundle.type === 'js' &&
298
348
  bundle.bundleBehavior !== 'inline' &&
349
+ bundle.bundleBehavior !== 'inlineIsolated' &&
299
350
  bundle.env.outputFormat === 'esmodule' &&
300
351
  !bundle.env.isIsolated() &&
301
352
  bundle.bundleBehavior !== 'isolated' &&
@@ -309,11 +360,8 @@ export class ScopeHoistingPackager {
309
360
  .filter((b) => this.shouldBundleQueue(b))
310
361
  .map((b) => b.publicId);
311
362
 
312
- const conditions = [];
313
- if (
314
- getFeatureFlag('conditionalBundlingApi') &&
315
- getFeatureFlag('conditionalBundlingAsyncRuntime')
316
- ) {
363
+ const conditions: Array<string> = [];
364
+ if (getFeatureFlag('conditionalBundlingApi')) {
317
365
  const conditionSet = this.bundleGraph
318
366
  .getConditionalBundleMapping()
319
367
  .get(bundle.id);
@@ -354,15 +402,21 @@ export class ScopeHoistingPackager {
354
402
  return `$parcel$global.rwr(${params.join(', ')});`;
355
403
  }
356
404
 
357
- async loadAssets(): Promise<Array<Asset>> {
405
+ async loadAssets(): Promise<{
406
+ wrapped: Array<Asset>;
407
+ constant: Array<Asset>;
408
+ }> {
358
409
  let queue = new PromiseQueue({maxConcurrent: 32});
359
- let wrapped = [];
410
+ let wrapped: Array<Asset> = [];
411
+ let constant: Array<Asset> = [];
412
+
360
413
  this.bundle.traverseAssets((asset) => {
361
414
  queue.add(async () => {
362
415
  let [code, map] = await Promise.all([
363
416
  asset.getCode(),
364
417
  this.bundle.env.sourceMap ? asset.getMapBuffer() : null,
365
418
  ]);
419
+
366
420
  return [asset.id, {code, map}];
367
421
  });
368
422
 
@@ -383,50 +437,115 @@ export class ScopeHoistingPackager {
383
437
  ) {
384
438
  this.wrappedAssets.add(asset.id);
385
439
  wrapped.push(asset);
440
+ } else if (
441
+ (getFeatureFlag('inlineConstOptimisationFix') ||
442
+ this.useBothScopeHoistingImprovements) &&
443
+ asset.meta.isConstantModule
444
+ ) {
445
+ constant.push(asset);
386
446
  }
387
447
  }
388
448
  });
389
449
 
390
- for (let wrappedAssetRoot of [...wrapped]) {
391
- this.bundle.traverseAssets((asset, _, actions) => {
392
- if (asset === wrappedAssetRoot) {
393
- return;
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
+ }
394
463
  }
464
+ }
395
465
 
396
- if (this.wrappedAssets.has(asset.id)) {
397
- actions.skipChildren();
398
- return;
399
- }
400
- // This prevents children of a wrapped asset also being wrapped - it's an "unsafe" optimisation
401
- // that should only be used when you know (or think you know) what you're doing.
402
- //
403
- // In particular this can force an async bundle to be scope hoisted where it previously would not be
404
- // due to the entry asset being wrapped.
405
- if (
406
- this.forceSkipWrapAssets.length > 0 &&
407
- this.forceSkipWrapAssets.some(
408
- (p) =>
409
- p === path.relative(this.options.projectRoot, asset.filePath),
410
- )
411
- ) {
412
- this.logger.verbose({
413
- message: `Force skipping wrapping of ${path.relative(
414
- this.options.projectRoot,
415
- asset.filePath,
416
- )}`,
417
- });
418
- actions.skipChildren();
419
- return;
420
- }
421
- if (!asset.meta.isConstantModule) {
422
- this.wrappedAssets.add(asset.id);
423
- wrapped.push(asset);
466
+ let moduleGroupParents = [...wrapped];
467
+
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);
424
474
  }
425
- }, wrappedAssetRoot);
475
+ }
476
+
477
+ for (let moduleGroupParentAsset of moduleGroupParents) {
478
+ this.bundle.traverseAssets((asset, _, actions) => {
479
+ if (asset === moduleGroupParentAsset) {
480
+ return;
481
+ }
482
+
483
+ if (this.wrappedAssets.has(asset.id)) {
484
+ actions.skipChildren();
485
+ return;
486
+ }
487
+
488
+ if (
489
+ !asset.meta.isConstantModule &&
490
+ (assignedAssets.has(asset) || this.isReExported(asset))
491
+ ) {
492
+ wrapped.push(asset);
493
+ this.wrappedAssets.add(asset.id);
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
+
499
+ actions.skipChildren();
500
+ return;
501
+ }
502
+
503
+ assignedAssets.add(asset);
504
+ }, moduleGroupParentAsset);
505
+ }
506
+ } else {
507
+ for (let wrappedAssetRoot of [...wrapped]) {
508
+ this.bundle.traverseAssets((asset, _, actions) => {
509
+ if (asset === wrappedAssetRoot) {
510
+ return;
511
+ }
512
+
513
+ if (this.wrappedAssets.has(asset.id)) {
514
+ actions.skipChildren();
515
+ return;
516
+ }
517
+
518
+ if (!asset.meta.isConstantModule) {
519
+ this.wrappedAssets.add(asset.id);
520
+ wrapped.push(asset);
521
+ }
522
+ }, wrappedAssetRoot);
523
+ }
426
524
  }
427
525
 
526
+ // @ts-expect-error TS2769
428
527
  this.assetOutputs = new Map(await queue.run());
429
- return wrapped;
528
+ return {wrapped, constant};
529
+ }
530
+
531
+ isReExported(asset: Asset): boolean {
532
+ let parentSymbols = this.bundleGraph
533
+ .getIncomingDependencies(asset)
534
+ .map((dep) => this.bundleGraph.getAssetWithDependency(dep))
535
+ .flatMap((parent) => {
536
+ if (parent == null) {
537
+ return [];
538
+ }
539
+ return this.bundleGraph.getExportedSymbols(parent, this.bundle);
540
+ });
541
+
542
+ let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
543
+
544
+ return assetSymbols.some((assetSymbol) =>
545
+ parentSymbols.some(
546
+ (parentSymbol) => parentSymbol.symbol === assetSymbol.symbol,
547
+ ),
548
+ );
430
549
  }
431
550
 
432
551
  buildExportedSymbols() {
@@ -440,6 +559,7 @@ export class ScopeHoistingPackager {
440
559
  // TODO: handle ESM exports of wrapped entry assets...
441
560
  let entry = this.bundle.getMainEntry();
442
561
  if (entry && !this.wrappedAssets.has(entry.id)) {
562
+ // @ts-expect-error TS2345
443
563
  let hasNamespace = entry.symbols.hasExportSymbol('*');
444
564
 
445
565
  for (let {
@@ -457,6 +577,7 @@ export class ScopeHoistingPackager {
457
577
  }
458
578
 
459
579
  let symbols = this.exportedSymbols.get(
580
+ // @ts-expect-error TS2345
460
581
  symbol === '*' ? nullthrows(entry.symbols.get('*')?.local) : symbol,
461
582
  )?.exportAs;
462
583
 
@@ -464,6 +585,7 @@ export class ScopeHoistingPackager {
464
585
  symbols = [];
465
586
  this.exportedSymbols.set(symbol, {
466
587
  asset,
588
+ // @ts-expect-error TS2322
467
589
  exportSymbol,
468
590
  local: symbol,
469
591
  exportAs: symbols,
@@ -474,6 +596,7 @@ export class ScopeHoistingPackager {
474
596
  exportAs = 'default';
475
597
  }
476
598
 
599
+ // @ts-expect-error TS2345
477
600
  symbols.push(exportAs);
478
601
  } else if (symbol === null) {
479
602
  // TODO `meta.exportsIdentifier[exportSymbol]` should be exported
@@ -519,7 +642,7 @@ export class ScopeHoistingPackager {
519
642
  return `${obj}[${JSON.stringify(property)}]`;
520
643
  }
521
644
 
522
- visitAsset(asset: Asset): [string, ?SourceMap, number] {
645
+ visitAsset(asset: Asset): [string, SourceMap | null | undefined, number] {
523
646
  invariant(!this.seenAssets.has(asset.id), 'Already visited asset');
524
647
  this.seenAssets.add(asset.id);
525
648
 
@@ -527,11 +650,15 @@ export class ScopeHoistingPackager {
527
650
  return this.buildAsset(asset, code, map);
528
651
  }
529
652
 
653
+ getAssetFilePath(asset: Asset): string {
654
+ return path.relative(this.options.projectRoot, asset.filePath);
655
+ }
656
+
530
657
  buildAsset(
531
658
  asset: Asset,
532
659
  code: string,
533
- map: ?Buffer,
534
- ): [string, ?SourceMap, number] {
660
+ map?: Buffer | null,
661
+ ): [string, SourceMap | null | undefined, number] {
535
662
  let shouldWrap = this.wrappedAssets.has(asset.id);
536
663
  let deps = this.bundleGraph.getDependencies(asset);
537
664
 
@@ -566,6 +693,7 @@ export class ScopeHoistingPackager {
566
693
  let [code, map, lines] = this.visitAsset(resolved);
567
694
  depCode += code + '\n';
568
695
  if (sourceMap && map) {
696
+ // @ts-expect-error TS2551
569
697
  sourceMap.addSourceMap(map, lineCount);
570
698
  }
571
699
  lineCount += lines + 1;
@@ -602,7 +730,9 @@ export class ScopeHoistingPackager {
602
730
  code += append;
603
731
 
604
732
  let lineCount = 0;
605
- let depContent = [];
733
+ // @ts-expect-error TS2552
734
+ let depContent: Array<[string, NodeSourceMap | null | undefined, number]> =
735
+ [];
606
736
  if (depMap.size === 0 && replacements.size === 0) {
607
737
  // If there are no dependencies or replacements, use a simple function to count the number of lines.
608
738
  lineCount = countLines(code) - 1;
@@ -647,12 +777,18 @@ export class ScopeHoistingPackager {
647
777
  // after the dependency is declared. This handles the case where the resulting asset
648
778
  // is wrapped, but the dependency in this asset is not marked as wrapped. This means
649
779
  // that it was imported/required at the top-level, so its side effects should run immediately.
650
- let [res, lines] = this.getHoistedParcelRequires(
651
- asset,
652
- dep,
653
- resolved,
654
- );
780
+ let res = '';
781
+ let lines = 0;
655
782
  let map;
783
+
784
+ if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
785
+ [res, lines] = this.getHoistedParcelRequires(
786
+ asset,
787
+ dep,
788
+ resolved,
789
+ );
790
+ }
791
+
656
792
  if (
657
793
  this.bundle.hasAsset(resolved) &&
658
794
  !this.seenAssets.has(resolved.id)
@@ -661,13 +797,48 @@ export class ScopeHoistingPackager {
661
797
  // outside our parcelRequire.register wrapper. This is safe because all
662
798
  // assets referenced by this asset will also be wrapped. Otherwise, inline the
663
799
  // asset content where the import statement was.
664
- if (shouldWrap) {
665
- depContent.push(this.visitAsset(resolved));
800
+ if (this.useBothScopeHoistingImprovements) {
801
+ if (
802
+ !resolved.meta.isConstantModule &&
803
+ !this.wrappedAssets.has(resolved.id)
804
+ ) {
805
+ let [depCode, depMap, depLines] =
806
+ this.visitAsset(resolved);
807
+ if (debugTools['asset-file-names-in-output']) {
808
+ let resolvedPath = this.getAssetFilePath(resolved);
809
+ res = outdent`
810
+ /* Scope hoisted asset: ${resolvedPath} */
811
+ ${depCode}
812
+ /* End: ${resolvedPath} */
813
+ ${res}
814
+ `;
815
+ lines += 3 + depLines;
816
+ } else {
817
+ res = depCode + '\n' + res;
818
+ lines += 1 + depLines;
819
+ }
820
+ map = depMap;
821
+ }
666
822
  } else {
667
- let [depCode, depMap, depLines] = this.visitAsset(resolved);
668
- res = depCode + '\n' + res;
669
- lines += 1 + depLines;
670
- map = depMap;
823
+ if (shouldWrap) {
824
+ depContent.push(this.visitAsset(resolved));
825
+ } else {
826
+ let [depCode, depMap, depLines] =
827
+ this.visitAsset(resolved);
828
+ res = depCode + '\n' + res;
829
+ lines += 1 + depLines;
830
+ map = depMap;
831
+ }
832
+ }
833
+ }
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;
671
842
  }
672
843
  }
673
844
 
@@ -679,6 +850,7 @@ export class ScopeHoistingPackager {
679
850
  }
680
851
 
681
852
  if (map) {
853
+ // @ts-expect-error TS2551
682
854
  sourceMap.addSourceMap(map, lineCount);
683
855
  }
684
856
  }
@@ -726,10 +898,16 @@ ${code}
726
898
 
727
899
  lineCount += 2;
728
900
 
901
+ if (debugTools['asset-file-names-in-output']) {
902
+ code = `/* ${this.getAssetFilePath(asset)} */\n` + code;
903
+ lineCount += 1;
904
+ }
905
+
729
906
  for (let [depCode, map, lines] of depContent) {
730
907
  if (!depCode) continue;
731
908
  code += depCode + '\n';
732
909
  if (sourceMap && map) {
910
+ // @ts-expect-error TS2551
733
911
  sourceMap.addSourceMap(map, lineCount);
734
912
  }
735
913
  lineCount += lines + 1;
@@ -812,10 +990,12 @@ ${code}
812
990
  }
813
991
 
814
992
  for (let [imported, {local}] of dep.symbols) {
993
+ // @ts-expect-error TS2367
815
994
  if (local === '*') {
816
995
  continue;
817
996
  }
818
997
 
998
+ // @ts-expect-error TS2345
819
999
  let symbol = this.getSymbolResolution(asset, resolved, imported, dep);
820
1000
  replacements.set(
821
1001
  local,
@@ -852,6 +1032,7 @@ ${code}
852
1032
  (this.bundle.env.outputFormat === 'commonjs' &&
853
1033
  asset === this.bundle.getMainEntry())
854
1034
  ) {
1035
+ // @ts-expect-error TS2345
855
1036
  let exportsName = asset.symbols.get('*')?.local || `$${assetId}$exports`;
856
1037
  replacements.set(exportsName, 'module.exports');
857
1038
  }
@@ -895,8 +1076,11 @@ ${code}
895
1076
 
896
1077
  for (let [imported, {local}] of dep.symbols) {
897
1078
  // If already imported, just add the already renamed variable to the mapping.
1079
+ // @ts-expect-error TS2345
898
1080
  let renamed = external.get(imported);
1081
+ // @ts-expect-error TS2367
899
1082
  if (renamed && local !== '*' && replacements) {
1083
+ // @ts-expect-error TS2345
900
1084
  replacements.set(local, renamed);
901
1085
  continue;
902
1086
  }
@@ -908,7 +1092,9 @@ ${code}
908
1092
  if (!renamed) {
909
1093
  if (referencedBundle) {
910
1094
  let entry = nullthrows(referencedBundle.getMainEntry());
1095
+ // @ts-expect-error TS2322
911
1096
  renamed =
1097
+ // @ts-expect-error TS2345
912
1098
  entry.symbols.get('*')?.local ??
913
1099
  `$${String(entry.meta.id)}$exports`;
914
1100
  } else {
@@ -917,13 +1103,17 @@ ${code}
917
1103
  );
918
1104
  }
919
1105
 
1106
+ // @ts-expect-error TS2345
920
1107
  external.set('*', renamed);
921
1108
  }
922
1109
 
1110
+ // @ts-expect-error TS2367
923
1111
  if (local !== '*' && replacements) {
924
1112
  let replacement;
1113
+ // @ts-expect-error TS2367
925
1114
  if (imported === '*') {
926
1115
  replacement = renamed;
1116
+ // @ts-expect-error TS2367
927
1117
  } else if (imported === 'default') {
928
1118
  let needsDefaultInterop = true;
929
1119
  if (referencedBundle) {
@@ -937,36 +1127,44 @@ ${code}
937
1127
  replacement = `${renamed}.default`;
938
1128
  }
939
1129
  } else {
1130
+ // @ts-expect-error TS2345
940
1131
  replacement = this.getPropertyAccess(renamed, imported);
941
1132
  }
942
1133
 
1134
+ // @ts-expect-error TS2345
943
1135
  replacements.set(local, replacement);
944
1136
  }
945
1137
  } else {
946
1138
  let property;
947
1139
  if (referencedBundle) {
948
1140
  let entry = nullthrows(referencedBundle.getMainEntry());
1141
+ // @ts-expect-error TS2345
949
1142
  if (entry.symbols.hasExportSymbol('*')) {
950
1143
  // If importing * and the referenced module has a * export (e.g. CJS), use default instead.
951
1144
  // This mirrors the logic in buildExportedSymbols.
952
1145
  property = imported;
1146
+ // @ts-expect-error TS2322
953
1147
  imported =
954
1148
  referencedBundle?.env.outputFormat === 'esmodule'
955
1149
  ? 'default'
956
1150
  : '*';
957
1151
  } else {
1152
+ // @ts-expect-error TS2367
958
1153
  if (imported === '*') {
959
1154
  let exportedSymbols = this.bundleGraph.getExportedSymbols(entry);
1155
+ // @ts-expect-error TS2367
960
1156
  if (local === '*') {
961
1157
  // Re-export all symbols.
962
1158
  for (let exported of exportedSymbols) {
963
1159
  if (exported.symbol) {
1160
+ // @ts-expect-error TS2345
964
1161
  external.set(exported.exportSymbol, exported.symbol);
965
1162
  }
966
1163
  }
967
1164
  continue;
968
1165
  }
969
1166
  }
1167
+ // @ts-expect-error TS2322
970
1168
  renamed = this.bundleGraph.getSymbolResolution(
971
1169
  entry,
972
1170
  imported,
@@ -979,30 +1177,40 @@ ${code}
979
1177
  // are deduplicated. We have to prefix the imported name with the bundle id so that
980
1178
  // local variables do not shadow it.
981
1179
  if (!renamed) {
1180
+ // @ts-expect-error TS2345
982
1181
  if (this.exportedSymbols.has(local)) {
1182
+ // @ts-expect-error TS2322
983
1183
  renamed = local;
1184
+ // @ts-expect-error TS2367
984
1185
  } else if (imported === 'default' || imported === '*') {
985
1186
  renamed = this.getTopLevelName(
986
1187
  `$${this.bundle.publicId}$${specifier}`,
987
1188
  );
988
1189
  } else {
989
1190
  renamed = this.getTopLevelName(
1191
+ // @ts-expect-error TS2731
990
1192
  `$${this.bundle.publicId}$${imported}`,
991
1193
  );
992
1194
  }
993
1195
  }
994
1196
 
1197
+ // @ts-expect-error TS2345
995
1198
  external.set(imported, renamed);
1199
+ // @ts-expect-error TS2367
996
1200
  if (local !== '*' && replacements) {
997
1201
  let replacement = renamed;
1202
+ // @ts-expect-error TS2367
998
1203
  if (property === '*') {
999
1204
  replacement = renamed;
1205
+ // @ts-expect-error TS2367
1000
1206
  } else if (property === 'default') {
1001
1207
  replacement = `($parcel$interopDefault(${renamed}))`;
1002
1208
  this.usedHelpers.add('$parcel$interopDefault');
1003
1209
  } else if (property) {
1210
+ // @ts-expect-error TS2345
1004
1211
  replacement = this.getPropertyAccess(renamed, property);
1005
1212
  }
1213
+ // @ts-expect-error TS2345
1006
1214
  replacements.set(local, replacement);
1007
1215
  }
1008
1216
  }
@@ -1041,6 +1249,7 @@ ${code}
1041
1249
  asset: resolvedAsset,
1042
1250
  exportSymbol,
1043
1251
  symbol,
1252
+ // @ts-expect-error TS2345
1044
1253
  } = this.bundleGraph.getSymbolResolution(resolved, imported, this.bundle);
1045
1254
 
1046
1255
  if (
@@ -1099,8 +1308,11 @@ ${code}
1099
1308
  staticExports &&
1100
1309
  !isWrapped &&
1101
1310
  (dep?.meta.kind === 'Import' || dep?.meta.kind === 'Export') &&
1311
+ // @ts-expect-error TS2345
1102
1312
  resolvedAsset.symbols.hasExportSymbol('*') &&
1313
+ // @ts-expect-error TS2345
1103
1314
  resolvedAsset.symbols.hasExportSymbol('default') &&
1315
+ // @ts-expect-error TS2345
1104
1316
  !resolvedAsset.symbols.hasExportSymbol('__esModule');
1105
1317
 
1106
1318
  // Find the namespace object for the resolved module. If wrapped and this
@@ -1116,7 +1328,9 @@ ${code}
1116
1328
  } else if (isWrapped && dep) {
1117
1329
  obj = `$${publicId}`;
1118
1330
  } else {
1331
+ // @ts-expect-error TS2345
1119
1332
  obj = resolvedAsset.symbols.get('*')?.local || `$${assetId}$exports`;
1333
+ // @ts-expect-error TS2345
1120
1334
  obj = replacements?.get(obj) || obj;
1121
1335
  }
1122
1336
 
@@ -1129,6 +1343,7 @@ ${code}
1129
1343
  // Directly use module.exports for wrapped assets importing themselves.
1130
1344
  return 'module.exports';
1131
1345
  } else {
1346
+ // @ts-expect-error TS2322
1132
1347
  return obj;
1133
1348
  }
1134
1349
  } else if (
@@ -1143,17 +1358,21 @@ ${code}
1143
1358
  if (
1144
1359
  (!dep || kind === 'Import' || kind === 'Export') &&
1145
1360
  exportSymbol === 'default' &&
1361
+ // @ts-expect-error TS2345
1146
1362
  resolvedAsset.symbols.hasExportSymbol('*') &&
1147
1363
  this.needsDefaultInterop(resolvedAsset)
1148
1364
  ) {
1149
1365
  this.usedHelpers.add('$parcel$interopDefault');
1366
+ // @ts-expect-error TS2731
1150
1367
  return `(/*@__PURE__*/$parcel$interopDefault(${obj}))`;
1151
1368
  } else {
1369
+ // @ts-expect-error TS2345
1152
1370
  return this.getPropertyAccess(obj, exportSymbol);
1153
1371
  }
1154
1372
  } else if (!symbol) {
1155
1373
  invariant(false, 'Asset was skipped or not found.');
1156
1374
  } else {
1375
+ // @ts-expect-error TS2322
1157
1376
  return replacements?.get(symbol) || symbol;
1158
1377
  }
1159
1378
  }
@@ -1191,8 +1410,22 @@ ${code}
1191
1410
 
1192
1411
  if (hoisted) {
1193
1412
  this.needsPrelude = true;
1194
- res += '\n' + [...hoisted.values()].join('\n');
1195
- 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
+ }
1196
1429
  }
1197
1430
 
1198
1431
  return [res, lineCount];
@@ -1216,38 +1449,56 @@ ${code}
1216
1449
  // If there's no __esModule flag, and default is a used symbol, we need
1217
1450
  // to insert an interop helper.
1218
1451
  let defaultInterop =
1452
+ // @ts-expect-error TS2345
1219
1453
  asset.symbols.hasExportSymbol('*') &&
1454
+ // @ts-expect-error TS2345
1220
1455
  usedSymbols.has('default') &&
1456
+ // @ts-expect-error TS2345
1221
1457
  !asset.symbols.hasExportSymbol('__esModule');
1222
1458
 
1223
- let usedNamespace =
1224
- // If the asset has * in its used symbols, we might need the exports namespace.
1225
- // The one case where this isn't true is in ESM library entries, where the only
1226
- // dependency on * is the entry dependency. In this case, we will use ESM exports
1227
- // instead of the namespace object.
1228
- (usedSymbols.has('*') &&
1229
- (this.bundle.env.outputFormat !== 'esmodule' ||
1230
- !this.bundle.env.isLibrary ||
1231
- asset !== this.bundle.getMainEntry() ||
1232
- this.bundleGraph
1233
- .getIncomingDependencies(asset)
1234
- .some(
1459
+ let usedNamespace;
1460
+ if (
1461
+ getFeatureFlag('inlineConstOptimisationFix') &&
1462
+ asset.meta.isConstantModule
1463
+ ) {
1464
+ // Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
1465
+ usedNamespace = this.bundleGraph.getIncomingDependencies(asset).some(
1466
+ (dep) =>
1467
+ this.bundle.hasDependency(dep) &&
1468
+ // @ts-expect-error TS2345
1469
+ nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
1470
+ );
1471
+ } else {
1472
+ usedNamespace =
1473
+ // If the asset has * in its used symbols, we might need the exports namespace.
1474
+ // The one case where this isn't true is in ESM library entries, where the only
1475
+ // dependency on * is the entry dependency. In this case, we will use ESM exports
1476
+ // instead of the namespace object.
1477
+ // @ts-expect-error TS2345
1478
+ (usedSymbols.has('*') &&
1479
+ (this.bundle.env.outputFormat !== 'esmodule' ||
1480
+ !this.bundle.env.isLibrary ||
1481
+ asset !== this.bundle.getMainEntry() ||
1482
+ this.bundleGraph.getIncomingDependencies(asset).some(
1235
1483
  (dep) =>
1236
1484
  !dep.isEntry &&
1237
1485
  this.bundle.hasDependency(dep) &&
1486
+ // @ts-expect-error TS2345
1238
1487
  nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
1239
1488
  ))) ||
1240
- // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
1241
- // we fallback on the namespace object.
1242
- (asset.symbols.hasExportSymbol('*') &&
1243
- [...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
1244
- // If the exports has this asset's namespace (e.g. ESM output from CJS input),
1245
- // include the namespace object for the default export.
1246
- this.exportedSymbols.has(`$${assetId}$exports`) ||
1247
- // CommonJS library bundle entries always need a namespace.
1248
- (this.bundle.env.isLibrary &&
1249
- this.bundle.env.outputFormat === 'commonjs' &&
1250
- asset === this.bundle.getMainEntry());
1489
+ // If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
1490
+ // we fallback on the namespace object.
1491
+ // @ts-expect-error TS2345
1492
+ (asset.symbols.hasExportSymbol('*') &&
1493
+ [...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
1494
+ // If the exports has this asset's namespace (e.g. ESM output from CJS input),
1495
+ // include the namespace object for the default export.
1496
+ this.exportedSymbols.has(`$${assetId}$exports`) ||
1497
+ // CommonJS library bundle entries always need a namespace.
1498
+ (this.bundle.env.isLibrary &&
1499
+ this.bundle.env.outputFormat === 'commonjs' &&
1500
+ asset === this.bundle.getMainEntry());
1501
+ }
1251
1502
 
1252
1503
  // If the asset doesn't have static exports, should wrap, the namespace is used,
1253
1504
  // or we need default interop, then we need to synthesize a namespace object for
@@ -1274,6 +1525,7 @@ ${code}
1274
1525
  // Insert the __esModule interop flag for this module if it has a `default` export
1275
1526
  // and the namespace symbol is used.
1276
1527
  // TODO: only if required by CJS?
1528
+ // @ts-expect-error TS2345
1277
1529
  if (asset.symbols.hasExportSymbol('default') && usedSymbols.has('*')) {
1278
1530
  prepend += `\n$parcel$defineInteropFlag($${assetId}$exports);\n`;
1279
1531
  prependLineCount += 2;
@@ -1292,6 +1544,7 @@ ${code}
1292
1544
  let isWrapped = resolved && resolved.meta.shouldWrap;
1293
1545
 
1294
1546
  for (let [imported, {local}] of dep.symbols) {
1547
+ // @ts-expect-error TS2367
1295
1548
  if (imported === '*' && local === '*') {
1296
1549
  if (!resolved) {
1297
1550
  // Re-exporting an external module. This should have already been handled in buildReplacements.
@@ -1309,9 +1562,11 @@ ${code}
1309
1562
  if (
1310
1563
  isWrapped ||
1311
1564
  resolved.meta.staticExports === false ||
1565
+ // @ts-expect-error TS2345
1312
1566
  nullthrows(this.bundleGraph.getUsedSymbols(resolved)).has('*') ||
1313
1567
  // an empty asset
1314
1568
  (!resolved.meta.hasCJSExports &&
1569
+ // @ts-expect-error TS2345
1315
1570
  resolved.symbols.hasExportSymbol('*'))
1316
1571
  ) {
1317
1572
  let obj = this.getSymbolResolution(
@@ -1328,7 +1583,9 @@ ${code}
1328
1583
  this.bundleGraph.getUsedSymbols(dep),
1329
1584
  )) {
1330
1585
  if (
1586
+ // @ts-expect-error TS2367
1331
1587
  symbol === 'default' || // `export * as ...` does not include the default export
1588
+ // @ts-expect-error TS2367
1332
1589
  symbol === '__esModule'
1333
1590
  ) {
1334
1591
  continue;
@@ -1337,6 +1594,7 @@ ${code}
1337
1594
  let resolvedSymbol = this.getSymbolResolution(
1338
1595
  asset,
1339
1596
  resolved,
1597
+ // @ts-expect-error TS2345
1340
1598
  symbol,
1341
1599
  undefined,
1342
1600
  replacements,
@@ -1362,6 +1620,7 @@ ${code}
1362
1620
  // re-exported symbols rather than only symbols declared in this asset.
1363
1621
  let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
1364
1622
  let usedExports = [...asset.symbols.exportSymbols()].filter((symbol) => {
1623
+ // @ts-expect-error TS2367
1365
1624
  if (symbol === '*') {
1366
1625
  return false;
1367
1626
  }
@@ -1378,6 +1637,7 @@ ${code}
1378
1637
  // No used symbols available for the asset, make sure we keep all of them
1379
1638
  if (!symbols) return false;
1380
1639
 
1640
+ // @ts-expect-error TS2345
1381
1641
  return !symbols.has(symbol) && !symbols.has('*');
1382
1642
  });
1383
1643
  return !unused;
@@ -1393,6 +1653,7 @@ ${code}
1393
1653
  let resolved = this.getSymbolResolution(
1394
1654
  asset,
1395
1655
  asset,
1656
+ // @ts-expect-error TS2345
1396
1657
  exp,
1397
1658
  undefined,
1398
1659
  replacements,
@@ -1448,8 +1709,10 @@ ${code}
1448
1709
  }
1449
1710
 
1450
1711
  for (let helper of this.usedHelpers) {
1712
+ // @ts-expect-error TS7053
1451
1713
  let currentHelper = helpers[helper];
1452
1714
  if (typeof currentHelper === 'function') {
1715
+ // @ts-expect-error TS7053
1453
1716
  currentHelper = helpers[helper](this.bundle.env);
1454
1717
  }
1455
1718
  res += currentHelper;
@@ -1470,11 +1733,14 @@ ${code}
1470
1733
  .some((g) => this.bundleGraph.isEntryBundleGroup(g)) ||
1471
1734
  this.bundle.env.isIsolated() ||
1472
1735
  this.bundle.bundleBehavior === 'isolated' ||
1736
+ this.bundle.bundleBehavior === 'inlineIsolated' ||
1473
1737
  // Conditional deps may be loaded before entrypoints on the server
1474
1738
  this.hasConditionalDependency();
1475
1739
 
1476
1740
  if (mightBeFirstJS) {
1477
- let preludeCode = prelude(this.parcelRequireName);
1741
+ let preludeCode = (
1742
+ getFeatureFlag('useNewPrelude') ? preludeNew : preludeOld
1743
+ )(this.parcelRequireName);
1478
1744
  res += preludeCode;
1479
1745
  if (enableSourceMaps) {
1480
1746
  lines += countLines(preludeCode) - 1;
@@ -1498,7 +1764,11 @@ ${code}
1498
1764
  }
1499
1765
 
1500
1766
  // Add importScripts for sibling bundles in workers.
1501
- if (this.bundle.env.isWorker() || this.bundle.env.isWorklet()) {
1767
+ if (
1768
+ this.bundle.env.isWorker() ||
1769
+ this.bundle.env.isTesseract() ||
1770
+ this.bundle.env.isWorklet()
1771
+ ) {
1502
1772
  let importScripts = '';
1503
1773
  let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
1504
1774
  for (let b of bundles) {
@@ -1522,7 +1792,9 @@ ${code}
1522
1792
 
1523
1793
  needsDefaultInterop(asset: Asset): boolean {
1524
1794
  if (
1795
+ // @ts-expect-error TS2345
1525
1796
  asset.symbols.hasExportSymbol('*') &&
1797
+ // @ts-expect-error TS2345
1526
1798
  !asset.symbols.hasExportSymbol('default')
1527
1799
  ) {
1528
1800
  return true;