@atlaspack/packager-js 2.14.5-canary.28 → 2.14.5-canary.280
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 +396 -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 +1374 -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 +271 -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} +433 -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,30 @@ 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
|
+
if (this.wrappedAssets.has(asset)) {
|
|
696
|
+
// If both the asset and the dep are wrapped there's no need to
|
|
697
|
+
// drop a side-effect require. This is an extremely rare case.
|
|
698
|
+
continue;
|
|
699
|
+
}
|
|
700
|
+
|
|
701
|
+
// When the dep is wrapped then we just need to drop a side effect
|
|
702
|
+
// require instead of inlining
|
|
703
|
+
depCode += `parcelRequire("${this.bundleGraph.getAssetPublicId(resolved)}");\n`;
|
|
704
|
+
lineCount += 1;
|
|
705
|
+
} else {
|
|
706
|
+
let [code, map, lines] = this.visitAsset(resolved);
|
|
707
|
+
depCode += code + '\n';
|
|
708
|
+
if (sourceMap && map) {
|
|
709
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
710
|
+
sourceMap.addSourceMap(map, lineCount);
|
|
711
|
+
}
|
|
712
|
+
lineCount += lines + 1;
|
|
570
713
|
}
|
|
571
|
-
lineCount += lines + 1;
|
|
572
714
|
}
|
|
573
715
|
}
|
|
574
716
|
|
|
@@ -602,7 +744,7 @@ export class ScopeHoistingPackager {
|
|
|
602
744
|
code += append;
|
|
603
745
|
|
|
604
746
|
let lineCount = 0;
|
|
605
|
-
let depContent = [];
|
|
747
|
+
let depContent: Array<[string, SourceMap | null | undefined, number]> = [];
|
|
606
748
|
if (depMap.size === 0 && replacements.size === 0) {
|
|
607
749
|
// If there are no dependencies or replacements, use a simple function to count the number of lines.
|
|
608
750
|
lineCount = countLines(code) - 1;
|
|
@@ -647,27 +789,68 @@ export class ScopeHoistingPackager {
|
|
|
647
789
|
// after the dependency is declared. This handles the case where the resulting asset
|
|
648
790
|
// is wrapped, but the dependency in this asset is not marked as wrapped. This means
|
|
649
791
|
// that it was imported/required at the top-level, so its side effects should run immediately.
|
|
650
|
-
let
|
|
651
|
-
|
|
652
|
-
dep,
|
|
653
|
-
resolved,
|
|
654
|
-
);
|
|
792
|
+
let res = '';
|
|
793
|
+
let lines = 0;
|
|
655
794
|
let map;
|
|
795
|
+
|
|
796
|
+
if (!getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
797
|
+
[res, lines] = this.getHoistedParcelRequires(
|
|
798
|
+
asset,
|
|
799
|
+
dep,
|
|
800
|
+
resolved,
|
|
801
|
+
);
|
|
802
|
+
}
|
|
803
|
+
|
|
656
804
|
if (
|
|
657
805
|
this.bundle.hasAsset(resolved) &&
|
|
658
|
-
!this.seenAssets.has(resolved
|
|
806
|
+
!this.seenAssets.has(resolved)
|
|
659
807
|
) {
|
|
660
808
|
// If this asset is wrapped, we need to hoist the code for the dependency
|
|
661
809
|
// outside our parcelRequire.register wrapper. This is safe because all
|
|
662
810
|
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
663
811
|
// asset content where the import statement was.
|
|
664
|
-
if (
|
|
665
|
-
|
|
812
|
+
if (this.useBothScopeHoistingImprovements) {
|
|
813
|
+
if (
|
|
814
|
+
!resolved.meta.isConstantModule &&
|
|
815
|
+
!this.wrappedAssets.has(resolved)
|
|
816
|
+
) {
|
|
817
|
+
let [depCode, depMap, depLines] =
|
|
818
|
+
this.visitAsset(resolved);
|
|
819
|
+
if (debugTools['asset-file-names-in-output']) {
|
|
820
|
+
let resolvedPath = this.getAssetFilePath(resolved);
|
|
821
|
+
res = outdent`
|
|
822
|
+
/* Scope hoisted asset: ${resolvedPath} */
|
|
823
|
+
${depCode}
|
|
824
|
+
/* End: ${resolvedPath} */
|
|
825
|
+
${res}
|
|
826
|
+
`;
|
|
827
|
+
lines += 3 + depLines;
|
|
828
|
+
} else {
|
|
829
|
+
res = depCode + '\n' + res;
|
|
830
|
+
lines += 1 + depLines;
|
|
831
|
+
}
|
|
832
|
+
map = depMap;
|
|
833
|
+
}
|
|
666
834
|
} else {
|
|
667
|
-
|
|
668
|
-
|
|
669
|
-
|
|
670
|
-
|
|
835
|
+
if (shouldWrap) {
|
|
836
|
+
depContent.push(this.visitAsset(resolved));
|
|
837
|
+
} else {
|
|
838
|
+
let [depCode, depMap, depLines] =
|
|
839
|
+
this.visitAsset(resolved);
|
|
840
|
+
res = depCode + '\n' + res;
|
|
841
|
+
lines += 1 + depLines;
|
|
842
|
+
map = depMap;
|
|
843
|
+
}
|
|
844
|
+
}
|
|
845
|
+
}
|
|
846
|
+
|
|
847
|
+
if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
848
|
+
let [requiresCode, requiresLines] =
|
|
849
|
+
this.getHoistedParcelRequires(asset, dep, resolved);
|
|
850
|
+
|
|
851
|
+
if (requiresCode) {
|
|
852
|
+
res = requiresCode + '\n' + res;
|
|
853
|
+
lines += requiresLines + 1;
|
|
671
854
|
}
|
|
672
855
|
}
|
|
673
856
|
|
|
@@ -679,6 +862,7 @@ export class ScopeHoistingPackager {
|
|
|
679
862
|
}
|
|
680
863
|
|
|
681
864
|
if (map) {
|
|
865
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
682
866
|
sourceMap.addSourceMap(map, lineCount);
|
|
683
867
|
}
|
|
684
868
|
}
|
|
@@ -726,10 +910,16 @@ ${code}
|
|
|
726
910
|
|
|
727
911
|
lineCount += 2;
|
|
728
912
|
|
|
913
|
+
if (debugTools['asset-file-names-in-output']) {
|
|
914
|
+
code = `/* ${this.getAssetFilePath(asset)} */\n` + code;
|
|
915
|
+
lineCount += 1;
|
|
916
|
+
}
|
|
917
|
+
|
|
729
918
|
for (let [depCode, map, lines] of depContent) {
|
|
730
919
|
if (!depCode) continue;
|
|
731
920
|
code += depCode + '\n';
|
|
732
921
|
if (sourceMap && map) {
|
|
922
|
+
// @ts-expect-error TS2551 - addSourceMap method exists but missing from @parcel/source-map type definitions
|
|
733
923
|
sourceMap.addSourceMap(map, lineCount);
|
|
734
924
|
}
|
|
735
925
|
lineCount += lines + 1;
|
|
@@ -848,7 +1038,7 @@ ${code}
|
|
|
848
1038
|
// If this asset is wrapped, we need to replace the exports namespace with `module.exports`,
|
|
849
1039
|
// which will be provided to us by the wrapper.
|
|
850
1040
|
if (
|
|
851
|
-
this.wrappedAssets.has(asset
|
|
1041
|
+
this.wrappedAssets.has(asset) ||
|
|
852
1042
|
(this.bundle.env.outputFormat === 'commonjs' &&
|
|
853
1043
|
asset === this.bundle.getMainEntry())
|
|
854
1044
|
) {
|
|
@@ -895,7 +1085,9 @@ ${code}
|
|
|
895
1085
|
|
|
896
1086
|
for (let [imported, {local}] of dep.symbols) {
|
|
897
1087
|
// If already imported, just add the already renamed variable to the mapping.
|
|
1088
|
+
|
|
898
1089
|
let renamed = external.get(imported);
|
|
1090
|
+
|
|
899
1091
|
if (renamed && local !== '*' && replacements) {
|
|
900
1092
|
replacements.set(local, renamed);
|
|
901
1093
|
continue;
|
|
@@ -908,6 +1100,7 @@ ${code}
|
|
|
908
1100
|
if (!renamed) {
|
|
909
1101
|
if (referencedBundle) {
|
|
910
1102
|
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
1103
|
+
|
|
911
1104
|
renamed =
|
|
912
1105
|
entry.symbols.get('*')?.local ??
|
|
913
1106
|
`$${String(entry.meta.id)}$exports`;
|
|
@@ -922,6 +1115,7 @@ ${code}
|
|
|
922
1115
|
|
|
923
1116
|
if (local !== '*' && replacements) {
|
|
924
1117
|
let replacement;
|
|
1118
|
+
|
|
925
1119
|
if (imported === '*') {
|
|
926
1120
|
replacement = renamed;
|
|
927
1121
|
} else if (imported === 'default') {
|
|
@@ -946,10 +1140,12 @@ ${code}
|
|
|
946
1140
|
let property;
|
|
947
1141
|
if (referencedBundle) {
|
|
948
1142
|
let entry = nullthrows(referencedBundle.getMainEntry());
|
|
1143
|
+
|
|
949
1144
|
if (entry.symbols.hasExportSymbol('*')) {
|
|
950
1145
|
// If importing * and the referenced module has a * export (e.g. CJS), use default instead.
|
|
951
1146
|
// This mirrors the logic in buildExportedSymbols.
|
|
952
1147
|
property = imported;
|
|
1148
|
+
|
|
953
1149
|
imported =
|
|
954
1150
|
referencedBundle?.env.outputFormat === 'esmodule'
|
|
955
1151
|
? 'default'
|
|
@@ -957,6 +1153,7 @@ ${code}
|
|
|
957
1153
|
} else {
|
|
958
1154
|
if (imported === '*') {
|
|
959
1155
|
let exportedSymbols = this.bundleGraph.getExportedSymbols(entry);
|
|
1156
|
+
|
|
960
1157
|
if (local === '*') {
|
|
961
1158
|
// Re-export all symbols.
|
|
962
1159
|
for (let exported of exportedSymbols) {
|
|
@@ -967,11 +1164,10 @@ ${code}
|
|
|
967
1164
|
continue;
|
|
968
1165
|
}
|
|
969
1166
|
}
|
|
970
|
-
|
|
971
|
-
|
|
972
|
-
imported,
|
|
973
|
-
|
|
974
|
-
).symbol;
|
|
1167
|
+
|
|
1168
|
+
renamed =
|
|
1169
|
+
this.bundleGraph.getSymbolResolution(entry, imported, this.bundle)
|
|
1170
|
+
.symbol || undefined;
|
|
975
1171
|
}
|
|
976
1172
|
}
|
|
977
1173
|
|
|
@@ -993,8 +1189,10 @@ ${code}
|
|
|
993
1189
|
}
|
|
994
1190
|
|
|
995
1191
|
external.set(imported, renamed);
|
|
1192
|
+
|
|
996
1193
|
if (local !== '*' && replacements) {
|
|
997
1194
|
let replacement = renamed;
|
|
1195
|
+
|
|
998
1196
|
if (property === '*') {
|
|
999
1197
|
replacement = renamed;
|
|
1000
1198
|
} else if (property === 'default') {
|
|
@@ -1003,6 +1201,7 @@ ${code}
|
|
|
1003
1201
|
} else if (property) {
|
|
1004
1202
|
replacement = this.getPropertyAccess(renamed, property);
|
|
1005
1203
|
}
|
|
1204
|
+
|
|
1006
1205
|
replacements.set(local, replacement);
|
|
1007
1206
|
}
|
|
1008
1207
|
}
|
|
@@ -1026,7 +1225,7 @@ ${code}
|
|
|
1026
1225
|
}
|
|
1027
1226
|
return (
|
|
1028
1227
|
(!this.bundle.hasAsset(resolved) && !this.externalAssets.has(resolved)) ||
|
|
1029
|
-
(this.wrappedAssets.has(resolved
|
|
1228
|
+
(this.wrappedAssets.has(resolved) && resolved !== parentAsset)
|
|
1030
1229
|
);
|
|
1031
1230
|
}
|
|
1032
1231
|
|
|
@@ -1076,14 +1275,14 @@ ${code}
|
|
|
1076
1275
|
(!this.bundle.hasAsset(resolvedAsset) ||
|
|
1077
1276
|
!this.shouldSkipAsset(resolvedAsset))
|
|
1078
1277
|
) {
|
|
1079
|
-
let hoisted = this.hoistedRequires.get(dep
|
|
1278
|
+
let hoisted = this.hoistedRequires.get(dep);
|
|
1080
1279
|
if (!hoisted) {
|
|
1081
1280
|
hoisted = new Map();
|
|
1082
|
-
this.hoistedRequires.set(dep
|
|
1281
|
+
this.hoistedRequires.set(dep, hoisted);
|
|
1083
1282
|
}
|
|
1084
1283
|
|
|
1085
1284
|
hoisted.set(
|
|
1086
|
-
resolvedAsset
|
|
1285
|
+
resolvedAsset,
|
|
1087
1286
|
`var $${publicId} = parcelRequire(${JSON.stringify(publicId)});`,
|
|
1088
1287
|
);
|
|
1089
1288
|
}
|
|
@@ -1117,6 +1316,7 @@ ${code}
|
|
|
1117
1316
|
obj = `$${publicId}`;
|
|
1118
1317
|
} else {
|
|
1119
1318
|
obj = resolvedAsset.symbols.get('*')?.local || `$${assetId}$exports`;
|
|
1319
|
+
|
|
1120
1320
|
obj = replacements?.get(obj) || obj;
|
|
1121
1321
|
}
|
|
1122
1322
|
|
|
@@ -1124,7 +1324,7 @@ ${code}
|
|
|
1124
1324
|
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
|
|
1125
1325
|
if (
|
|
1126
1326
|
parentAsset === resolvedAsset &&
|
|
1127
|
-
this.wrappedAssets.has(resolvedAsset
|
|
1327
|
+
this.wrappedAssets.has(resolvedAsset)
|
|
1128
1328
|
) {
|
|
1129
1329
|
// Directly use module.exports for wrapped assets importing themselves.
|
|
1130
1330
|
return 'module.exports';
|
|
@@ -1167,7 +1367,7 @@ ${code}
|
|
|
1167
1367
|
return ['', 0];
|
|
1168
1368
|
}
|
|
1169
1369
|
|
|
1170
|
-
let hoisted = this.hoistedRequires.get(dep
|
|
1370
|
+
let hoisted = this.hoistedRequires.get(dep);
|
|
1171
1371
|
let res = '';
|
|
1172
1372
|
let lineCount = 0;
|
|
1173
1373
|
let isWrapped = this.isWrapped(resolved, parentAsset);
|
|
@@ -1179,7 +1379,7 @@ ${code}
|
|
|
1179
1379
|
if (
|
|
1180
1380
|
isWrapped &&
|
|
1181
1381
|
!dep.meta.shouldWrap &&
|
|
1182
|
-
(!hoisted || hoisted.keys().next().value !== resolved
|
|
1382
|
+
(!hoisted || hoisted.keys().next().value !== resolved) &&
|
|
1183
1383
|
!this.bundleGraph.isDependencySkipped(dep) &&
|
|
1184
1384
|
!this.shouldSkipAsset(resolved)
|
|
1185
1385
|
) {
|
|
@@ -1191,8 +1391,22 @@ ${code}
|
|
|
1191
1391
|
|
|
1192
1392
|
if (hoisted) {
|
|
1193
1393
|
this.needsPrelude = true;
|
|
1194
|
-
|
|
1195
|
-
|
|
1394
|
+
|
|
1395
|
+
if (getFeatureFlag('applyScopeHoistingImprovementV2')) {
|
|
1396
|
+
let hoistedValues = [...hoisted.values()].filter(
|
|
1397
|
+
(val) => !this.seenHoistedRequires.has(val),
|
|
1398
|
+
);
|
|
1399
|
+
|
|
1400
|
+
for (let val of hoistedValues) {
|
|
1401
|
+
this.seenHoistedRequires.add(val);
|
|
1402
|
+
}
|
|
1403
|
+
|
|
1404
|
+
res += '\n' + hoistedValues.join('\n');
|
|
1405
|
+
lineCount += hoisted.size;
|
|
1406
|
+
} else {
|
|
1407
|
+
res += '\n' + [...hoisted.values()].join('\n');
|
|
1408
|
+
lineCount += hoisted.size;
|
|
1409
|
+
}
|
|
1196
1410
|
}
|
|
1197
1411
|
|
|
1198
1412
|
return [res, lineCount];
|
|
@@ -1207,7 +1421,7 @@ ${code}
|
|
|
1207
1421
|
let prependLineCount = 0;
|
|
1208
1422
|
let append = '';
|
|
1209
1423
|
|
|
1210
|
-
let shouldWrap = this.wrappedAssets.has(asset
|
|
1424
|
+
let shouldWrap = this.wrappedAssets.has(asset);
|
|
1211
1425
|
let usedSymbols = nullthrows(this.bundleGraph.getUsedSymbols(asset));
|
|
1212
1426
|
let assetId = asset.meta.id;
|
|
1213
1427
|
invariant(typeof assetId === 'string');
|
|
@@ -1220,34 +1434,51 @@ ${code}
|
|
|
1220
1434
|
usedSymbols.has('default') &&
|
|
1221
1435
|
!asset.symbols.hasExportSymbol('__esModule');
|
|
1222
1436
|
|
|
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
|
-
|
|
1437
|
+
let usedNamespace;
|
|
1438
|
+
if (
|
|
1439
|
+
getFeatureFlag('inlineConstOptimisationFix') &&
|
|
1440
|
+
asset.meta.isConstantModule
|
|
1441
|
+
) {
|
|
1442
|
+
// Only set usedNamespace if there is an incoming dependency in the current bundle that uses '*'
|
|
1443
|
+
usedNamespace = this.bundleGraph
|
|
1444
|
+
.getIncomingDependencies(asset)
|
|
1445
|
+
.some(
|
|
1446
|
+
(dep) =>
|
|
1447
|
+
this.bundle.hasDependency(dep) &&
|
|
1448
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1449
|
+
);
|
|
1450
|
+
} else {
|
|
1451
|
+
usedNamespace =
|
|
1452
|
+
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
1453
|
+
// The one case where this isn't true is in ESM library entries, where the only
|
|
1454
|
+
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
1455
|
+
// instead of the namespace object.
|
|
1456
|
+
|
|
1457
|
+
(usedSymbols.has('*') &&
|
|
1458
|
+
(this.bundle.env.outputFormat !== 'esmodule' ||
|
|
1459
|
+
!this.bundle.env.isLibrary ||
|
|
1460
|
+
asset !== this.bundle.getMainEntry() ||
|
|
1461
|
+
this.bundleGraph
|
|
1462
|
+
.getIncomingDependencies(asset)
|
|
1463
|
+
.some(
|
|
1464
|
+
(dep) =>
|
|
1465
|
+
!dep.isEntry &&
|
|
1466
|
+
this.bundle.hasDependency(dep) &&
|
|
1467
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1468
|
+
))) ||
|
|
1469
|
+
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
1470
|
+
// we fallback on the namespace object.
|
|
1471
|
+
|
|
1472
|
+
(asset.symbols.hasExportSymbol('*') &&
|
|
1473
|
+
[...usedSymbols].some((s) => !asset.symbols.hasExportSymbol(s))) ||
|
|
1474
|
+
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
1475
|
+
// include the namespace object for the default export.
|
|
1476
|
+
this.exportedSymbols.has(`$${assetId}$exports`) ||
|
|
1477
|
+
// CommonJS library bundle entries always need a namespace.
|
|
1478
|
+
(this.bundle.env.isLibrary &&
|
|
1479
|
+
this.bundle.env.outputFormat === 'commonjs' &&
|
|
1480
|
+
asset === this.bundle.getMainEntry());
|
|
1481
|
+
}
|
|
1251
1482
|
|
|
1252
1483
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
1253
1484
|
// or we need default interop, then we need to synthesize a namespace object for
|
|
@@ -1274,6 +1505,7 @@ ${code}
|
|
|
1274
1505
|
// Insert the __esModule interop flag for this module if it has a `default` export
|
|
1275
1506
|
// and the namespace symbol is used.
|
|
1276
1507
|
// TODO: only if required by CJS?
|
|
1508
|
+
|
|
1277
1509
|
if (asset.symbols.hasExportSymbol('default') && usedSymbols.has('*')) {
|
|
1278
1510
|
prepend += `\n$parcel$defineInteropFlag($${assetId}$exports);\n`;
|
|
1279
1511
|
prependLineCount += 2;
|
|
@@ -1337,6 +1569,7 @@ ${code}
|
|
|
1337
1569
|
let resolvedSymbol = this.getSymbolResolution(
|
|
1338
1570
|
asset,
|
|
1339
1571
|
resolved,
|
|
1572
|
+
|
|
1340
1573
|
symbol,
|
|
1341
1574
|
undefined,
|
|
1342
1575
|
replacements,
|
|
@@ -1388,28 +1621,39 @@ ${code}
|
|
|
1388
1621
|
// for the symbol so that when the value changes the object property also changes. This is
|
|
1389
1622
|
// required to simulate ESM live bindings. It's easier to do it this way rather than inserting
|
|
1390
1623
|
// additional assignments after each mutation of the original binding.
|
|
1391
|
-
|
|
1392
|
-
.
|
|
1393
|
-
|
|
1394
|
-
|
|
1395
|
-
|
|
1624
|
+
for (let exp of usedExports) {
|
|
1625
|
+
let resolved = this.getSymbolResolution(
|
|
1626
|
+
asset,
|
|
1627
|
+
asset,
|
|
1628
|
+
exp,
|
|
1629
|
+
undefined,
|
|
1630
|
+
replacements,
|
|
1631
|
+
);
|
|
1632
|
+
const meta = asset.symbols.get(exp)?.meta;
|
|
1633
|
+
if (
|
|
1634
|
+
getFeatureFlag('exportsRebindingOptimisation') &&
|
|
1635
|
+
(meta?.isStaticBindingSafe ||
|
|
1636
|
+
this.manualStaticBindingExports?.some((regex) =>
|
|
1637
|
+
regex.test(asset.filePath),
|
|
1638
|
+
))
|
|
1639
|
+
) {
|
|
1640
|
+
append += `$${assetId}$exports[${JSON.stringify(
|
|
1396
1641
|
exp,
|
|
1397
|
-
|
|
1398
|
-
|
|
1399
|
-
);
|
|
1642
|
+
)}] = ${resolved};\n`;
|
|
1643
|
+
} else {
|
|
1400
1644
|
let get = this.buildFunctionExpression([], resolved);
|
|
1401
1645
|
let isEsmExport = !!asset.symbols.get(exp)?.meta?.isEsm;
|
|
1402
1646
|
let set =
|
|
1403
1647
|
!isEsmExport && asset.meta.hasCJSExports
|
|
1404
1648
|
? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`)
|
|
1405
1649
|
: '';
|
|
1406
|
-
|
|
1650
|
+
prepend += `$parcel$export($${assetId}$exports, ${JSON.stringify(
|
|
1407
1651
|
exp,
|
|
1408
|
-
)}, ${get}${set})
|
|
1409
|
-
|
|
1410
|
-
|
|
1411
|
-
|
|
1412
|
-
|
|
1652
|
+
)}, ${get}${set});\n`;
|
|
1653
|
+
this.usedHelpers.add('$parcel$export');
|
|
1654
|
+
prependLineCount += 1 + usedExports.length;
|
|
1655
|
+
}
|
|
1656
|
+
}
|
|
1413
1657
|
}
|
|
1414
1658
|
}
|
|
1415
1659
|
|
|
@@ -1448,9 +1692,11 @@ ${code}
|
|
|
1448
1692
|
}
|
|
1449
1693
|
|
|
1450
1694
|
for (let helper of this.usedHelpers) {
|
|
1451
|
-
let currentHelper = helpers[helper];
|
|
1695
|
+
let currentHelper = (helpers as Record<string, any>)[helper];
|
|
1452
1696
|
if (typeof currentHelper === 'function') {
|
|
1453
|
-
currentHelper = helpers[helper](
|
|
1697
|
+
currentHelper = (helpers as Record<string, any>)[helper](
|
|
1698
|
+
this.bundle.env,
|
|
1699
|
+
);
|
|
1454
1700
|
}
|
|
1455
1701
|
res += currentHelper;
|
|
1456
1702
|
if (enableSourceMaps) {
|
|
@@ -1470,11 +1716,14 @@ ${code}
|
|
|
1470
1716
|
.some((g) => this.bundleGraph.isEntryBundleGroup(g)) ||
|
|
1471
1717
|
this.bundle.env.isIsolated() ||
|
|
1472
1718
|
this.bundle.bundleBehavior === 'isolated' ||
|
|
1719
|
+
this.bundle.bundleBehavior === 'inlineIsolated' ||
|
|
1473
1720
|
// Conditional deps may be loaded before entrypoints on the server
|
|
1474
1721
|
this.hasConditionalDependency();
|
|
1475
1722
|
|
|
1476
1723
|
if (mightBeFirstJS) {
|
|
1477
|
-
let preludeCode =
|
|
1724
|
+
let preludeCode = (
|
|
1725
|
+
getFeatureFlag('useNewPrelude') ? preludeNew : preludeOld
|
|
1726
|
+
)(this.parcelRequireName);
|
|
1478
1727
|
res += preludeCode;
|
|
1479
1728
|
if (enableSourceMaps) {
|
|
1480
1729
|
lines += countLines(preludeCode) - 1;
|
|
@@ -1498,7 +1747,11 @@ ${code}
|
|
|
1498
1747
|
}
|
|
1499
1748
|
|
|
1500
1749
|
// Add importScripts for sibling bundles in workers.
|
|
1501
|
-
if (
|
|
1750
|
+
if (
|
|
1751
|
+
this.bundle.env.isWorker() ||
|
|
1752
|
+
this.bundle.env.isTesseract() ||
|
|
1753
|
+
this.bundle.env.isWorklet()
|
|
1754
|
+
) {
|
|
1502
1755
|
let importScripts = '';
|
|
1503
1756
|
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
|
|
1504
1757
|
for (let b of bundles) {
|