@atlaspack/packager-js 2.14.5-canary.26 → 2.14.5-canary.262
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 +407 -0
- package/dist/CJSOutputFormat.js +34 -0
- package/dist/DevPackager.js +202 -0
- package/dist/ESMOutputFormat.js +102 -0
- package/dist/GlobalOutputFormat.js +18 -0
- package/dist/ScopeHoistingPackager.js +1369 -0
- package/dist/helpers.js +170 -0
- package/dist/index.js +120 -0
- package/dist/utils.js +60 -0
- package/lib/DevPackager.js +28 -3
- package/lib/ESMOutputFormat.js +1 -1
- package/lib/ScopeHoistingPackager.js +265 -107
- package/lib/dev-prelude.js +6 -6
- package/lib/helpers.js +38 -3
- package/lib/index.js +35 -9
- package/lib/types/CJSOutputFormat.d.ts +7 -0
- package/lib/types/DevPackager.d.ts +15 -0
- package/lib/types/ESMOutputFormat.d.ts +7 -0
- package/lib/types/GlobalOutputFormat.d.ts +7 -0
- package/lib/types/ScopeHoistingPackager.d.ts +71 -0
- package/lib/types/helpers.d.ts +12 -0
- package/lib/types/index.d.ts +3 -0
- package/lib/types/utils.d.ts +6 -0
- package/package.json +17 -12
- package/src/{CJSOutputFormat.js → CJSOutputFormat.ts} +0 -1
- package/src/{DevPackager.js → DevPackager.ts} +34 -7
- package/src/{ESMOutputFormat.js → ESMOutputFormat.ts} +3 -4
- package/src/{GlobalOutputFormat.js → GlobalOutputFormat.ts} +0 -1
- package/src/{ScopeHoistingPackager.js → ScopeHoistingPackager.ts} +427 -180
- package/src/dev-prelude.js +6 -6
- package/src/{helpers.js → helpers.ts} +37 -3
- package/src/{index.js → index.ts} +64 -38
- package/src/{utils.js → utils.ts} +1 -2
- package/tsconfig.json +27 -0
- package/tsconfig.tsbuildinfo +1 -0
|
@@ -1,5 +1,3 @@
|
|
|
1
|
-
// @flow
|
|
2
|
-
|
|
3
1
|
import type {
|
|
4
2
|
Asset,
|
|
5
3
|
BundleGraph,
|
|
@@ -15,6 +13,8 @@ import {
|
|
|
15
13
|
relativeBundlePath,
|
|
16
14
|
countLines,
|
|
17
15
|
normalizeSeparators,
|
|
16
|
+
debugTools,
|
|
17
|
+
globToRegex,
|
|
18
18
|
} from '@atlaspack/utils';
|
|
19
19
|
import SourceMap from '@parcel/source-map';
|
|
20
20
|
import nullthrows from 'nullthrows';
|
|
@@ -25,11 +25,18 @@ import ThrowableDiagnostic, {
|
|
|
25
25
|
import globals from 'globals';
|
|
26
26
|
import path from 'path';
|
|
27
27
|
import {getFeatureFlag} from '@atlaspack/feature-flags';
|
|
28
|
+
import {outdent} from 'outdent';
|
|
28
29
|
|
|
29
30
|
import {ESMOutputFormat} from './ESMOutputFormat';
|
|
30
31
|
import {CJSOutputFormat} from './CJSOutputFormat';
|
|
31
32
|
import {GlobalOutputFormat} from './GlobalOutputFormat';
|
|
32
|
-
import {
|
|
33
|
+
import {
|
|
34
|
+
preludeOld,
|
|
35
|
+
preludeNew,
|
|
36
|
+
helpers,
|
|
37
|
+
bundleQueuePrelude,
|
|
38
|
+
fnExpr,
|
|
39
|
+
} from './helpers';
|
|
33
40
|
import {
|
|
34
41
|
replaceScriptDependencies,
|
|
35
42
|
getSpecifier,
|
|
@@ -39,7 +46,6 @@ import {
|
|
|
39
46
|
|
|
40
47
|
// General regex used to replace imports with the resolved code, references with resolutions,
|
|
41
48
|
// and count the number of newlines in the file for source maps.
|
|
42
|
-
//
|
|
43
49
|
// For conditional bundling the only difference in this regex is adding `importCond` where we have `importAsync` etc..
|
|
44
50
|
const REPLACEMENT_RE_CONDITIONAL =
|
|
45
51
|
/\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 +61,7 @@ const GLOBALS_BY_CONTEXT = {
|
|
|
55
61
|
...Object.keys(globals.serviceworker),
|
|
56
62
|
]),
|
|
57
63
|
worklet: new Set([...BUILTINS]),
|
|
64
|
+
tesseract: new Set([...BUILTINS, ...Object.keys(globals.worker)]),
|
|
58
65
|
node: new Set([...BUILTINS, ...Object.keys(globals.node)]),
|
|
59
66
|
'electron-main': new Set([...BUILTINS, ...Object.keys(globals.node)]),
|
|
60
67
|
'electron-renderer': new Set([
|
|
@@ -62,19 +69,28 @@ const GLOBALS_BY_CONTEXT = {
|
|
|
62
69
|
...Object.keys(globals.node),
|
|
63
70
|
...Object.keys(globals.browser),
|
|
64
71
|
]),
|
|
65
|
-
};
|
|
72
|
+
} as const;
|
|
66
73
|
|
|
67
74
|
const OUTPUT_FORMATS = {
|
|
68
75
|
esmodule: ESMOutputFormat,
|
|
69
76
|
commonjs: CJSOutputFormat,
|
|
70
77
|
global: GlobalOutputFormat,
|
|
71
|
-
};
|
|
78
|
+
} as const;
|
|
72
79
|
|
|
73
80
|
export interface OutputFormat {
|
|
74
81
|
buildBundlePrelude(): [string, number];
|
|
75
82
|
buildBundlePostlude(): [string, number];
|
|
76
83
|
}
|
|
77
84
|
|
|
85
|
+
export type PackageResult = {
|
|
86
|
+
contents: string;
|
|
87
|
+
map: SourceMap | null | undefined;
|
|
88
|
+
scopeHoistingStats?: {
|
|
89
|
+
totalAssets: number;
|
|
90
|
+
wrappedAssets: number;
|
|
91
|
+
};
|
|
92
|
+
};
|
|
93
|
+
|
|
78
94
|
export class ScopeHoistingPackager {
|
|
79
95
|
options: PluginOptions;
|
|
80
96
|
bundleGraph: BundleGraph<NamedBundle>;
|
|
@@ -83,27 +99,38 @@ export class ScopeHoistingPackager {
|
|
|
83
99
|
useAsyncBundleRuntime: boolean;
|
|
84
100
|
outputFormat: OutputFormat;
|
|
85
101
|
isAsyncBundle: boolean;
|
|
86
|
-
globalNames:
|
|
87
|
-
|
|
102
|
+
globalNames: ReadonlySet<string>;
|
|
103
|
+
manualStaticBindingExports: RegExp[] | null;
|
|
104
|
+
assetOutputs: Map<
|
|
105
|
+
Asset,
|
|
106
|
+
{
|
|
107
|
+
code: string;
|
|
108
|
+
map: Buffer | null | undefined;
|
|
109
|
+
}
|
|
110
|
+
> = new Map();
|
|
88
111
|
exportedSymbols: Map<
|
|
89
112
|
string,
|
|
90
|
-
{
|
|
91
|
-
asset: Asset
|
|
92
|
-
exportSymbol: string
|
|
93
|
-
local: string
|
|
94
|
-
exportAs: Array<string
|
|
95
|
-
|
|
113
|
+
{
|
|
114
|
+
asset: Asset;
|
|
115
|
+
exportSymbol: string;
|
|
116
|
+
local: string;
|
|
117
|
+
exportAs: Array<string>;
|
|
118
|
+
}
|
|
96
119
|
> = new Map();
|
|
97
120
|
externals: Map<string, Map<string, string>> = new Map();
|
|
98
121
|
topLevelNames: Map<string, number> = new Map();
|
|
99
|
-
seenAssets: Set<
|
|
100
|
-
wrappedAssets: Set<
|
|
101
|
-
|
|
122
|
+
seenAssets: Set<Asset> = new Set();
|
|
123
|
+
wrappedAssets: Set<Asset> = new Set();
|
|
124
|
+
constantAssets: Set<Asset> = new Set();
|
|
125
|
+
hoistedRequires: Map<Dependency, Map<Asset, string>> = new Map();
|
|
126
|
+
seenHoistedRequires: Set<string> = new Set();
|
|
102
127
|
needsPrelude: boolean = false;
|
|
103
128
|
usedHelpers: Set<string> = new Set();
|
|
104
129
|
externalAssets: Set<Asset> = new Set();
|
|
105
|
-
forceSkipWrapAssets: Array<string> = [];
|
|
106
130
|
logger: PluginLogger;
|
|
131
|
+
useBothScopeHoistingImprovements: boolean =
|
|
132
|
+
getFeatureFlag('applyScopeHoistingImprovementV2') ||
|
|
133
|
+
getFeatureFlag('applyScopeHoistingImprovement');
|
|
107
134
|
|
|
108
135
|
constructor(
|
|
109
136
|
options: PluginOptions,
|
|
@@ -111,7 +138,7 @@ export class ScopeHoistingPackager {
|
|
|
111
138
|
bundle: NamedBundle,
|
|
112
139
|
parcelRequireName: string,
|
|
113
140
|
useAsyncBundleRuntime: boolean,
|
|
114
|
-
|
|
141
|
+
manualStaticBindingExports: string[] | null,
|
|
115
142
|
logger: PluginLogger,
|
|
116
143
|
) {
|
|
117
144
|
this.options = options;
|
|
@@ -119,7 +146,8 @@ export class ScopeHoistingPackager {
|
|
|
119
146
|
this.bundle = bundle;
|
|
120
147
|
this.parcelRequireName = parcelRequireName;
|
|
121
148
|
this.useAsyncBundleRuntime = useAsyncBundleRuntime;
|
|
122
|
-
this.
|
|
149
|
+
this.manualStaticBindingExports =
|
|
150
|
+
manualStaticBindingExports?.map((glob) => globToRegex(glob)) ?? null;
|
|
123
151
|
this.logger = logger;
|
|
124
152
|
|
|
125
153
|
let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
|
|
@@ -128,13 +156,14 @@ export class ScopeHoistingPackager {
|
|
|
128
156
|
this.isAsyncBundle =
|
|
129
157
|
this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') &&
|
|
130
158
|
!this.bundle.env.isIsolated() &&
|
|
131
|
-
this.bundle.bundleBehavior !== 'isolated'
|
|
159
|
+
this.bundle.bundleBehavior !== 'isolated' &&
|
|
160
|
+
this.bundle.bundleBehavior !== 'inlineIsolated';
|
|
132
161
|
|
|
133
162
|
this.globalNames = GLOBALS_BY_CONTEXT[bundle.env.context];
|
|
134
163
|
}
|
|
135
164
|
|
|
136
|
-
async package(): Promise<
|
|
137
|
-
|
|
165
|
+
async package(): Promise<PackageResult> {
|
|
166
|
+
await this.loadAssets();
|
|
138
167
|
this.buildExportedSymbols();
|
|
139
168
|
|
|
140
169
|
// If building a library, the target is actually another bundler rather
|
|
@@ -155,10 +184,13 @@ export class ScopeHoistingPackager {
|
|
|
155
184
|
|
|
156
185
|
let res = '';
|
|
157
186
|
let lineCount = 0;
|
|
158
|
-
let sourceMap = null;
|
|
159
|
-
let processAsset = (asset) => {
|
|
187
|
+
let sourceMap: SourceMap | null | undefined = null;
|
|
188
|
+
let processAsset = (asset: Asset) => {
|
|
189
|
+
this.seenHoistedRequires.clear();
|
|
160
190
|
let [content, map, lines] = this.visitAsset(asset);
|
|
191
|
+
|
|
161
192
|
if (sourceMap && map) {
|
|
193
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
162
194
|
sourceMap.addSourceMap(map, lineCount);
|
|
163
195
|
} else if (this.bundle.env.sourceMap) {
|
|
164
196
|
sourceMap = map;
|
|
@@ -168,10 +200,22 @@ export class ScopeHoistingPackager {
|
|
|
168
200
|
lineCount += lines + 1;
|
|
169
201
|
};
|
|
170
202
|
|
|
203
|
+
if (
|
|
204
|
+
getFeatureFlag('inlineConstOptimisationFix') ||
|
|
205
|
+
this.useBothScopeHoistingImprovements
|
|
206
|
+
) {
|
|
207
|
+
// Write out all constant modules used by this bundle
|
|
208
|
+
for (let asset of this.constantAssets) {
|
|
209
|
+
if (!this.seenAssets.has(asset)) {
|
|
210
|
+
processAsset(asset);
|
|
211
|
+
}
|
|
212
|
+
}
|
|
213
|
+
}
|
|
214
|
+
|
|
171
215
|
// Hoist wrapped asset to the top of the bundle to ensure that they are registered
|
|
172
216
|
// before they are used.
|
|
173
|
-
for (let asset of wrappedAssets) {
|
|
174
|
-
if (!this.seenAssets.has(asset
|
|
217
|
+
for (let asset of this.wrappedAssets) {
|
|
218
|
+
if (!this.seenAssets.has(asset)) {
|
|
175
219
|
processAsset(asset);
|
|
176
220
|
}
|
|
177
221
|
}
|
|
@@ -179,7 +223,7 @@ export class ScopeHoistingPackager {
|
|
|
179
223
|
// Add each asset that is directly connected to the bundle. Dependencies will be handled
|
|
180
224
|
// by replacing `import` statements in the code.
|
|
181
225
|
this.bundle.traverseAssets((asset, _, actions) => {
|
|
182
|
-
if (this.seenAssets.has(asset
|
|
226
|
+
if (this.seenAssets.has(asset)) {
|
|
183
227
|
actions.skipChildren();
|
|
184
228
|
return;
|
|
185
229
|
}
|
|
@@ -191,14 +235,28 @@ export class ScopeHoistingPackager {
|
|
|
191
235
|
let [prelude, preludeLines] = this.buildBundlePrelude();
|
|
192
236
|
res = prelude + res;
|
|
193
237
|
lineCount += preludeLines;
|
|
238
|
+
// @ts-expect-error TS2339 - offsetLines method exists but missing from @parcel/source-map type definitions
|
|
194
239
|
sourceMap?.offsetLines(1, preludeLines);
|
|
195
240
|
|
|
196
241
|
let entries = this.bundle.getEntryAssets();
|
|
197
242
|
let mainEntry = this.bundle.getMainEntry();
|
|
198
243
|
if (this.isAsyncBundle) {
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
244
|
+
if (
|
|
245
|
+
this.useBothScopeHoistingImprovements ||
|
|
246
|
+
getFeatureFlag('supportWebpackChunkName')
|
|
247
|
+
) {
|
|
248
|
+
// Generally speaking, async bundles should not be executed on load, as
|
|
249
|
+
// they're just collections of assets that other assets require.
|
|
250
|
+
// However, there are some special cases where a runtime asset needs to be
|
|
251
|
+
// injected, but no other asset will require it (mostly the bundle
|
|
252
|
+
// manifest).
|
|
253
|
+
// In this case, those assets need to be required on load.
|
|
254
|
+
entries = entries.filter(
|
|
255
|
+
(a) => a.meta?.runtimeAssetRequiringExecutionOnLoad,
|
|
256
|
+
);
|
|
257
|
+
} else {
|
|
258
|
+
entries = entries.filter((a) => a.id !== mainEntry?.id);
|
|
259
|
+
}
|
|
202
260
|
mainEntry = null;
|
|
203
261
|
}
|
|
204
262
|
|
|
@@ -206,7 +264,7 @@ export class ScopeHoistingPackager {
|
|
|
206
264
|
|
|
207
265
|
// If any of the entry assets are wrapped, call parcelRequire so they are executed.
|
|
208
266
|
for (let entry of entries) {
|
|
209
|
-
if (this.wrappedAssets.has(entry
|
|
267
|
+
if (this.wrappedAssets.has(entry) && !this.isScriptEntry(entry)) {
|
|
210
268
|
let parcelRequire = `parcelRequire(${JSON.stringify(
|
|
211
269
|
this.bundleGraph.getAssetPublicId(entry),
|
|
212
270
|
)});\n`;
|
|
@@ -250,9 +308,7 @@ export class ScopeHoistingPackager {
|
|
|
250
308
|
lineCount++;
|
|
251
309
|
|
|
252
310
|
let mainEntry = nullthrows(this.bundle.getMainEntry());
|
|
253
|
-
let {code, map: mapBuffer} = nullthrows(
|
|
254
|
-
this.assetOutputs.get(mainEntry.id),
|
|
255
|
-
);
|
|
311
|
+
let {code, map: mapBuffer} = nullthrows(this.assetOutputs.get(mainEntry));
|
|
256
312
|
let map;
|
|
257
313
|
if (mapBuffer) {
|
|
258
314
|
map = new SourceMap(this.options.projectRoot, mapBuffer);
|
|
@@ -265,14 +321,21 @@ export class ScopeHoistingPackager {
|
|
|
265
321
|
this.parcelRequireName,
|
|
266
322
|
);
|
|
267
323
|
if (sourceMap && map) {
|
|
324
|
+
// @ts-expect-error TS2339 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
268
325
|
sourceMap.addSourceMap(map, lineCount);
|
|
269
326
|
}
|
|
270
327
|
}
|
|
271
328
|
|
|
272
|
-
|
|
273
|
-
|
|
274
|
-
|
|
275
|
-
|
|
329
|
+
const result: PackageResult = {contents: res, map: sourceMap};
|
|
330
|
+
|
|
331
|
+
if (debugTools['scope-hoisting-stats']) {
|
|
332
|
+
result.scopeHoistingStats = {
|
|
333
|
+
totalAssets: this.assetOutputs.size,
|
|
334
|
+
wrappedAssets: this.wrappedAssets.size,
|
|
335
|
+
};
|
|
336
|
+
}
|
|
337
|
+
|
|
338
|
+
return result;
|
|
276
339
|
}
|
|
277
340
|
|
|
278
341
|
shouldBundleQueue(bundle: NamedBundle): boolean {
|
|
@@ -281,10 +344,7 @@ export class ScopeHoistingPackager {
|
|
|
281
344
|
|
|
282
345
|
let hasConditionalReference = false;
|
|
283
346
|
let isConditionalBundle = false;
|
|
284
|
-
if (
|
|
285
|
-
getFeatureFlag('conditionalBundlingApi') &&
|
|
286
|
-
getFeatureFlag('conditionalBundlingAsyncRuntime')
|
|
287
|
-
) {
|
|
347
|
+
if (getFeatureFlag('conditionalBundlingApi')) {
|
|
288
348
|
// If the bundle has a conditional bundle reference (has an importCond)
|
|
289
349
|
hasConditionalReference =
|
|
290
350
|
this.bundleGraph.getReferencedConditionalBundles(bundle).length > 0;
|
|
@@ -296,6 +356,7 @@ export class ScopeHoistingPackager {
|
|
|
296
356
|
this.useAsyncBundleRuntime &&
|
|
297
357
|
bundle.type === 'js' &&
|
|
298
358
|
bundle.bundleBehavior !== 'inline' &&
|
|
359
|
+
bundle.bundleBehavior !== 'inlineIsolated' &&
|
|
299
360
|
bundle.env.outputFormat === 'esmodule' &&
|
|
300
361
|
!bundle.env.isIsolated() &&
|
|
301
362
|
bundle.bundleBehavior !== 'isolated' &&
|
|
@@ -309,11 +370,8 @@ export class ScopeHoistingPackager {
|
|
|
309
370
|
.filter((b) => this.shouldBundleQueue(b))
|
|
310
371
|
.map((b) => b.publicId);
|
|
311
372
|
|
|
312
|
-
const conditions = [];
|
|
313
|
-
if (
|
|
314
|
-
getFeatureFlag('conditionalBundlingApi') &&
|
|
315
|
-
getFeatureFlag('conditionalBundlingAsyncRuntime')
|
|
316
|
-
) {
|
|
373
|
+
const conditions: Array<string> = [];
|
|
374
|
+
if (getFeatureFlag('conditionalBundlingApi')) {
|
|
317
375
|
const conditionSet = this.bundleGraph
|
|
318
376
|
.getConditionalBundleMapping()
|
|
319
377
|
.get(bundle.id);
|
|
@@ -354,16 +412,20 @@ export class ScopeHoistingPackager {
|
|
|
354
412
|
return `$parcel$global.rwr(${params.join(', ')});`;
|
|
355
413
|
}
|
|
356
414
|
|
|
357
|
-
async loadAssets()
|
|
358
|
-
|
|
359
|
-
let
|
|
415
|
+
async loadAssets() {
|
|
416
|
+
type QueueItem = [Asset, {code: string; map: Buffer | undefined | null}];
|
|
417
|
+
let queue = new PromiseQueue<QueueItem>({
|
|
418
|
+
maxConcurrent: 32,
|
|
419
|
+
});
|
|
420
|
+
|
|
360
421
|
this.bundle.traverseAssets((asset) => {
|
|
361
422
|
queue.add(async () => {
|
|
362
423
|
let [code, map] = await Promise.all([
|
|
363
424
|
asset.getCode(),
|
|
364
425
|
this.bundle.env.sourceMap ? asset.getMapBuffer() : null,
|
|
365
426
|
]);
|
|
366
|
-
|
|
427
|
+
|
|
428
|
+
return [asset, {code, map}];
|
|
367
429
|
});
|
|
368
430
|
|
|
369
431
|
if (
|
|
@@ -381,52 +443,113 @@ export class ScopeHoistingPackager {
|
|
|
381
443
|
.getIncomingDependencies(asset)
|
|
382
444
|
.some((dep) => dep.priority === 'lazy')
|
|
383
445
|
) {
|
|
384
|
-
this.wrappedAssets.add(asset
|
|
385
|
-
|
|
446
|
+
this.wrappedAssets.add(asset);
|
|
447
|
+
} else if (
|
|
448
|
+
(getFeatureFlag('inlineConstOptimisationFix') ||
|
|
449
|
+
this.useBothScopeHoistingImprovements) &&
|
|
450
|
+
asset.meta.isConstantModule
|
|
451
|
+
) {
|
|
452
|
+
this.constantAssets.add(asset);
|
|
386
453
|
}
|
|
387
454
|
}
|
|
388
455
|
});
|
|
389
456
|
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
457
|
+
if (this.useBothScopeHoistingImprovements) {
|
|
458
|
+
// Tracks which assets have been assigned to a wrap group
|
|
459
|
+
let assignedAssets = new Set<Asset>();
|
|
460
|
+
|
|
461
|
+
// In V2 scope hoisting, we iterate from the main entry, rather than
|
|
462
|
+
// wrapping the entry assets
|
|
463
|
+
if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
464
|
+
// Make all entry assets wrapped, to avoid any top level hoisting
|
|
465
|
+
for (let entryAsset of this.bundle.getEntryAssets()) {
|
|
466
|
+
if (!this.wrappedAssets.has(entryAsset)) {
|
|
467
|
+
this.wrappedAssets.add(entryAsset);
|
|
468
|
+
}
|
|
394
469
|
}
|
|
470
|
+
}
|
|
395
471
|
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
//
|
|
402
|
-
//
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
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);
|
|
472
|
+
// We need to make a new copy here so that we can add to the list and
|
|
473
|
+
// iterate the newly added items, without mutating the wrappedAssets set
|
|
474
|
+
let moduleGroupParents = [...this.wrappedAssets.values()];
|
|
475
|
+
|
|
476
|
+
if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
477
|
+
// The main entry needs to be check to find assets that would have gone in
|
|
478
|
+
// the top level scope
|
|
479
|
+
let mainEntry = this.bundle.getMainEntry();
|
|
480
|
+
if (mainEntry && !this.wrappedAssets.has(mainEntry)) {
|
|
481
|
+
moduleGroupParents.unshift(mainEntry);
|
|
424
482
|
}
|
|
425
|
-
}
|
|
483
|
+
}
|
|
484
|
+
|
|
485
|
+
for (let moduleGroupParentAsset of moduleGroupParents) {
|
|
486
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
487
|
+
if (asset === moduleGroupParentAsset) {
|
|
488
|
+
return;
|
|
489
|
+
}
|
|
490
|
+
|
|
491
|
+
if (this.wrappedAssets.has(asset)) {
|
|
492
|
+
actions.skipChildren();
|
|
493
|
+
return;
|
|
494
|
+
}
|
|
495
|
+
|
|
496
|
+
if (
|
|
497
|
+
!asset.meta.isConstantModule &&
|
|
498
|
+
(assignedAssets.has(asset) || this.isReExported(asset))
|
|
499
|
+
) {
|
|
500
|
+
this.wrappedAssets.add(asset);
|
|
501
|
+
|
|
502
|
+
// This also needs to be added to the traversal so that we iterate
|
|
503
|
+
// it during this check.
|
|
504
|
+
moduleGroupParents.push(asset);
|
|
505
|
+
|
|
506
|
+
actions.skipChildren();
|
|
507
|
+
return;
|
|
508
|
+
}
|
|
509
|
+
|
|
510
|
+
assignedAssets.add(asset);
|
|
511
|
+
}, moduleGroupParentAsset);
|
|
512
|
+
}
|
|
513
|
+
} else {
|
|
514
|
+
for (let wrappedAssetRoot of this.wrappedAssets) {
|
|
515
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
516
|
+
if (asset === wrappedAssetRoot) {
|
|
517
|
+
return;
|
|
518
|
+
}
|
|
519
|
+
|
|
520
|
+
if (this.wrappedAssets.has(asset)) {
|
|
521
|
+
actions.skipChildren();
|
|
522
|
+
return;
|
|
523
|
+
}
|
|
524
|
+
|
|
525
|
+
if (!asset.meta.isConstantModule) {
|
|
526
|
+
this.wrappedAssets.add(asset);
|
|
527
|
+
}
|
|
528
|
+
}, wrappedAssetRoot);
|
|
529
|
+
}
|
|
426
530
|
}
|
|
427
531
|
|
|
428
532
|
this.assetOutputs = new Map(await queue.run());
|
|
429
|
-
|
|
533
|
+
}
|
|
534
|
+
|
|
535
|
+
isReExported(asset: Asset): boolean {
|
|
536
|
+
let parentSymbols = this.bundleGraph
|
|
537
|
+
.getIncomingDependencies(asset)
|
|
538
|
+
.map((dep) => this.bundleGraph.getAssetWithDependency(dep))
|
|
539
|
+
.flatMap((parent) => {
|
|
540
|
+
if (parent == null) {
|
|
541
|
+
return [];
|
|
542
|
+
}
|
|
543
|
+
return this.bundleGraph.getExportedSymbols(parent, this.bundle);
|
|
544
|
+
});
|
|
545
|
+
|
|
546
|
+
let assetSymbols = this.bundleGraph.getExportedSymbols(asset, this.bundle);
|
|
547
|
+
|
|
548
|
+
return assetSymbols.some((assetSymbol) =>
|
|
549
|
+
parentSymbols.some(
|
|
550
|
+
(parentSymbol) => parentSymbol.symbol === assetSymbol.symbol,
|
|
551
|
+
),
|
|
552
|
+
);
|
|
430
553
|
}
|
|
431
554
|
|
|
432
555
|
buildExportedSymbols() {
|
|
@@ -439,7 +562,7 @@ export class ScopeHoistingPackager {
|
|
|
439
562
|
|
|
440
563
|
// TODO: handle ESM exports of wrapped entry assets...
|
|
441
564
|
let entry = this.bundle.getMainEntry();
|
|
442
|
-
if (entry && !this.wrappedAssets.has(entry
|
|
565
|
+
if (entry && !this.wrappedAssets.has(entry)) {
|
|
443
566
|
let hasNamespace = entry.symbols.hasExportSymbol('*');
|
|
444
567
|
|
|
445
568
|
for (let {
|
|
@@ -464,6 +587,7 @@ export class ScopeHoistingPackager {
|
|
|
464
587
|
symbols = [];
|
|
465
588
|
this.exportedSymbols.set(symbol, {
|
|
466
589
|
asset,
|
|
590
|
+
|
|
467
591
|
exportSymbol,
|
|
468
592
|
local: symbol,
|
|
469
593
|
exportAs: symbols,
|
|
@@ -519,20 +643,24 @@ export class ScopeHoistingPackager {
|
|
|
519
643
|
return `${obj}[${JSON.stringify(property)}]`;
|
|
520
644
|
}
|
|
521
645
|
|
|
522
|
-
visitAsset(asset: Asset): [string,
|
|
523
|
-
invariant(!this.seenAssets.has(asset
|
|
524
|
-
this.seenAssets.add(asset
|
|
646
|
+
visitAsset(asset: Asset): [string, SourceMap | null | undefined, number] {
|
|
647
|
+
invariant(!this.seenAssets.has(asset), 'Already visited asset');
|
|
648
|
+
this.seenAssets.add(asset);
|
|
525
649
|
|
|
526
|
-
let {code, map} = nullthrows(this.assetOutputs.get(asset
|
|
650
|
+
let {code, map} = nullthrows(this.assetOutputs.get(asset));
|
|
527
651
|
return this.buildAsset(asset, code, map);
|
|
528
652
|
}
|
|
529
653
|
|
|
654
|
+
getAssetFilePath(asset: Asset): string {
|
|
655
|
+
return path.relative(this.options.projectRoot, asset.filePath);
|
|
656
|
+
}
|
|
657
|
+
|
|
530
658
|
buildAsset(
|
|
531
659
|
asset: Asset,
|
|
532
660
|
code: string,
|
|
533
|
-
map
|
|
534
|
-
): [string,
|
|
535
|
-
let shouldWrap = this.wrappedAssets.has(asset
|
|
661
|
+
map?: Buffer | null,
|
|
662
|
+
): [string, SourceMap | null | undefined, number] {
|
|
663
|
+
let shouldWrap = this.wrappedAssets.has(asset);
|
|
536
664
|
let deps = this.bundleGraph.getDependencies(asset);
|
|
537
665
|
|
|
538
666
|
let sourceMap =
|
|
@@ -559,16 +687,24 @@ export class ScopeHoistingPackager {
|
|
|
559
687
|
continue;
|
|
560
688
|
}
|
|
561
689
|
|
|
562
|
-
if (
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
690
|
+
if (this.bundle.hasAsset(resolved) && !this.seenAssets.has(resolved)) {
|
|
691
|
+
if (
|
|
692
|
+
this.useBothScopeHoistingImprovements &&
|
|
693
|
+
this.wrappedAssets.has(resolved)
|
|
694
|
+
) {
|
|
695
|
+
// When the dep is wrapped then we just need to drop a side effect
|
|
696
|
+
// require instead of inlining
|
|
697
|
+
depCode += `parcelRequire("${this.bundleGraph.getAssetPublicId(resolved)}");\n`;
|
|
698
|
+
lineCount += 1;
|
|
699
|
+
} else {
|
|
700
|
+
let [code, map, lines] = this.visitAsset(resolved);
|
|
701
|
+
depCode += code + '\n';
|
|
702
|
+
if (sourceMap && map) {
|
|
703
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
704
|
+
sourceMap.addSourceMap(map, lineCount);
|
|
705
|
+
}
|
|
706
|
+
lineCount += lines + 1;
|
|
570
707
|
}
|
|
571
|
-
lineCount += lines + 1;
|
|
572
708
|
}
|
|
573
709
|
}
|
|
574
710
|
|
|
@@ -602,7 +738,7 @@ export class ScopeHoistingPackager {
|
|
|
602
738
|
code += append;
|
|
603
739
|
|
|
604
740
|
let lineCount = 0;
|
|
605
|
-
let depContent = [];
|
|
741
|
+
let depContent: Array<[string, SourceMap | null | undefined, number]> = [];
|
|
606
742
|
if (depMap.size === 0 && replacements.size === 0) {
|
|
607
743
|
// If there are no dependencies or replacements, use a simple function to count the number of lines.
|
|
608
744
|
lineCount = countLines(code) - 1;
|
|
@@ -647,27 +783,68 @@ export class ScopeHoistingPackager {
|
|
|
647
783
|
// after the dependency is declared. This handles the case where the resulting asset
|
|
648
784
|
// is wrapped, but the dependency in this asset is not marked as wrapped. This means
|
|
649
785
|
// that it was imported/required at the top-level, so its side effects should run immediately.
|
|
650
|
-
let
|
|
651
|
-
|
|
652
|
-
dep,
|
|
653
|
-
resolved,
|
|
654
|
-
);
|
|
786
|
+
let res = '';
|
|
787
|
+
let lines = 0;
|
|
655
788
|
let map;
|
|
789
|
+
|
|
790
|
+
if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
791
|
+
[res, lines] = this.getHoistedParcelRequires(
|
|
792
|
+
asset,
|
|
793
|
+
dep,
|
|
794
|
+
resolved,
|
|
795
|
+
);
|
|
796
|
+
}
|
|
797
|
+
|
|
656
798
|
if (
|
|
657
799
|
this.bundle.hasAsset(resolved) &&
|
|
658
|
-
!this.seenAssets.has(resolved
|
|
800
|
+
!this.seenAssets.has(resolved)
|
|
659
801
|
) {
|
|
660
802
|
// If this asset is wrapped, we need to hoist the code for the dependency
|
|
661
803
|
// outside our parcelRequire.register wrapper. This is safe because all
|
|
662
804
|
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
663
805
|
// asset content where the import statement was.
|
|
664
|
-
if (
|
|
665
|
-
|
|
806
|
+
if (this.useBothScopeHoistingImprovements) {
|
|
807
|
+
if (
|
|
808
|
+
!resolved.meta.isConstantModule &&
|
|
809
|
+
!this.wrappedAssets.has(resolved)
|
|
810
|
+
) {
|
|
811
|
+
let [depCode, depMap, depLines] =
|
|
812
|
+
this.visitAsset(resolved);
|
|
813
|
+
if (debugTools['asset-file-names-in-output']) {
|
|
814
|
+
let resolvedPath = this.getAssetFilePath(resolved);
|
|
815
|
+
res = outdent`
|
|
816
|
+
/* Scope hoisted asset: ${resolvedPath} */
|
|
817
|
+
${depCode}
|
|
818
|
+
/* End: ${resolvedPath} */
|
|
819
|
+
${res}
|
|
820
|
+
`;
|
|
821
|
+
lines += 3 + depLines;
|
|
822
|
+
} else {
|
|
823
|
+
res = depCode + '\n' + res;
|
|
824
|
+
lines += 1 + depLines;
|
|
825
|
+
}
|
|
826
|
+
map = depMap;
|
|
827
|
+
}
|
|
666
828
|
} else {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
829
|
+
if (shouldWrap) {
|
|
830
|
+
depContent.push(this.visitAsset(resolved));
|
|
831
|
+
} else {
|
|
832
|
+
let [depCode, depMap, depLines] =
|
|
833
|
+
this.visitAsset(resolved);
|
|
834
|
+
res = depCode + '\n' + res;
|
|
835
|
+
lines += 1 + depLines;
|
|
836
|
+
map = depMap;
|
|
837
|
+
}
|
|
838
|
+
}
|
|
839
|
+
}
|
|
840
|
+
|
|
841
|
+
if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
842
|
+
let [requiresCode, requiresLines] =
|
|
843
|
+
this.getHoistedParcelRequires(asset, dep, resolved);
|
|
844
|
+
|
|
845
|
+
if (requiresCode) {
|
|
846
|
+
res = requiresCode + '\n' + res;
|
|
847
|
+
lines += requiresLines + 1;
|
|
671
848
|
}
|
|
672
849
|
}
|
|
673
850
|
|
|
@@ -679,6 +856,7 @@ export class ScopeHoistingPackager {
|
|
|
679
856
|
}
|
|
680
857
|
|
|
681
858
|
if (map) {
|
|
859
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
682
860
|
sourceMap.addSourceMap(map, lineCount);
|
|
683
861
|
}
|
|
684
862
|
}
|
|
@@ -726,10 +904,16 @@ ${code}
|
|
|
726
904
|
|
|
727
905
|
lineCount += 2;
|
|
728
906
|
|
|
907
|
+
if (debugTools['asset-file-names-in-output']) {
|
|
908
|
+
code = `/* ${this.getAssetFilePath(asset)} */\n` + code;
|
|
909
|
+
lineCount += 1;
|
|
910
|
+
}
|
|
911
|
+
|
|
729
912
|
for (let [depCode, map, lines] of depContent) {
|
|
730
913
|
if (!depCode) continue;
|
|
731
914
|
code += depCode + '\n';
|
|
732
915
|
if (sourceMap && map) {
|
|
916
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
733
917
|
sourceMap.addSourceMap(map, lineCount);
|
|
734
918
|
}
|
|
735
919
|
lineCount += lines + 1;
|
|
@@ -848,7 +1032,7 @@ ${code}
|
|
|
848
1032
|
// If this asset is wrapped, we need to replace the exports namespace with `module.exports`,
|
|
849
1033
|
// which will be provided to us by the wrapper.
|
|
850
1034
|
if (
|
|
851
|
-
this.wrappedAssets.has(asset
|
|
1035
|
+
this.wrappedAssets.has(asset) ||
|
|
852
1036
|
(this.bundle.env.outputFormat === 'commonjs' &&
|
|
853
1037
|
asset === this.bundle.getMainEntry())
|
|
854
1038
|
) {
|
|
@@ -895,7 +1079,9 @@ ${code}
|
|
|
895
1079
|
|
|
896
1080
|
for (let [imported, {local}] of dep.symbols) {
|
|
897
1081
|
// If already imported, just add the already renamed variable to the mapping.
|
|
1082
|
+
|
|
898
1083
|
let renamed = external.get(imported);
|
|
1084
|
+
|
|
899
1085
|
if (renamed && local !== '*' && replacements) {
|
|
900
1086
|
replacements.set(local, renamed);
|
|
901
1087
|
continue;
|
|
@@ -908,6 +1094,7 @@ ${code}
|
|
|
908
1094
|
if (!renamed) {
|
|
909
1095
|
if (referencedBundle) {
|
|
910
1096
|
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
1097
|
+
|
|
911
1098
|
renamed =
|
|
912
1099
|
entry.symbols.get('*')?.local ??
|
|
913
1100
|
`$${String(entry.meta.id)}$exports`;
|
|
@@ -922,6 +1109,7 @@ ${code}
|
|
|
922
1109
|
|
|
923
1110
|
if (local !== '*' && replacements) {
|
|
924
1111
|
let replacement;
|
|
1112
|
+
|
|
925
1113
|
if (imported === '*') {
|
|
926
1114
|
replacement = renamed;
|
|
927
1115
|
} else if (imported === 'default') {
|
|
@@ -946,10 +1134,12 @@ ${code}
|
|
|
946
1134
|
let property;
|
|
947
1135
|
if (referencedBundle) {
|
|
948
1136
|
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
1137
|
+
|
|
949
1138
|
if (entry.symbols.hasExportSymbol('*')) {
|
|
950
1139
|
// If importing * and the referenced module has a * export (e.g. CJS), use default instead.
|
|
951
1140
|
// This mirrors the logic in buildExportedSymbols.
|
|
952
1141
|
property = imported;
|
|
1142
|
+
|
|
953
1143
|
imported =
|
|
954
1144
|
referencedBundle?.env.outputFormat === 'esmodule'
|
|
955
1145
|
? 'default'
|
|
@@ -957,6 +1147,7 @@ ${code}
|
|
|
957
1147
|
} else {
|
|
958
1148
|
if (imported === '*') {
|
|
959
1149
|
let exportedSymbols = this.bundleGraph.getExportedSymbols(entry);
|
|
1150
|
+
|
|
960
1151
|
if (local === '*') {
|
|
961
1152
|
// Re-export all symbols.
|
|
962
1153
|
for (let exported of exportedSymbols) {
|
|
@@ -967,11 +1158,10 @@ ${code}
|
|
|
967
1158
|
continue;
|
|
968
1159
|
}
|
|
969
1160
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
imported,
|
|
973
|
-
|
|
974
|
-
).symbol;
|
|
1161
|
+
|
|
1162
|
+
renamed =
|
|
1163
|
+
this.bundleGraph.getSymbolResolution(entry, imported, this.bundle)
|
|
1164
|
+
.symbol || undefined;
|
|
975
1165
|
}
|
|
976
1166
|
}
|
|
977
1167
|
|
|
@@ -993,8 +1183,10 @@ ${code}
|
|
|
993
1183
|
}
|
|
994
1184
|
|
|
995
1185
|
external.set(imported, renamed);
|
|
1186
|
+
|
|
996
1187
|
if (local !== '*' && replacements) {
|
|
997
1188
|
let replacement = renamed;
|
|
1189
|
+
|
|
998
1190
|
if (property === '*') {
|
|
999
1191
|
replacement = renamed;
|
|
1000
1192
|
} else if (property === 'default') {
|
|
@@ -1003,6 +1195,7 @@ ${code}
|
|
|
1003
1195
|
} else if (property) {
|
|
1004
1196
|
replacement = this.getPropertyAccess(renamed, property);
|
|
1005
1197
|
}
|
|
1198
|
+
|
|
1006
1199
|
replacements.set(local, replacement);
|
|
1007
1200
|
}
|
|
1008
1201
|
}
|
|
@@ -1026,7 +1219,7 @@ ${code}
|
|
|
1026
1219
|
}
|
|
1027
1220
|
return (
|
|
1028
1221
|
(!this.bundle.hasAsset(resolved) && !this.externalAssets.has(resolved)) ||
|
|
1029
|
-
(this.wrappedAssets.has(resolved
|
|
1222
|
+
(this.wrappedAssets.has(resolved) && resolved !== parentAsset)
|
|
1030
1223
|
);
|
|
1031
1224
|
}
|
|
1032
1225
|
|
|
@@ -1076,14 +1269,14 @@ ${code}
|
|
|
1076
1269
|
(!this.bundle.hasAsset(resolvedAsset) ||
|
|
1077
1270
|
!this.shouldSkipAsset(resolvedAsset))
|
|
1078
1271
|
) {
|
|
1079
|
-
let hoisted = this.hoistedRequires.get(dep
|
|
1272
|
+
let hoisted = this.hoistedRequires.get(dep);
|
|
1080
1273
|
if (!hoisted) {
|
|
1081
1274
|
hoisted = new Map();
|
|
1082
|
-
this.hoistedRequires.set(dep
|
|
1275
|
+
this.hoistedRequires.set(dep, hoisted);
|
|
1083
1276
|
}
|
|
1084
1277
|
|
|
1085
1278
|
hoisted.set(
|
|
1086
|
-
resolvedAsset
|
|
1279
|
+
resolvedAsset,
|
|
1087
1280
|
`var $${publicId} = parcelRequire(${JSON.stringify(publicId)});`,
|
|
1088
1281
|
);
|
|
1089
1282
|
}
|
|
@@ -1117,6 +1310,7 @@ ${code}
|
|
|
1117
1310
|
obj = `$${publicId}`;
|
|
1118
1311
|
} else {
|
|
1119
1312
|
obj = resolvedAsset.symbols.get('*')?.local || `$${assetId}$exports`;
|
|
1313
|
+
|
|
1120
1314
|
obj = replacements?.get(obj) || obj;
|
|
1121
1315
|
}
|
|
1122
1316
|
|
|
@@ -1124,7 +1318,7 @@ ${code}
|
|
|
1124
1318
|
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
|
|
1125
1319
|
if (
|
|
1126
1320
|
parentAsset === resolvedAsset &&
|
|
1127
|
-
this.wrappedAssets.has(resolvedAsset
|
|
1321
|
+
this.wrappedAssets.has(resolvedAsset)
|
|
1128
1322
|
) {
|
|
1129
1323
|
// Directly use module.exports for wrapped assets importing themselves.
|
|
1130
1324
|
return 'module.exports';
|
|
@@ -1167,7 +1361,7 @@ ${code}
|
|
|
1167
1361
|
return ['', 0];
|
|
1168
1362
|
}
|
|
1169
1363
|
|
|
1170
|
-
let hoisted = this.hoistedRequires.get(dep
|
|
1364
|
+
let hoisted = this.hoistedRequires.get(dep);
|
|
1171
1365
|
let res = '';
|
|
1172
1366
|
let lineCount = 0;
|
|
1173
1367
|
let isWrapped = this.isWrapped(resolved, parentAsset);
|
|
@@ -1179,7 +1373,7 @@ ${code}
|
|
|
1179
1373
|
if (
|
|
1180
1374
|
isWrapped &&
|
|
1181
1375
|
!dep.meta.shouldWrap &&
|
|
1182
|
-
(!hoisted || hoisted.keys().next().value !== resolved
|
|
1376
|
+
(!hoisted || hoisted.keys().next().value !== resolved) &&
|
|
1183
1377
|
!this.bundleGraph.isDependencySkipped(dep) &&
|
|
1184
1378
|
!this.shouldSkipAsset(resolved)
|
|
1185
1379
|
) {
|
|
@@ -1191,8 +1385,22 @@ ${code}
|
|
|
1191
1385
|
|
|
1192
1386
|
if (hoisted) {
|
|
1193
1387
|
this.needsPrelude = true;
|
|
1194
|
-
|
|
1195
|
-
|
|
1388
|
+
|
|
1389
|
+
if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
1390
|
+
let hoistedValues = [...hoisted.values()].filter(
|
|
1391
|
+
(val) => !this.seenHoistedRequires.has(val),
|
|
1392
|
+
);
|
|
1393
|
+
|
|
1394
|
+
for (let val of hoistedValues) {
|
|
1395
|
+
this.seenHoistedRequires.add(val);
|
|
1396
|
+
}
|
|
1397
|
+
|
|
1398
|
+
res += '\n' + hoistedValues.join('\n');
|
|
1399
|
+
lineCount += hoisted.size;
|
|
1400
|
+
} else {
|
|
1401
|
+
res += '\n' + [...hoisted.values()].join('\n');
|
|
1402
|
+
lineCount += hoisted.size;
|
|
1403
|
+
}
|
|
1196
1404
|
}
|
|
1197
1405
|
|
|
1198
1406
|
return [res, lineCount];
|
|
@@ -1207,7 +1415,7 @@ ${code}
|
|
|
1207
1415
|
let prependLineCount = 0;
|
|
1208
1416
|
let append = '';
|
|
1209
1417
|
|
|
1210
|
-
let shouldWrap = this.wrappedAssets.has(asset
|
|
1418
|
+
let shouldWrap = this.wrappedAssets.has(asset);
|
|
1211
1419
|
let usedSymbols = nullthrows(this.bundleGraph.getUsedSymbols(asset));
|
|
1212
1420
|
let assetId = asset.meta.id;
|
|
1213
1421
|
invariant(typeof assetId === 'string');
|
|
@@ -1220,34 +1428,51 @@ ${code}
|
|
|
1220
1428
|
usedSymbols.has('default') &&
|
|
1221
1429
|
!asset.symbols.hasExportSymbol('__esModule');
|
|
1222
1430
|
|
|
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
|
-
|
|
1431
|
+
let usedNamespace;
|
|
1432
|
+
if (
|
|
1433
|
+
getFeatureFlag('inlineConstOptimisationFix') &&
|
|
1434
|
+
asset.meta.isConstantModule
|
|
1435
|
+
) {
|
|
1436
|
+
// Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
|
|
1437
|
+
usedNamespace = this.bundleGraph
|
|
1438
|
+
.getIncomingDependencies(asset)
|
|
1439
|
+
.some(
|
|
1440
|
+
(dep) =>
|
|
1441
|
+
this.bundle.hasDependency(dep) &&
|
|
1442
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1443
|
+
);
|
|
1444
|
+
} else {
|
|
1445
|
+
usedNamespace =
|
|
1446
|
+
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
1447
|
+
// The one case where this isn't true is in ESM library entries, where the only
|
|
1448
|
+
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
1449
|
+
// instead of the namespace object.
|
|
1450
|
+
|
|
1451
|
+
(usedSymbols.has('*') &&
|
|
1452
|
+
(this.bundle.env.outputFormat !== 'esmodule' ||
|
|
1453
|
+
!this.bundle.env.isLibrary ||
|
|
1454
|
+
asset !== this.bundle.getMainEntry() ||
|
|
1455
|
+
this.bundleGraph
|
|
1456
|
+
.getIncomingDependencies(asset)
|
|
1457
|
+
.some(
|
|
1458
|
+
(dep) =>
|
|
1459
|
+
!dep.isEntry &&
|
|
1460
|
+
this.bundle.hasDependency(dep) &&
|
|
1461
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1462
|
+
))) ||
|
|
1463
|
+
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
1464
|
+
// we fallback on the namespace object.
|
|
1465
|
+
|
|
1466
|
+
(asset.symbols.hasExportSymbol('*') &&
|
|
1467
|
+
[...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
|
|
1468
|
+
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
1469
|
+
// include the namespace object for the default export.
|
|
1470
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
1471
|
+
// CommonJS library bundle entries always need a namespace.
|
|
1472
|
+
(this.bundle.env.isLibrary &&
|
|
1473
|
+
this.bundle.env.outputFormat === 'commonjs' &&
|
|
1474
|
+
asset === this.bundle.getMainEntry());
|
|
1475
|
+
}
|
|
1251
1476
|
|
|
1252
1477
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
1253
1478
|
// or we need default interop, then we need to synthesize a namespace object for
|
|
@@ -1274,6 +1499,7 @@ ${code}
|
|
|
1274
1499
|
// Insert the __esModule interop flag for this module if it has a `default` export
|
|
1275
1500
|
// and the namespace symbol is used.
|
|
1276
1501
|
// TODO: only if required by CJS?
|
|
1502
|
+
|
|
1277
1503
|
if (asset.symbols.hasExportSymbol('default') && usedSymbols.has('*')) {
|
|
1278
1504
|
prepend += `\n$parcel$defineInteropFlag($${assetId}$exports);\n`;
|
|
1279
1505
|
prependLineCount += 2;
|
|
@@ -1337,6 +1563,7 @@ ${code}
|
|
|
1337
1563
|
let resolvedSymbol = this.getSymbolResolution(
|
|
1338
1564
|
asset,
|
|
1339
1565
|
resolved,
|
|
1566
|
+
|
|
1340
1567
|
symbol,
|
|
1341
1568
|
undefined,
|
|
1342
1569
|
replacements,
|
|
@@ -1388,28 +1615,39 @@ ${code}
|
|
|
1388
1615
|
// for the symbol so that when the value changes the object property also changes. This is
|
|
1389
1616
|
// required to simulate ESM live bindings. It's easier to do it this way rather than inserting
|
|
1390
1617
|
// additional assignments after each mutation of the original binding.
|
|
1391
|
-
|
|
1392
|
-
.
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1618
|
+
for (let exp of usedExports) {
|
|
1619
|
+
let resolved = this.getSymbolResolution(
|
|
1620
|
+
asset,
|
|
1621
|
+
asset,
|
|
1622
|
+
exp,
|
|
1623
|
+
undefined,
|
|
1624
|
+
replacements,
|
|
1625
|
+
);
|
|
1626
|
+
const meta = asset.symbols.get(exp)?.meta;
|
|
1627
|
+
if (
|
|
1628
|
+
getFeatureFlag('exportsRebindingOptimisation') &&
|
|
1629
|
+
(meta?.isStaticBindingSafe ||
|
|
1630
|
+
this.manualStaticBindingExports?.some((regex) =>
|
|
1631
|
+
regex.test(asset.filePath),
|
|
1632
|
+
))
|
|
1633
|
+
) {
|
|
1634
|
+
append += `$${assetId}$exports[${JSON.stringify(
|
|
1396
1635
|
exp,
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
);
|
|
1636
|
+
)}] = ${resolved};\n`;
|
|
1637
|
+
} else {
|
|
1400
1638
|
let get = this.buildFunctionExpression([], resolved);
|
|
1401
1639
|
let isEsmExport = !!asset.symbols.get(exp)?.meta?.isEsm;
|
|
1402
1640
|
let set =
|
|
1403
1641
|
!isEsmExport && asset.meta.hasCJSExports
|
|
1404
1642
|
? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`)
|
|
1405
1643
|
: '';
|
|
1406
|
-
|
|
1644
|
+
prepend += `$parcel$export($${assetId}$exports, ${JSON.stringify(
|
|
1407
1645
|
exp,
|
|
1408
|
-
)}, ${get}${set})
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1646
|
+
)}, ${get}${set});\n`;
|
|
1647
|
+
this.usedHelpers.add('$parcel$export');
|
|
1648
|
+
prependLineCount += 1 + usedExports.length;
|
|
1649
|
+
}
|
|
1650
|
+
}
|
|
1413
1651
|
}
|
|
1414
1652
|
}
|
|
1415
1653
|
|
|
@@ -1448,9 +1686,11 @@ ${code}
|
|
|
1448
1686
|
}
|
|
1449
1687
|
|
|
1450
1688
|
for (let helper of this.usedHelpers) {
|
|
1451
|
-
let currentHelper = helpers[helper];
|
|
1689
|
+
let currentHelper = (helpers as Record<string, any>)[helper];
|
|
1452
1690
|
if (typeof currentHelper === 'function') {
|
|
1453
|
-
currentHelper = helpers[helper](
|
|
1691
|
+
currentHelper = (helpers as Record<string, any>)[helper](
|
|
1692
|
+
this.bundle.env,
|
|
1693
|
+
);
|
|
1454
1694
|
}
|
|
1455
1695
|
res += currentHelper;
|
|
1456
1696
|
if (enableSourceMaps) {
|
|
@@ -1470,11 +1710,14 @@ ${code}
|
|
|
1470
1710
|
.some((g) => this.bundleGraph.isEntryBundleGroup(g)) ||
|
|
1471
1711
|
this.bundle.env.isIsolated() ||
|
|
1472
1712
|
this.bundle.bundleBehavior === 'isolated' ||
|
|
1713
|
+
this.bundle.bundleBehavior === 'inlineIsolated' ||
|
|
1473
1714
|
// Conditional deps may be loaded before entrypoints on the server
|
|
1474
1715
|
this.hasConditionalDependency();
|
|
1475
1716
|
|
|
1476
1717
|
if (mightBeFirstJS) {
|
|
1477
|
-
let preludeCode =
|
|
1718
|
+
let preludeCode = (
|
|
1719
|
+
getFeatureFlag('useNewPrelude') ? preludeNew : preludeOld
|
|
1720
|
+
)(this.parcelRequireName);
|
|
1478
1721
|
res += preludeCode;
|
|
1479
1722
|
if (enableSourceMaps) {
|
|
1480
1723
|
lines += countLines(preludeCode) - 1;
|
|
@@ -1498,7 +1741,11 @@ ${code}
|
|
|
1498
1741
|
}
|
|
1499
1742
|
|
|
1500
1743
|
// Add importScripts for sibling bundles in workers.
|
|
1501
|
-
if (
|
|
1744
|
+
if (
|
|
1745
|
+
this.bundle.env.isWorker() ||
|
|
1746
|
+
this.bundle.env.isTesseract() ||
|
|
1747
|
+
this.bundle.env.isWorklet()
|
|
1748
|
+
) {
|
|
1502
1749
|
let importScripts = '';
|
|
1503
1750
|
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
|
|
1504
1751
|
for (let b of bundles) {
|