@parcel/packager-js 2.0.0-beta.3.1 → 2.0.0-dev.1510
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/lib/CJSOutputFormat.js +6 -110
- package/lib/DevPackager.js +50 -70
- package/lib/ESMOutputFormat.js +26 -38
- package/lib/GlobalOutputFormat.js +3 -11
- package/lib/ScopeHoistingPackager.js +535 -492
- package/lib/dev-prelude.js +10 -8
- package/lib/helpers.js +78 -30
- package/lib/index.js +71 -52
- package/lib/utils.js +51 -0
- package/package.json +9 -7
- package/src/.eslintrc.json +13 -0
- package/src/CJSOutputFormat.js +7 -119
- package/src/DevPackager.js +76 -22
- package/src/ESMOutputFormat.js +34 -5
- package/src/GlobalOutputFormat.js +6 -3
- package/src/ScopeHoistingPackager.js +640 -337
- package/src/dev-prelude.js +10 -8
- package/src/helpers.js +121 -27
- package/src/index.js +89 -26
- package/src/utils.js +57 -0
|
@@ -8,23 +8,38 @@ import type {
|
|
|
8
8
|
NamedBundle,
|
|
9
9
|
} from '@parcel/types';
|
|
10
10
|
|
|
11
|
-
import {
|
|
11
|
+
import {
|
|
12
|
+
DefaultMap,
|
|
13
|
+
PromiseQueue,
|
|
14
|
+
relativeBundlePath,
|
|
15
|
+
countLines,
|
|
16
|
+
normalizeSeparators,
|
|
17
|
+
} from '@parcel/utils';
|
|
12
18
|
import SourceMap from '@parcel/source-map';
|
|
13
19
|
import nullthrows from 'nullthrows';
|
|
14
20
|
import invariant from 'assert';
|
|
15
|
-
import ThrowableDiagnostic
|
|
21
|
+
import ThrowableDiagnostic, {
|
|
22
|
+
convertSourceLocationToHighlight,
|
|
23
|
+
} from '@parcel/diagnostic';
|
|
16
24
|
import globals from 'globals';
|
|
25
|
+
import path from 'path';
|
|
17
26
|
|
|
18
27
|
import {ESMOutputFormat} from './ESMOutputFormat';
|
|
19
28
|
import {CJSOutputFormat} from './CJSOutputFormat';
|
|
20
29
|
import {GlobalOutputFormat} from './GlobalOutputFormat';
|
|
21
|
-
import {prelude, helpers} from './helpers';
|
|
30
|
+
import {prelude, helpers, bundleQueuePrelude, fnExpr} from './helpers';
|
|
31
|
+
import {replaceScriptDependencies, getSpecifier} from './utils';
|
|
22
32
|
|
|
23
33
|
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
|
|
24
34
|
const IDENTIFIER_RE = /^[$_\p{ID_Start}][$_\u200C\u200D\p{ID_Continue}]*$/u;
|
|
25
35
|
const ID_START_RE = /^[$_\p{ID_Start}]/u;
|
|
26
36
|
const NON_ID_CONTINUE_RE = /[^$_\u200C\u200D\p{ID_Continue}]/gu;
|
|
27
37
|
|
|
38
|
+
// General regex used to replace imports with the resolved code, references with resolutions,
|
|
39
|
+
// and count the number of newlines in the file for source maps.
|
|
40
|
+
const REPLACEMENT_RE =
|
|
41
|
+
/\n|import\s+"([0-9a-f]{16}:.+?)";|(?:\$[0-9a-f]{16}\$exports)|(?:\$[0-9a-f]{16}\$(?:import|importAsync|require)\$[0-9a-f]+(?:\$[0-9a-f]+)?)/g;
|
|
42
|
+
|
|
28
43
|
const BUILTINS = Object.keys(globals.builtin);
|
|
29
44
|
const GLOBALS_BY_CONTEXT = {
|
|
30
45
|
browser: new Set([...BUILTINS, ...Object.keys(globals.browser)]),
|
|
@@ -33,6 +48,7 @@ const GLOBALS_BY_CONTEXT = {
|
|
|
33
48
|
...BUILTINS,
|
|
34
49
|
...Object.keys(globals.serviceworker),
|
|
35
50
|
]),
|
|
51
|
+
worklet: new Set([...BUILTINS]),
|
|
36
52
|
node: new Set([...BUILTINS, ...Object.keys(globals.node)]),
|
|
37
53
|
'electron-main': new Set([...BUILTINS, ...Object.keys(globals.node)]),
|
|
38
54
|
'electron-renderer': new Set([
|
|
@@ -50,7 +66,7 @@ const OUTPUT_FORMATS = {
|
|
|
50
66
|
|
|
51
67
|
export interface OutputFormat {
|
|
52
68
|
buildBundlePrelude(): [string, number];
|
|
53
|
-
buildBundlePostlude(): string;
|
|
69
|
+
buildBundlePostlude(): [string, number];
|
|
54
70
|
}
|
|
55
71
|
|
|
56
72
|
export class ScopeHoistingPackager {
|
|
@@ -58,13 +74,19 @@ export class ScopeHoistingPackager {
|
|
|
58
74
|
bundleGraph: BundleGraph<NamedBundle>;
|
|
59
75
|
bundle: NamedBundle;
|
|
60
76
|
parcelRequireName: string;
|
|
77
|
+
useAsyncBundleRuntime: boolean;
|
|
61
78
|
outputFormat: OutputFormat;
|
|
62
79
|
isAsyncBundle: boolean;
|
|
63
80
|
globalNames: $ReadOnlySet<string>;
|
|
64
81
|
assetOutputs: Map<string, {|code: string, map: ?Buffer|}>;
|
|
65
82
|
exportedSymbols: Map<
|
|
66
83
|
string,
|
|
67
|
-
|
|
84
|
+
{|
|
|
85
|
+
asset: Asset,
|
|
86
|
+
exportSymbol: string,
|
|
87
|
+
local: string,
|
|
88
|
+
exportAs: Array<string>,
|
|
89
|
+
|},
|
|
68
90
|
> = new Map();
|
|
69
91
|
externals: Map<string, Map<string, string>> = new Map();
|
|
70
92
|
topLevelNames: Map<string, number> = new Map();
|
|
@@ -73,17 +95,20 @@ export class ScopeHoistingPackager {
|
|
|
73
95
|
hoistedRequires: Map<string, Map<string, string>> = new Map();
|
|
74
96
|
needsPrelude: boolean = false;
|
|
75
97
|
usedHelpers: Set<string> = new Set();
|
|
98
|
+
externalAssets: Set<Asset> = new Set();
|
|
76
99
|
|
|
77
100
|
constructor(
|
|
78
101
|
options: PluginOptions,
|
|
79
102
|
bundleGraph: BundleGraph<NamedBundle>,
|
|
80
103
|
bundle: NamedBundle,
|
|
81
104
|
parcelRequireName: string,
|
|
105
|
+
useAsyncBundleRuntime: boolean,
|
|
82
106
|
) {
|
|
83
107
|
this.options = options;
|
|
84
108
|
this.bundleGraph = bundleGraph;
|
|
85
109
|
this.bundle = bundle;
|
|
86
110
|
this.parcelRequireName = parcelRequireName;
|
|
111
|
+
this.useAsyncBundleRuntime = useAsyncBundleRuntime;
|
|
87
112
|
|
|
88
113
|
let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
|
|
89
114
|
this.outputFormat = new OutputFormat(this);
|
|
@@ -91,13 +116,13 @@ export class ScopeHoistingPackager {
|
|
|
91
116
|
this.isAsyncBundle =
|
|
92
117
|
this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') &&
|
|
93
118
|
!this.bundle.env.isIsolated() &&
|
|
94
|
-
|
|
119
|
+
this.bundle.bundleBehavior !== 'isolated';
|
|
95
120
|
|
|
96
121
|
this.globalNames = GLOBALS_BY_CONTEXT[bundle.env.context];
|
|
97
122
|
}
|
|
98
123
|
|
|
99
124
|
async package(): Promise<{|contents: string, map: ?SourceMap|}> {
|
|
100
|
-
await this.loadAssets();
|
|
125
|
+
let wrappedAssets = await this.loadAssets();
|
|
101
126
|
this.buildExportedSymbols();
|
|
102
127
|
|
|
103
128
|
// If building a library, the target is actually another bundler rather
|
|
@@ -109,37 +134,66 @@ export class ScopeHoistingPackager {
|
|
|
109
134
|
this.bundle.env.isLibrary ||
|
|
110
135
|
this.bundle.env.outputFormat === 'commonjs'
|
|
111
136
|
) {
|
|
112
|
-
let
|
|
113
|
-
|
|
114
|
-
|
|
137
|
+
for (let b of this.bundleGraph.getReferencedBundles(this.bundle)) {
|
|
138
|
+
let entry = b.getMainEntry();
|
|
139
|
+
let symbols = new Map();
|
|
140
|
+
if (entry && !this.isAsyncBundle && entry.type === 'js') {
|
|
141
|
+
this.externalAssets.add(entry);
|
|
142
|
+
|
|
143
|
+
let usedSymbols = this.bundleGraph.getUsedSymbols(entry) || new Set();
|
|
144
|
+
for (let s of usedSymbols) {
|
|
145
|
+
// If the referenced bundle is ESM, and we are importing '*', use 'default' instead.
|
|
146
|
+
// This matches the logic below in buildExportedSymbols.
|
|
147
|
+
let imported = s;
|
|
148
|
+
if (imported === '*' && b.env.outputFormat === 'esmodule') {
|
|
149
|
+
imported = 'default';
|
|
150
|
+
}
|
|
151
|
+
symbols.set(imported, this.getSymbolResolution(entry, entry, s));
|
|
152
|
+
}
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
this.externals.set(relativeBundlePath(this.bundle, b), symbols);
|
|
115
156
|
}
|
|
116
157
|
}
|
|
117
158
|
|
|
118
|
-
// Add each asset that is directly connected to the bundle. Dependencies will be handled
|
|
119
|
-
// by replacing `import` statements in the code.
|
|
120
159
|
let res = '';
|
|
121
160
|
let lineCount = 0;
|
|
122
|
-
let sourceMap =
|
|
123
|
-
|
|
124
|
-
: null;
|
|
125
|
-
this.bundle.traverseAssets((asset, _, actions) => {
|
|
126
|
-
if (this.seenAssets.has(asset.id)) {
|
|
127
|
-
actions.skipChildren();
|
|
128
|
-
return;
|
|
129
|
-
}
|
|
130
|
-
|
|
161
|
+
let sourceMap = null;
|
|
162
|
+
let processAsset = asset => {
|
|
131
163
|
let [content, map, lines] = this.visitAsset(asset);
|
|
132
164
|
if (sourceMap && map) {
|
|
133
165
|
sourceMap.addSourceMap(map, lineCount);
|
|
166
|
+
} else if (this.bundle.env.sourceMap) {
|
|
167
|
+
sourceMap = map;
|
|
134
168
|
}
|
|
135
169
|
|
|
136
170
|
res += content + '\n';
|
|
137
171
|
lineCount += lines + 1;
|
|
172
|
+
};
|
|
173
|
+
|
|
174
|
+
// Hoist wrapped asset to the top of the bundle to ensure that they are registered
|
|
175
|
+
// before they are used.
|
|
176
|
+
for (let asset of wrappedAssets) {
|
|
177
|
+
if (!this.seenAssets.has(asset.id)) {
|
|
178
|
+
processAsset(asset);
|
|
179
|
+
}
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
// Add each asset that is directly connected to the bundle. Dependencies will be handled
|
|
183
|
+
// by replacing `import` statements in the code.
|
|
184
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
185
|
+
if (this.seenAssets.has(asset.id)) {
|
|
186
|
+
actions.skipChildren();
|
|
187
|
+
return;
|
|
188
|
+
}
|
|
189
|
+
|
|
190
|
+
processAsset(asset);
|
|
138
191
|
actions.skipChildren();
|
|
139
192
|
});
|
|
140
193
|
|
|
141
194
|
let [prelude, preludeLines] = this.buildBundlePrelude();
|
|
142
195
|
res = prelude + res;
|
|
196
|
+
lineCount += preludeLines;
|
|
143
197
|
sourceMap?.offsetLines(1, preludeLines);
|
|
144
198
|
|
|
145
199
|
let entries = this.bundle.getEntryAssets();
|
|
@@ -151,27 +205,72 @@ export class ScopeHoistingPackager {
|
|
|
151
205
|
mainEntry = null;
|
|
152
206
|
}
|
|
153
207
|
|
|
208
|
+
let needsBundleQueue = this.shouldBundleQueue(this.bundle);
|
|
209
|
+
|
|
154
210
|
// If any of the entry assets are wrapped, call parcelRequire so they are executed.
|
|
155
211
|
for (let entry of entries) {
|
|
156
|
-
if (this.wrappedAssets.has(entry.id)) {
|
|
212
|
+
if (this.wrappedAssets.has(entry.id) && !this.isScriptEntry(entry)) {
|
|
157
213
|
let parcelRequire = `parcelRequire(${JSON.stringify(
|
|
158
214
|
this.bundleGraph.getAssetPublicId(entry),
|
|
159
215
|
)});\n`;
|
|
160
216
|
|
|
161
217
|
let entryExports = entry.symbols.get('*')?.local;
|
|
218
|
+
|
|
162
219
|
if (
|
|
163
220
|
entryExports &&
|
|
164
221
|
entry === mainEntry &&
|
|
165
222
|
this.exportedSymbols.has(entryExports)
|
|
166
223
|
) {
|
|
224
|
+
invariant(
|
|
225
|
+
!needsBundleQueue,
|
|
226
|
+
'Entry exports are not yet compaitble with async bundles',
|
|
227
|
+
);
|
|
167
228
|
res += `\nvar ${entryExports} = ${parcelRequire}`;
|
|
168
229
|
} else {
|
|
230
|
+
if (needsBundleQueue) {
|
|
231
|
+
parcelRequire = this.runWhenReady(this.bundle, parcelRequire);
|
|
232
|
+
}
|
|
233
|
+
|
|
169
234
|
res += `\n${parcelRequire}`;
|
|
170
235
|
}
|
|
236
|
+
|
|
237
|
+
lineCount += 2;
|
|
171
238
|
}
|
|
172
239
|
}
|
|
173
240
|
|
|
174
|
-
|
|
241
|
+
let [postlude, postludeLines] = this.outputFormat.buildBundlePostlude();
|
|
242
|
+
res += postlude;
|
|
243
|
+
lineCount += postludeLines;
|
|
244
|
+
|
|
245
|
+
// The entry asset of a script bundle gets hoisted outside the bundle wrapper so that
|
|
246
|
+
// its top-level variables become globals like a real browser script. We need to replace
|
|
247
|
+
// all dependency references for runtimes with a parcelRequire call.
|
|
248
|
+
if (
|
|
249
|
+
this.bundle.env.outputFormat === 'global' &&
|
|
250
|
+
this.bundle.env.sourceType === 'script'
|
|
251
|
+
) {
|
|
252
|
+
res += '\n';
|
|
253
|
+
lineCount++;
|
|
254
|
+
|
|
255
|
+
let mainEntry = nullthrows(this.bundle.getMainEntry());
|
|
256
|
+
let {code, map: mapBuffer} = nullthrows(
|
|
257
|
+
this.assetOutputs.get(mainEntry.id),
|
|
258
|
+
);
|
|
259
|
+
let map;
|
|
260
|
+
if (mapBuffer) {
|
|
261
|
+
map = new SourceMap(this.options.projectRoot, mapBuffer);
|
|
262
|
+
}
|
|
263
|
+
res += replaceScriptDependencies(
|
|
264
|
+
this.bundleGraph,
|
|
265
|
+
this.bundle,
|
|
266
|
+
code,
|
|
267
|
+
map,
|
|
268
|
+
this.parcelRequireName,
|
|
269
|
+
);
|
|
270
|
+
if (sourceMap && map) {
|
|
271
|
+
sourceMap.addSourceMap(map, lineCount);
|
|
272
|
+
}
|
|
273
|
+
}
|
|
175
274
|
|
|
176
275
|
return {
|
|
177
276
|
contents: res,
|
|
@@ -179,78 +278,125 @@ export class ScopeHoistingPackager {
|
|
|
179
278
|
};
|
|
180
279
|
}
|
|
181
280
|
|
|
182
|
-
|
|
281
|
+
shouldBundleQueue(bundle: NamedBundle): boolean {
|
|
282
|
+
return (
|
|
283
|
+
this.useAsyncBundleRuntime &&
|
|
284
|
+
bundle.type === 'js' &&
|
|
285
|
+
bundle.bundleBehavior !== 'inline' &&
|
|
286
|
+
bundle.env.outputFormat === 'esmodule' &&
|
|
287
|
+
!bundle.env.isIsolated() &&
|
|
288
|
+
bundle.bundleBehavior !== 'isolated' &&
|
|
289
|
+
!this.bundleGraph.hasParentBundleOfType(bundle, 'js')
|
|
290
|
+
);
|
|
291
|
+
}
|
|
292
|
+
|
|
293
|
+
runWhenReady(bundle: NamedBundle, codeToRun: string): string {
|
|
294
|
+
let deps = this.bundleGraph
|
|
295
|
+
.getReferencedBundles(bundle)
|
|
296
|
+
.filter(b => this.shouldBundleQueue(b))
|
|
297
|
+
.map(b => b.publicId);
|
|
298
|
+
|
|
299
|
+
if (deps.length === 0) {
|
|
300
|
+
// If no deps we can safely execute immediately
|
|
301
|
+
return codeToRun;
|
|
302
|
+
}
|
|
303
|
+
|
|
304
|
+
let params = [
|
|
305
|
+
JSON.stringify(this.bundle.publicId),
|
|
306
|
+
fnExpr(this.bundle.env, [], [codeToRun]),
|
|
307
|
+
JSON.stringify(deps),
|
|
308
|
+
];
|
|
309
|
+
|
|
310
|
+
return `$parcel$global.rwr(${params.join(', ')});`;
|
|
311
|
+
}
|
|
312
|
+
|
|
313
|
+
async loadAssets(): Promise<Array<Asset>> {
|
|
183
314
|
let queue = new PromiseQueue({maxConcurrent: 32});
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
if (
|
|
209
|
-
shouldWrap ||
|
|
210
|
-
node.value.meta.shouldWrap ||
|
|
211
|
-
this.isAsyncBundle ||
|
|
212
|
-
this.bundleGraph.isAssetReferencedByDependant(
|
|
213
|
-
this.bundle,
|
|
214
|
-
node.value,
|
|
215
|
-
)
|
|
216
|
-
) {
|
|
217
|
-
this.wrappedAssets.add(node.value.id);
|
|
218
|
-
return true;
|
|
219
|
-
}
|
|
315
|
+
let wrapped = [];
|
|
316
|
+
this.bundle.traverseAssets(asset => {
|
|
317
|
+
queue.add(async () => {
|
|
318
|
+
let [code, map] = await Promise.all([
|
|
319
|
+
asset.getCode(),
|
|
320
|
+
this.bundle.env.sourceMap ? asset.getMapBuffer() : null,
|
|
321
|
+
]);
|
|
322
|
+
return [asset.id, {code, map}];
|
|
323
|
+
});
|
|
324
|
+
|
|
325
|
+
if (
|
|
326
|
+
asset.meta.shouldWrap ||
|
|
327
|
+
this.isAsyncBundle ||
|
|
328
|
+
this.bundle.env.sourceType === 'script' ||
|
|
329
|
+
this.bundleGraph.isAssetReferenced(this.bundle, asset) ||
|
|
330
|
+
this.bundleGraph
|
|
331
|
+
.getIncomingDependencies(asset)
|
|
332
|
+
.some(dep => dep.meta.shouldWrap && dep.specifierType !== 'url')
|
|
333
|
+
) {
|
|
334
|
+
if (!asset.meta.isConstantModule) {
|
|
335
|
+
this.wrappedAssets.add(asset.id);
|
|
336
|
+
wrapped.push(asset);
|
|
337
|
+
}
|
|
220
338
|
}
|
|
221
339
|
});
|
|
222
340
|
|
|
341
|
+
for (let wrappedAssetRoot of [...wrapped]) {
|
|
342
|
+
this.bundle.traverseAssets((asset, _, actions) => {
|
|
343
|
+
if (asset === wrappedAssetRoot) {
|
|
344
|
+
return;
|
|
345
|
+
}
|
|
346
|
+
|
|
347
|
+
if (this.wrappedAssets.has(asset.id)) {
|
|
348
|
+
actions.skipChildren();
|
|
349
|
+
return;
|
|
350
|
+
}
|
|
351
|
+
if (!asset.meta.isConstantModule) {
|
|
352
|
+
this.wrappedAssets.add(asset.id);
|
|
353
|
+
wrapped.push(asset);
|
|
354
|
+
}
|
|
355
|
+
}, wrappedAssetRoot);
|
|
356
|
+
}
|
|
357
|
+
|
|
223
358
|
this.assetOutputs = new Map(await queue.run());
|
|
359
|
+
return wrapped;
|
|
224
360
|
}
|
|
225
361
|
|
|
226
362
|
buildExportedSymbols() {
|
|
227
|
-
if (
|
|
363
|
+
if (
|
|
364
|
+
this.isAsyncBundle ||
|
|
365
|
+
!this.bundle.env.isLibrary ||
|
|
366
|
+
this.bundle.env.outputFormat !== 'esmodule'
|
|
367
|
+
) {
|
|
228
368
|
return;
|
|
229
369
|
}
|
|
230
370
|
|
|
371
|
+
// TODO: handle ESM exports of wrapped entry assets...
|
|
231
372
|
let entry = this.bundle.getMainEntry();
|
|
232
|
-
if (entry) {
|
|
233
|
-
for (let {
|
|
234
|
-
|
|
235
|
-
|
|
373
|
+
if (entry && !this.wrappedAssets.has(entry.id)) {
|
|
374
|
+
for (let {
|
|
375
|
+
asset,
|
|
376
|
+
exportAs,
|
|
377
|
+
symbol,
|
|
378
|
+
exportSymbol,
|
|
379
|
+
} of this.bundleGraph.getExportedSymbols(entry)) {
|
|
236
380
|
if (typeof symbol === 'string') {
|
|
237
381
|
let symbols = this.exportedSymbols.get(
|
|
238
382
|
symbol === '*' ? nullthrows(entry.symbols.get('*')?.local) : symbol,
|
|
239
|
-
);
|
|
383
|
+
)?.exportAs;
|
|
240
384
|
|
|
241
|
-
|
|
242
|
-
if (symbols) {
|
|
243
|
-
local = symbols[0].local;
|
|
244
|
-
} else {
|
|
385
|
+
if (!symbols) {
|
|
245
386
|
symbols = [];
|
|
246
|
-
this.exportedSymbols.set(symbol,
|
|
387
|
+
this.exportedSymbols.set(symbol, {
|
|
388
|
+
asset,
|
|
389
|
+
exportSymbol,
|
|
390
|
+
local: symbol,
|
|
391
|
+
exportAs: symbols,
|
|
392
|
+
});
|
|
247
393
|
}
|
|
248
394
|
|
|
249
395
|
if (exportAs === '*') {
|
|
250
396
|
exportAs = 'default';
|
|
251
397
|
}
|
|
252
398
|
|
|
253
|
-
symbols.push(
|
|
399
|
+
symbols.push(exportAs);
|
|
254
400
|
} else if (symbol === null) {
|
|
255
401
|
// TODO `meta.exportsIdentifier[exportSymbol]` should be exported
|
|
256
402
|
// let relativePath = relative(options.projectRoot, asset.filePath);
|
|
@@ -287,6 +433,14 @@ export class ScopeHoistingPackager {
|
|
|
287
433
|
return name + count;
|
|
288
434
|
}
|
|
289
435
|
|
|
436
|
+
getPropertyAccess(obj: string, property: string): string {
|
|
437
|
+
if (IDENTIFIER_RE.test(property)) {
|
|
438
|
+
return `${obj}.${property}`;
|
|
439
|
+
}
|
|
440
|
+
|
|
441
|
+
return `${obj}[${JSON.stringify(property)}]`;
|
|
442
|
+
}
|
|
443
|
+
|
|
290
444
|
visitAsset(asset: Asset): [string, ?SourceMap, number] {
|
|
291
445
|
invariant(!this.seenAssets.has(asset.id), 'Already visited asset');
|
|
292
446
|
this.seenAssets.add(asset.id);
|
|
@@ -303,24 +457,27 @@ export class ScopeHoistingPackager {
|
|
|
303
457
|
let shouldWrap = this.wrappedAssets.has(asset.id);
|
|
304
458
|
let deps = this.bundleGraph.getDependencies(asset);
|
|
305
459
|
|
|
306
|
-
let sourceMap =
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
sourceMap?.addBuffer(map);
|
|
311
|
-
}
|
|
460
|
+
let sourceMap =
|
|
461
|
+
this.bundle.env.sourceMap && map
|
|
462
|
+
? new SourceMap(this.options.projectRoot, map)
|
|
463
|
+
: null;
|
|
312
464
|
|
|
313
465
|
// If this asset is skipped, just add dependencies and not the asset's content.
|
|
314
466
|
if (this.shouldSkipAsset(asset)) {
|
|
315
467
|
let depCode = '';
|
|
316
468
|
let lineCount = 0;
|
|
317
469
|
for (let dep of deps) {
|
|
318
|
-
let resolved = this.bundleGraph.
|
|
319
|
-
dep,
|
|
320
|
-
this.bundle,
|
|
321
|
-
);
|
|
470
|
+
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
|
|
322
471
|
let skipped = this.bundleGraph.isDependencySkipped(dep);
|
|
323
|
-
if (
|
|
472
|
+
if (skipped) {
|
|
473
|
+
continue;
|
|
474
|
+
}
|
|
475
|
+
|
|
476
|
+
if (!resolved) {
|
|
477
|
+
if (!dep.isOptional) {
|
|
478
|
+
this.addExternal(dep);
|
|
479
|
+
}
|
|
480
|
+
|
|
324
481
|
continue;
|
|
325
482
|
}
|
|
326
483
|
|
|
@@ -345,6 +502,14 @@ export class ScopeHoistingPackager {
|
|
|
345
502
|
this.usedHelpers.add('$parcel$global');
|
|
346
503
|
}
|
|
347
504
|
|
|
505
|
+
if (this.bundle.env.isNode() && asset.meta.has_node_replacements) {
|
|
506
|
+
const relPath = normalizeSeparators(
|
|
507
|
+
path.relative(this.bundle.target.distDir, path.dirname(asset.filePath)),
|
|
508
|
+
);
|
|
509
|
+
code = code.replace('$parcel$dirnameReplace', relPath);
|
|
510
|
+
code = code.replace('$parcel$filenameReplace', relPath);
|
|
511
|
+
}
|
|
512
|
+
|
|
348
513
|
let [depMap, replacements] = this.buildReplacements(asset, deps);
|
|
349
514
|
let [prepend, prependLines, append] = this.buildAssetPrelude(asset, deps);
|
|
350
515
|
if (prependLines > 0) {
|
|
@@ -354,107 +519,106 @@ export class ScopeHoistingPackager {
|
|
|
354
519
|
|
|
355
520
|
code += append;
|
|
356
521
|
|
|
357
|
-
// Build a regular expression for all the replacements we need to do.
|
|
358
|
-
// We need to track how many newlines there are for source maps, replace
|
|
359
|
-
// all import statements with dependency code, and perform inline replacements
|
|
360
|
-
// of all imported symbols with their resolved export symbols. This is all done
|
|
361
|
-
// in a single regex so that we only do one pass over the whole code.
|
|
362
|
-
let regex = new RegExp(
|
|
363
|
-
'\n|import\\s+"([0-9a-f]{32}:.+?)";' +
|
|
364
|
-
(replacements.size > 0
|
|
365
|
-
? '|' +
|
|
366
|
-
[...replacements.keys()]
|
|
367
|
-
.sort((a, b) => b.length - a.length)
|
|
368
|
-
.map(k => k.replace(/[$]/g, '\\$&'))
|
|
369
|
-
.join('|')
|
|
370
|
-
: ''),
|
|
371
|
-
'g',
|
|
372
|
-
);
|
|
373
|
-
|
|
374
522
|
let lineCount = 0;
|
|
375
|
-
let offset = 0;
|
|
376
|
-
let columnStartIndex = 0;
|
|
377
523
|
let depContent = [];
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
524
|
+
if (depMap.size === 0 && replacements.size === 0) {
|
|
525
|
+
// If there are no dependencies or replacements, use a simple function to count the number of lines.
|
|
526
|
+
lineCount = countLines(code) - 1;
|
|
527
|
+
} else {
|
|
528
|
+
// Otherwise, use a regular expression to perform replacements.
|
|
529
|
+
// We need to track how many newlines there are for source maps, replace
|
|
530
|
+
// all import statements with dependency code, and perform inline replacements
|
|
531
|
+
// of all imported symbols with their resolved export symbols. This is all done
|
|
532
|
+
// in a single regex so that we only do one pass over the whole code.
|
|
533
|
+
let offset = 0;
|
|
534
|
+
let columnStartIndex = 0;
|
|
535
|
+
code = code.replace(REPLACEMENT_RE, (m, d, i) => {
|
|
536
|
+
if (m === '\n') {
|
|
537
|
+
columnStartIndex = i + offset + 1;
|
|
538
|
+
lineCount++;
|
|
539
|
+
return '\n';
|
|
540
|
+
}
|
|
384
541
|
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
this.bundle,
|
|
391
|
-
);
|
|
392
|
-
let skipped = this.bundleGraph.isDependencySkipped(dep);
|
|
393
|
-
if (resolved && !skipped) {
|
|
394
|
-
// Hoist variable declarations for the referenced parcelRequire dependencies
|
|
395
|
-
// after the dependency is declared. This handles the case where the resulting asset
|
|
396
|
-
// is wrapped, but the dependency in this asset is not marked as wrapped. This means
|
|
397
|
-
// that it was imported/required at the top-level, so its side effects should run immediately.
|
|
398
|
-
let [res, lines] = this.getHoistedParcelRequires(
|
|
399
|
-
asset,
|
|
400
|
-
dep,
|
|
401
|
-
resolved,
|
|
402
|
-
);
|
|
403
|
-
let map;
|
|
404
|
-
if (
|
|
405
|
-
this.bundle.hasAsset(resolved) &&
|
|
406
|
-
!this.seenAssets.has(resolved.id)
|
|
407
|
-
) {
|
|
408
|
-
// If this asset is wrapped, we need to hoist the code for the dependency
|
|
409
|
-
// outside our parcelRequire.register wrapper. This is safe because all
|
|
410
|
-
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
411
|
-
// asset content where the import statement was.
|
|
412
|
-
if (shouldWrap) {
|
|
413
|
-
depContent.push(this.visitAsset(resolved));
|
|
414
|
-
} else {
|
|
415
|
-
let [depCode, depMap, depLines] = this.visitAsset(resolved);
|
|
416
|
-
res = depCode + '\n' + res;
|
|
417
|
-
lines += 1 + depLines;
|
|
418
|
-
map = depMap;
|
|
419
|
-
}
|
|
542
|
+
// If we matched an import, replace with the source code for the dependency.
|
|
543
|
+
if (d != null) {
|
|
544
|
+
let deps = depMap.get(d);
|
|
545
|
+
if (!deps) {
|
|
546
|
+
return m;
|
|
420
547
|
}
|
|
421
548
|
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
549
|
+
let replacement = '';
|
|
550
|
+
|
|
551
|
+
// A single `${id}:${specifier}:esm` might have been resolved to multiple assets due to
|
|
552
|
+
// reexports.
|
|
553
|
+
for (let dep of deps) {
|
|
554
|
+
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
|
|
555
|
+
let skipped = this.bundleGraph.isDependencySkipped(dep);
|
|
556
|
+
if (resolved && !skipped) {
|
|
557
|
+
// Hoist variable declarations for the referenced parcelRequire dependencies
|
|
558
|
+
// after the dependency is declared. This handles the case where the resulting asset
|
|
559
|
+
// is wrapped, but the dependency in this asset is not marked as wrapped. This means
|
|
560
|
+
// that it was imported/required at the top-level, so its side effects should run immediately.
|
|
561
|
+
let [res, lines] = this.getHoistedParcelRequires(
|
|
562
|
+
asset,
|
|
563
|
+
dep,
|
|
564
|
+
resolved,
|
|
565
|
+
);
|
|
566
|
+
let map;
|
|
567
|
+
if (
|
|
568
|
+
this.bundle.hasAsset(resolved) &&
|
|
569
|
+
!this.seenAssets.has(resolved.id)
|
|
570
|
+
) {
|
|
571
|
+
// If this asset is wrapped, we need to hoist the code for the dependency
|
|
572
|
+
// outside our parcelRequire.register wrapper. This is safe because all
|
|
573
|
+
// assets referenced by this asset will also be wrapped. Otherwise, inline the
|
|
574
|
+
// asset content where the import statement was.
|
|
575
|
+
if (shouldWrap) {
|
|
576
|
+
depContent.push(this.visitAsset(resolved));
|
|
577
|
+
} else {
|
|
578
|
+
let [depCode, depMap, depLines] = this.visitAsset(resolved);
|
|
579
|
+
res = depCode + '\n' + res;
|
|
580
|
+
lines += 1 + depLines;
|
|
581
|
+
map = depMap;
|
|
582
|
+
}
|
|
583
|
+
}
|
|
584
|
+
|
|
585
|
+
// Push this asset's source mappings down by the number of lines in the dependency
|
|
586
|
+
// plus the number of hoisted parcelRequires. Then insert the source map for the dependency.
|
|
587
|
+
if (sourceMap) {
|
|
588
|
+
if (lines > 0) {
|
|
589
|
+
sourceMap.offsetLines(lineCount + 1, lines);
|
|
590
|
+
}
|
|
591
|
+
|
|
592
|
+
if (map) {
|
|
593
|
+
sourceMap.addSourceMap(map, lineCount);
|
|
594
|
+
}
|
|
595
|
+
}
|
|
428
596
|
|
|
429
|
-
|
|
430
|
-
|
|
597
|
+
replacement += res;
|
|
598
|
+
lineCount += lines;
|
|
431
599
|
}
|
|
432
600
|
}
|
|
433
|
-
|
|
434
|
-
lineCount += lines;
|
|
435
|
-
return res;
|
|
601
|
+
return replacement;
|
|
436
602
|
}
|
|
437
603
|
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
);
|
|
453
|
-
offset += lengthDifference;
|
|
604
|
+
// If it wasn't a dependency, then it was an inline replacement (e.g. $id$import$foo -> $id$export$foo).
|
|
605
|
+
let replacement = replacements.get(m) ?? m;
|
|
606
|
+
if (sourceMap) {
|
|
607
|
+
// Offset the source map columns for this line if the replacement was a different length.
|
|
608
|
+
// This assumes that the match and replacement both do not contain any newlines.
|
|
609
|
+
let lengthDifference = replacement.length - m.length;
|
|
610
|
+
if (lengthDifference !== 0) {
|
|
611
|
+
sourceMap.offsetColumns(
|
|
612
|
+
lineCount + 1,
|
|
613
|
+
i + offset - columnStartIndex + m.length,
|
|
614
|
+
lengthDifference,
|
|
615
|
+
);
|
|
616
|
+
offset += lengthDifference;
|
|
617
|
+
}
|
|
454
618
|
}
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
}
|
|
619
|
+
return replacement;
|
|
620
|
+
});
|
|
621
|
+
}
|
|
458
622
|
|
|
459
623
|
// If the asset is wrapped, we need to insert the dependency code outside the parcelRequire.register
|
|
460
624
|
// wrapper. Dependencies must be inserted AFTER the asset is registered so that circular dependencies work.
|
|
@@ -463,7 +627,7 @@ export class ScopeHoistingPackager {
|
|
|
463
627
|
sourceMap?.offsetLines(1, 1);
|
|
464
628
|
lineCount++;
|
|
465
629
|
|
|
466
|
-
code = `
|
|
630
|
+
code = `parcelRegister(${JSON.stringify(
|
|
467
631
|
this.bundleGraph.getAssetPublicId(asset),
|
|
468
632
|
)}, function(module, exports) {
|
|
469
633
|
${code}
|
|
@@ -476,7 +640,7 @@ ${code}
|
|
|
476
640
|
if (!depCode) continue;
|
|
477
641
|
code += depCode + '\n';
|
|
478
642
|
if (sourceMap && map) {
|
|
479
|
-
sourceMap.addSourceMap(map, lineCount
|
|
643
|
+
sourceMap.addSourceMap(map, lineCount);
|
|
480
644
|
}
|
|
481
645
|
lineCount += lines + 1;
|
|
482
646
|
}
|
|
@@ -484,22 +648,38 @@ ${code}
|
|
|
484
648
|
this.needsPrelude = true;
|
|
485
649
|
}
|
|
486
650
|
|
|
651
|
+
if (
|
|
652
|
+
!shouldWrap &&
|
|
653
|
+
this.shouldBundleQueue(this.bundle) &&
|
|
654
|
+
this.bundle.getEntryAssets().some(entry => entry.id === asset.id)
|
|
655
|
+
) {
|
|
656
|
+
code = this.runWhenReady(this.bundle, code);
|
|
657
|
+
}
|
|
658
|
+
|
|
487
659
|
return [code, sourceMap, lineCount];
|
|
488
660
|
}
|
|
489
661
|
|
|
490
662
|
buildReplacements(
|
|
491
663
|
asset: Asset,
|
|
492
664
|
deps: Array<Dependency>,
|
|
493
|
-
): [Map<string, Dependency
|
|
665
|
+
): [Map<string, Array<Dependency>>, Map<string, string>] {
|
|
494
666
|
let assetId = asset.meta.id;
|
|
495
667
|
invariant(typeof assetId === 'string');
|
|
496
668
|
|
|
497
669
|
// Build two maps: one of import specifiers, and one of imported symbols to replace.
|
|
498
670
|
// These will be used to build a regex below.
|
|
499
|
-
let depMap = new
|
|
671
|
+
let depMap = new DefaultMap<string, Array<Dependency>>(() => []);
|
|
500
672
|
let replacements = new Map();
|
|
501
673
|
for (let dep of deps) {
|
|
502
|
-
|
|
674
|
+
let specifierType =
|
|
675
|
+
dep.specifierType === 'esm' ? `:${dep.specifierType}` : '';
|
|
676
|
+
depMap
|
|
677
|
+
.get(
|
|
678
|
+
`${assetId}:${getSpecifier(dep)}${
|
|
679
|
+
!dep.meta.placeholder ? specifierType : ''
|
|
680
|
+
}`,
|
|
681
|
+
)
|
|
682
|
+
.push(dep);
|
|
503
683
|
|
|
504
684
|
let asyncResolution = this.bundleGraph.resolveAsyncDependency(
|
|
505
685
|
dep,
|
|
@@ -510,44 +690,16 @@ ${code}
|
|
|
510
690
|
? // Prefer the underlying asset over a runtime to load it. It will
|
|
511
691
|
// be wrapped in Promise.resolve() later.
|
|
512
692
|
asyncResolution.value
|
|
513
|
-
: this.bundleGraph.
|
|
693
|
+
: this.bundleGraph.getResolvedAsset(dep, this.bundle);
|
|
514
694
|
if (
|
|
515
695
|
!resolved &&
|
|
516
696
|
!dep.isOptional &&
|
|
517
697
|
!this.bundleGraph.isDependencySkipped(dep)
|
|
518
698
|
) {
|
|
519
|
-
|
|
520
|
-
for (let [imported, {local}] of dep.symbols) {
|
|
521
|
-
// If already imported, just add the already renamed variable to the mapping.
|
|
522
|
-
let renamed = external.get(imported);
|
|
523
|
-
if (renamed && local !== '*') {
|
|
524
|
-
replacements.set(local, renamed);
|
|
525
|
-
continue;
|
|
526
|
-
}
|
|
527
|
-
|
|
528
|
-
// Rename the specifier so that multiple local imports of the same imported specifier
|
|
529
|
-
// are deduplicated. We have to prefix the imported name with the bundle id so that
|
|
530
|
-
// local variables do not shadow it.
|
|
531
|
-
if (this.exportedSymbols.has(local)) {
|
|
532
|
-
renamed = local;
|
|
533
|
-
} else if (imported === 'default' || imported === '*') {
|
|
534
|
-
renamed = this.getTopLevelName(
|
|
535
|
-
`$${this.bundle.publicId}$${dep.moduleSpecifier}`,
|
|
536
|
-
);
|
|
537
|
-
} else {
|
|
538
|
-
renamed = this.getTopLevelName(
|
|
539
|
-
`$${this.bundle.publicId}$${imported}`,
|
|
540
|
-
);
|
|
541
|
-
}
|
|
542
|
-
|
|
543
|
-
external.set(imported, renamed);
|
|
544
|
-
if (local !== '*') {
|
|
545
|
-
replacements.set(local, renamed);
|
|
546
|
-
}
|
|
547
|
-
}
|
|
699
|
+
this.addExternal(dep, replacements);
|
|
548
700
|
}
|
|
549
701
|
|
|
550
|
-
if (!resolved
|
|
702
|
+
if (!resolved) {
|
|
551
703
|
continue;
|
|
552
704
|
}
|
|
553
705
|
|
|
@@ -556,7 +708,7 @@ ${code}
|
|
|
556
708
|
continue;
|
|
557
709
|
}
|
|
558
710
|
|
|
559
|
-
let symbol = this.
|
|
711
|
+
let symbol = this.getSymbolResolution(asset, resolved, imported, dep);
|
|
560
712
|
replacements.set(
|
|
561
713
|
local,
|
|
562
714
|
// If this was an internalized async asset, wrap in a Promise.resolve.
|
|
@@ -569,10 +721,10 @@ ${code}
|
|
|
569
721
|
// Async dependencies need a namespace object even if all used symbols were statically analyzed.
|
|
570
722
|
// This is recorded in the promiseSymbol meta property set by the transformer rather than in
|
|
571
723
|
// symbols so that we don't mark all symbols as used.
|
|
572
|
-
if (dep.
|
|
724
|
+
if (dep.priority === 'lazy' && dep.meta.promiseSymbol) {
|
|
573
725
|
let promiseSymbol = dep.meta.promiseSymbol;
|
|
574
726
|
invariant(typeof promiseSymbol === 'string');
|
|
575
|
-
let symbol = this.
|
|
727
|
+
let symbol = this.getSymbolResolution(asset, resolved, '*', dep);
|
|
576
728
|
replacements.set(
|
|
577
729
|
promiseSymbol,
|
|
578
730
|
asyncResolution?.type === 'asset'
|
|
@@ -596,38 +748,103 @@ ${code}
|
|
|
596
748
|
return [depMap, replacements];
|
|
597
749
|
}
|
|
598
750
|
|
|
599
|
-
addExternal(dep: Dependency
|
|
751
|
+
addExternal(dep: Dependency, replacements?: Map<string, string>) {
|
|
600
752
|
if (this.bundle.env.outputFormat === 'global') {
|
|
601
753
|
throw new ThrowableDiagnostic({
|
|
602
754
|
diagnostic: {
|
|
603
755
|
message:
|
|
604
756
|
'External modules are not supported when building for browser',
|
|
605
|
-
|
|
606
|
-
|
|
607
|
-
|
|
608
|
-
|
|
609
|
-
|
|
610
|
-
|
|
611
|
-
|
|
612
|
-
|
|
613
|
-
]
|
|
614
|
-
: [],
|
|
615
|
-
},
|
|
757
|
+
codeFrames: [
|
|
758
|
+
{
|
|
759
|
+
filePath: nullthrows(dep.sourcePath),
|
|
760
|
+
codeHighlights: dep.loc
|
|
761
|
+
? [convertSourceLocationToHighlight(dep.loc)]
|
|
762
|
+
: [],
|
|
763
|
+
},
|
|
764
|
+
],
|
|
616
765
|
},
|
|
617
766
|
});
|
|
618
767
|
}
|
|
619
768
|
|
|
620
|
-
// Map of
|
|
621
|
-
let external = this.externals.get(dep.
|
|
769
|
+
// Map of DependencySpecifier -> Map<ExportedSymbol, Identifier>>
|
|
770
|
+
let external = this.externals.get(dep.specifier);
|
|
622
771
|
if (!external) {
|
|
623
772
|
external = new Map();
|
|
624
|
-
this.externals.set(dep.
|
|
773
|
+
this.externals.set(dep.specifier, external);
|
|
625
774
|
}
|
|
626
775
|
|
|
627
|
-
|
|
776
|
+
for (let [imported, {local}] of dep.symbols) {
|
|
777
|
+
// If already imported, just add the already renamed variable to the mapping.
|
|
778
|
+
let renamed = external.get(imported);
|
|
779
|
+
if (renamed && local !== '*' && replacements) {
|
|
780
|
+
replacements.set(local, renamed);
|
|
781
|
+
continue;
|
|
782
|
+
}
|
|
783
|
+
|
|
784
|
+
// For CJS output, always use a property lookup so that exports remain live.
|
|
785
|
+
// For ESM output, use named imports which are always live.
|
|
786
|
+
if (this.bundle.env.outputFormat === 'commonjs') {
|
|
787
|
+
renamed = external.get('*');
|
|
788
|
+
if (!renamed) {
|
|
789
|
+
renamed = this.getTopLevelName(
|
|
790
|
+
`$${this.bundle.publicId}$${dep.specifier}`,
|
|
791
|
+
);
|
|
792
|
+
|
|
793
|
+
external.set('*', renamed);
|
|
794
|
+
}
|
|
795
|
+
|
|
796
|
+
if (local !== '*' && replacements) {
|
|
797
|
+
let replacement;
|
|
798
|
+
if (imported === '*') {
|
|
799
|
+
replacement = renamed;
|
|
800
|
+
} else if (imported === 'default') {
|
|
801
|
+
replacement = `($parcel$interopDefault(${renamed}))`;
|
|
802
|
+
this.usedHelpers.add('$parcel$interopDefault');
|
|
803
|
+
} else {
|
|
804
|
+
replacement = this.getPropertyAccess(renamed, imported);
|
|
805
|
+
}
|
|
806
|
+
|
|
807
|
+
replacements.set(local, replacement);
|
|
808
|
+
}
|
|
809
|
+
} else {
|
|
810
|
+
// Rename the specifier so that multiple local imports of the same imported specifier
|
|
811
|
+
// are deduplicated. We have to prefix the imported name with the bundle id so that
|
|
812
|
+
// local variables do not shadow it.
|
|
813
|
+
if (this.exportedSymbols.has(local)) {
|
|
814
|
+
renamed = local;
|
|
815
|
+
} else if (imported === 'default' || imported === '*') {
|
|
816
|
+
renamed = this.getTopLevelName(
|
|
817
|
+
`$${this.bundle.publicId}$${dep.specifier}`,
|
|
818
|
+
);
|
|
819
|
+
} else {
|
|
820
|
+
renamed = this.getTopLevelName(
|
|
821
|
+
`$${this.bundle.publicId}$${imported}`,
|
|
822
|
+
);
|
|
823
|
+
}
|
|
824
|
+
|
|
825
|
+
external.set(imported, renamed);
|
|
826
|
+
if (local !== '*' && replacements) {
|
|
827
|
+
replacements.set(local, renamed);
|
|
828
|
+
}
|
|
829
|
+
}
|
|
830
|
+
}
|
|
831
|
+
}
|
|
832
|
+
|
|
833
|
+
isWrapped(resolved: Asset, parentAsset: Asset): boolean {
|
|
834
|
+
if (resolved.meta.isConstantModule) {
|
|
835
|
+
invariant(
|
|
836
|
+
this.bundle.hasAsset(resolved),
|
|
837
|
+
'Constant module not found in bundle',
|
|
838
|
+
);
|
|
839
|
+
return false;
|
|
840
|
+
}
|
|
841
|
+
return (
|
|
842
|
+
(!this.bundle.hasAsset(resolved) && !this.externalAssets.has(resolved)) ||
|
|
843
|
+
(this.wrappedAssets.has(resolved.id) && resolved !== parentAsset)
|
|
844
|
+
);
|
|
628
845
|
}
|
|
629
846
|
|
|
630
|
-
|
|
847
|
+
getSymbolResolution(
|
|
631
848
|
parentAsset: Asset,
|
|
632
849
|
resolved: Asset,
|
|
633
850
|
imported: string,
|
|
@@ -637,17 +854,41 @@ ${code}
|
|
|
637
854
|
asset: resolvedAsset,
|
|
638
855
|
exportSymbol,
|
|
639
856
|
symbol,
|
|
640
|
-
} = this.bundleGraph.
|
|
641
|
-
|
|
642
|
-
|
|
643
|
-
|
|
644
|
-
|
|
857
|
+
} = this.bundleGraph.getSymbolResolution(resolved, imported, this.bundle);
|
|
858
|
+
|
|
859
|
+
if (
|
|
860
|
+
resolvedAsset.type !== 'js' ||
|
|
861
|
+
(dep && this.bundleGraph.isDependencySkipped(dep))
|
|
862
|
+
) {
|
|
863
|
+
// Graceful fallback for non-js imports or when trying to resolve a symbol
|
|
864
|
+
// that is actually unused but we still need a placeholder value.
|
|
865
|
+
return '{}';
|
|
866
|
+
}
|
|
867
|
+
|
|
868
|
+
let isWrapped = this.isWrapped(resolvedAsset, parentAsset);
|
|
645
869
|
let staticExports = resolvedAsset.meta.staticExports !== false;
|
|
646
870
|
let publicId = this.bundleGraph.getAssetPublicId(resolvedAsset);
|
|
647
871
|
|
|
648
|
-
//
|
|
872
|
+
// External CommonJS dependencies need to be accessed as an object property rather than imported
|
|
873
|
+
// directly to maintain live binding.
|
|
874
|
+
let isExternalCommonJS =
|
|
875
|
+
!isWrapped &&
|
|
876
|
+
this.bundle.env.isLibrary &&
|
|
877
|
+
this.bundle.env.outputFormat === 'commonjs' &&
|
|
878
|
+
!this.bundle.hasAsset(resolvedAsset);
|
|
879
|
+
|
|
880
|
+
// If the resolved asset is wrapped, but imported at the top-level by this asset,
|
|
649
881
|
// then we hoist parcelRequire calls to the top of this asset so side effects run immediately.
|
|
650
|
-
if (
|
|
882
|
+
if (
|
|
883
|
+
isWrapped &&
|
|
884
|
+
dep &&
|
|
885
|
+
!dep?.meta.shouldWrap &&
|
|
886
|
+
symbol !== false &&
|
|
887
|
+
// Only do this if the asset is part of a different bundle (so it was definitely
|
|
888
|
+
// parcelRequire.register'ed there), or if it is indeed registered in this bundle.
|
|
889
|
+
(!this.bundle.hasAsset(resolvedAsset) ||
|
|
890
|
+
!this.shouldSkipAsset(resolvedAsset))
|
|
891
|
+
) {
|
|
651
892
|
let hoisted = this.hoistedRequires.get(dep.id);
|
|
652
893
|
if (!hoisted) {
|
|
653
894
|
hoisted = new Map();
|
|
@@ -670,7 +911,7 @@ ${code}
|
|
|
670
911
|
exportSymbol === 'default' &&
|
|
671
912
|
staticExports &&
|
|
672
913
|
!isWrapped &&
|
|
673
|
-
dep?.meta.kind === 'Import' &&
|
|
914
|
+
(dep?.meta.kind === 'Import' || dep?.meta.kind === 'Export') &&
|
|
674
915
|
resolvedAsset.symbols.hasExportSymbol('*') &&
|
|
675
916
|
resolvedAsset.symbols.hasExportSymbol('default') &&
|
|
676
917
|
!resolvedAsset.symbols.hasExportSymbol('__esModule');
|
|
@@ -691,17 +932,26 @@ ${code}
|
|
|
691
932
|
|
|
692
933
|
if (imported === '*' || exportSymbol === '*' || isDefaultInterop) {
|
|
693
934
|
// Resolve to the namespace object if requested or this is a CJS default interop reqiure.
|
|
694
|
-
|
|
935
|
+
if (
|
|
936
|
+
parentAsset === resolvedAsset &&
|
|
937
|
+
this.wrappedAssets.has(resolvedAsset.id)
|
|
938
|
+
) {
|
|
939
|
+
// Directly use module.exports for wrapped assets importing themselves.
|
|
940
|
+
return 'module.exports';
|
|
941
|
+
} else {
|
|
942
|
+
return obj;
|
|
943
|
+
}
|
|
695
944
|
} else if (
|
|
696
|
-
(!staticExports || isWrapped || !symbol) &&
|
|
945
|
+
(!staticExports || isWrapped || !symbol || isExternalCommonJS) &&
|
|
697
946
|
resolvedAsset !== parentAsset
|
|
698
947
|
) {
|
|
699
948
|
// If the resolved asset is wrapped or has non-static exports,
|
|
700
949
|
// we need to use a member access off the namespace object rather
|
|
701
950
|
// than a direct reference. If importing default from a CJS module,
|
|
702
951
|
// use a helper to check the __esModule flag at runtime.
|
|
952
|
+
let kind = dep?.meta.kind;
|
|
703
953
|
if (
|
|
704
|
-
dep
|
|
954
|
+
(!dep || kind === 'Import' || kind === 'Export') &&
|
|
705
955
|
exportSymbol === 'default' &&
|
|
706
956
|
resolvedAsset.symbols.hasExportSymbol('*') &&
|
|
707
957
|
this.needsDefaultInterop(resolvedAsset)
|
|
@@ -709,11 +959,7 @@ ${code}
|
|
|
709
959
|
this.usedHelpers.add('$parcel$interopDefault');
|
|
710
960
|
return `(/*@__PURE__*/$parcel$interopDefault(${obj}))`;
|
|
711
961
|
} else {
|
|
712
|
-
|
|
713
|
-
return `${obj}.${exportSymbol}`;
|
|
714
|
-
}
|
|
715
|
-
|
|
716
|
-
return `${obj}[${JSON.stringify(exportSymbol)}]`;
|
|
962
|
+
return this.getPropertyAccess(obj, exportSymbol);
|
|
717
963
|
}
|
|
718
964
|
} else if (!symbol) {
|
|
719
965
|
invariant(false, 'Asset was skipped or not found.');
|
|
@@ -734,9 +980,7 @@ ${code}
|
|
|
734
980
|
let hoisted = this.hoistedRequires.get(dep.id);
|
|
735
981
|
let res = '';
|
|
736
982
|
let lineCount = 0;
|
|
737
|
-
let isWrapped =
|
|
738
|
-
!this.bundle.hasAsset(resolved) ||
|
|
739
|
-
(this.wrappedAssets.has(resolved.id) && resolved !== parentAsset);
|
|
983
|
+
let isWrapped = this.isWrapped(resolved, parentAsset);
|
|
740
984
|
|
|
741
985
|
// If the resolved asset is wrapped and is imported in the top-level by this asset,
|
|
742
986
|
// we need to run side effects when this asset runs. If the resolved asset is not
|
|
@@ -773,7 +1017,7 @@ ${code}
|
|
|
773
1017
|
let append = '';
|
|
774
1018
|
|
|
775
1019
|
let shouldWrap = this.wrappedAssets.has(asset.id);
|
|
776
|
-
let usedSymbols = this.bundleGraph.getUsedSymbols(asset);
|
|
1020
|
+
let usedSymbols = nullthrows(this.bundleGraph.getUsedSymbols(asset));
|
|
777
1021
|
let assetId = asset.meta.id;
|
|
778
1022
|
invariant(typeof assetId === 'string');
|
|
779
1023
|
|
|
@@ -785,21 +1029,29 @@ ${code}
|
|
|
785
1029
|
usedSymbols.has('default') &&
|
|
786
1030
|
!asset.symbols.hasExportSymbol('__esModule');
|
|
787
1031
|
|
|
788
|
-
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
789
|
-
// The one case where this isn't true is in ESM library entries, where the only
|
|
790
|
-
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
791
|
-
// instead of the namespace object.
|
|
792
1032
|
let usedNamespace =
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
.
|
|
800
|
-
|
|
801
|
-
|
|
802
|
-
|
|
1033
|
+
// If the asset has * in its used symbols, we might need the exports namespace.
|
|
1034
|
+
// The one case where this isn't true is in ESM library entries, where the only
|
|
1035
|
+
// dependency on * is the entry dependency. In this case, we will use ESM exports
|
|
1036
|
+
// instead of the namespace object.
|
|
1037
|
+
(usedSymbols.has('*') &&
|
|
1038
|
+
(this.bundle.env.outputFormat !== 'esmodule' ||
|
|
1039
|
+
!this.bundle.env.isLibrary ||
|
|
1040
|
+
asset !== this.bundle.getMainEntry() ||
|
|
1041
|
+
this.bundleGraph
|
|
1042
|
+
.getIncomingDependencies(asset)
|
|
1043
|
+
.some(
|
|
1044
|
+
dep =>
|
|
1045
|
+
!dep.isEntry &&
|
|
1046
|
+
nullthrows(this.bundleGraph.getUsedSymbols(dep)).has('*'),
|
|
1047
|
+
))) ||
|
|
1048
|
+
// If a symbol is imported (used) from a CJS asset but isn't listed in the symbols,
|
|
1049
|
+
// we fallback on the namespace object.
|
|
1050
|
+
(asset.symbols.hasExportSymbol('*') &&
|
|
1051
|
+
[...usedSymbols].some(s => !asset.symbols.hasExportSymbol(s))) ||
|
|
1052
|
+
// If the exports has this asset's namespace (e.g. ESM output from CJS input),
|
|
1053
|
+
// include the namespace object for the default export.
|
|
1054
|
+
this.exportedSymbols.has(`$${assetId}$exports`);
|
|
803
1055
|
|
|
804
1056
|
// If the asset doesn't have static exports, should wrap, the namespace is used,
|
|
805
1057
|
// or we need default interop, then we need to synthesize a namespace object for
|
|
@@ -832,65 +1084,23 @@ ${code}
|
|
|
832
1084
|
this.usedHelpers.add('$parcel$defineInteropFlag');
|
|
833
1085
|
}
|
|
834
1086
|
|
|
835
|
-
// Find
|
|
836
|
-
//
|
|
837
|
-
//
|
|
838
|
-
let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
|
|
839
|
-
let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
|
|
840
|
-
if (symbol === '*') {
|
|
841
|
-
return false;
|
|
842
|
-
}
|
|
843
|
-
|
|
844
|
-
// If we need default interop, then all symbols are needed because the `default`
|
|
845
|
-
// symbol really maps to the whole namespace.
|
|
846
|
-
if (defaultInterop) {
|
|
847
|
-
return true;
|
|
848
|
-
}
|
|
849
|
-
|
|
850
|
-
let unused = incomingDeps.every(d => {
|
|
851
|
-
let symbols = this.bundleGraph.getUsedSymbols(d);
|
|
852
|
-
return !symbols.has(symbol) && !symbols.has('*');
|
|
853
|
-
});
|
|
854
|
-
return !unused;
|
|
855
|
-
});
|
|
856
|
-
|
|
857
|
-
if (usedExports.length > 0) {
|
|
858
|
-
// Insert $parcel$export calls for each of the used exports. This creates a getter/setter
|
|
859
|
-
// for the symbol so that when the value changes the object property also changes. This is
|
|
860
|
-
// required to simulate ESM live bindings. It's easier to do it this way rather than inserting
|
|
861
|
-
// additional assignments after each mutation of the original binding.
|
|
862
|
-
prepend += `\n${usedExports
|
|
863
|
-
.map(exp => {
|
|
864
|
-
let resolved = this.resolveSymbol(asset, asset, exp);
|
|
865
|
-
return `$parcel$export($${assetId}$exports, ${JSON.stringify(
|
|
866
|
-
exp,
|
|
867
|
-
)}, () => ${resolved}${
|
|
868
|
-
asset.meta.hasCJSExports ? `, (v) => ${resolved} = v` : ''
|
|
869
|
-
});`;
|
|
870
|
-
})
|
|
871
|
-
.join('\n')}\n`;
|
|
872
|
-
this.usedHelpers.add('$parcel$export');
|
|
873
|
-
prependLineCount += 1 + usedExports.length;
|
|
874
|
-
}
|
|
875
|
-
|
|
876
|
-
// Find wildcard re-export dependencies, and make sure their exports are also included in ours.
|
|
1087
|
+
// Find wildcard re-export dependencies, and make sure their exports are also included in
|
|
1088
|
+
// ours. Importantly, add them before the asset's own exports so that wildcard exports get
|
|
1089
|
+
// correctly overwritten by own exports of the same name.
|
|
877
1090
|
for (let dep of deps) {
|
|
878
|
-
let resolved = this.bundleGraph.
|
|
879
|
-
dep,
|
|
880
|
-
this.bundle,
|
|
881
|
-
);
|
|
1091
|
+
let resolved = this.bundleGraph.getResolvedAsset(dep, this.bundle);
|
|
882
1092
|
if (dep.isOptional || this.bundleGraph.isDependencySkipped(dep)) {
|
|
883
1093
|
continue;
|
|
884
1094
|
}
|
|
885
1095
|
|
|
886
|
-
let isWrapped = resolved &&
|
|
1096
|
+
let isWrapped = resolved && resolved.meta.shouldWrap;
|
|
887
1097
|
|
|
888
1098
|
for (let [imported, {local}] of dep.symbols) {
|
|
889
1099
|
if (imported === '*' && local === '*') {
|
|
890
1100
|
if (!resolved) {
|
|
891
1101
|
// Re-exporting an external module. This should have already been handled in buildReplacements.
|
|
892
1102
|
let external = nullthrows(
|
|
893
|
-
nullthrows(this.externals.get(dep.
|
|
1103
|
+
nullthrows(this.externals.get(dep.specifier)).get('*'),
|
|
894
1104
|
);
|
|
895
1105
|
append += `$parcel$exportWildcard($${assetId}$exports, ${external});\n`;
|
|
896
1106
|
this.usedHelpers.add('$parcel$exportWildcard');
|
|
@@ -903,31 +1113,90 @@ ${code}
|
|
|
903
1113
|
if (
|
|
904
1114
|
isWrapped ||
|
|
905
1115
|
resolved.meta.staticExports === false ||
|
|
906
|
-
this.bundleGraph.getUsedSymbols(resolved).has('*')
|
|
1116
|
+
nullthrows(this.bundleGraph.getUsedSymbols(resolved)).has('*') ||
|
|
1117
|
+
// an empty asset
|
|
1118
|
+
(!resolved.meta.hasCJSExports &&
|
|
1119
|
+
resolved.symbols.hasExportSymbol('*'))
|
|
907
1120
|
) {
|
|
908
|
-
let obj = this.
|
|
1121
|
+
let obj = this.getSymbolResolution(asset, resolved, '*', dep);
|
|
909
1122
|
append += `$parcel$exportWildcard($${assetId}$exports, ${obj});\n`;
|
|
910
1123
|
this.usedHelpers.add('$parcel$exportWildcard');
|
|
911
1124
|
} else {
|
|
912
|
-
for (let symbol of
|
|
913
|
-
|
|
1125
|
+
for (let symbol of nullthrows(
|
|
1126
|
+
this.bundleGraph.getUsedSymbols(dep),
|
|
1127
|
+
)) {
|
|
1128
|
+
if (
|
|
1129
|
+
symbol === 'default' || // `export * as ...` does not include the default export
|
|
1130
|
+
symbol === '__esModule'
|
|
1131
|
+
) {
|
|
1132
|
+
continue;
|
|
1133
|
+
}
|
|
1134
|
+
|
|
1135
|
+
let resolvedSymbol = this.getSymbolResolution(
|
|
914
1136
|
asset,
|
|
915
1137
|
resolved,
|
|
916
1138
|
symbol,
|
|
917
1139
|
);
|
|
1140
|
+
let get = this.buildFunctionExpression([], resolvedSymbol);
|
|
1141
|
+
let set = asset.meta.hasCJSExports
|
|
1142
|
+
? ', ' +
|
|
1143
|
+
this.buildFunctionExpression(['v'], `${resolvedSymbol} = v`)
|
|
1144
|
+
: '';
|
|
918
1145
|
prepend += `$parcel$export($${assetId}$exports, ${JSON.stringify(
|
|
919
1146
|
symbol,
|
|
920
|
-
)},
|
|
921
|
-
|
|
922
|
-
? `, (v) => ${resolvedSymbol} = v`
|
|
923
|
-
: ''
|
|
924
|
-
});\n`;
|
|
1147
|
+
)}, ${get}${set});\n`;
|
|
1148
|
+
this.usedHelpers.add('$parcel$export');
|
|
925
1149
|
prependLineCount++;
|
|
926
1150
|
}
|
|
927
1151
|
}
|
|
928
1152
|
}
|
|
929
1153
|
}
|
|
930
1154
|
}
|
|
1155
|
+
|
|
1156
|
+
// Find the used exports of this module. This is based on the used symbols of
|
|
1157
|
+
// incoming dependencies rather than the asset's own used exports so that we include
|
|
1158
|
+
// re-exported symbols rather than only symbols declared in this asset.
|
|
1159
|
+
let incomingDeps = this.bundleGraph.getIncomingDependencies(asset);
|
|
1160
|
+
let usedExports = [...asset.symbols.exportSymbols()].filter(symbol => {
|
|
1161
|
+
if (symbol === '*') {
|
|
1162
|
+
return false;
|
|
1163
|
+
}
|
|
1164
|
+
|
|
1165
|
+
// If we need default interop, then all symbols are needed because the `default`
|
|
1166
|
+
// symbol really maps to the whole namespace.
|
|
1167
|
+
if (defaultInterop) {
|
|
1168
|
+
return true;
|
|
1169
|
+
}
|
|
1170
|
+
|
|
1171
|
+
let unused = incomingDeps.every(d => {
|
|
1172
|
+
let symbols = nullthrows(this.bundleGraph.getUsedSymbols(d));
|
|
1173
|
+
return !symbols.has(symbol) && !symbols.has('*');
|
|
1174
|
+
});
|
|
1175
|
+
return !unused;
|
|
1176
|
+
});
|
|
1177
|
+
|
|
1178
|
+
if (usedExports.length > 0) {
|
|
1179
|
+
// Insert $parcel$export calls for each of the used exports. This creates a getter/setter
|
|
1180
|
+
// for the symbol so that when the value changes the object property also changes. This is
|
|
1181
|
+
// required to simulate ESM live bindings. It's easier to do it this way rather than inserting
|
|
1182
|
+
// additional assignments after each mutation of the original binding.
|
|
1183
|
+
prepend += `\n${usedExports
|
|
1184
|
+
.map(exp => {
|
|
1185
|
+
let resolved = this.getSymbolResolution(asset, asset, exp);
|
|
1186
|
+
let get = this.buildFunctionExpression([], resolved);
|
|
1187
|
+
let isEsmExport = !!asset.symbols.get(exp)?.meta?.isEsm;
|
|
1188
|
+
let set =
|
|
1189
|
+
!isEsmExport && asset.meta.hasCJSExports
|
|
1190
|
+
? ', ' + this.buildFunctionExpression(['v'], `${resolved} = v`)
|
|
1191
|
+
: '';
|
|
1192
|
+
return `$parcel$export($${assetId}$exports, ${JSON.stringify(
|
|
1193
|
+
exp,
|
|
1194
|
+
)}, ${get}${set});`;
|
|
1195
|
+
})
|
|
1196
|
+
.join('\n')}\n`;
|
|
1197
|
+
this.usedHelpers.add('$parcel$export');
|
|
1198
|
+
prependLineCount += 1 + usedExports.length;
|
|
1199
|
+
}
|
|
931
1200
|
}
|
|
932
1201
|
|
|
933
1202
|
return [prepend, prependLineCount, append];
|
|
@@ -954,10 +1223,8 @@ ${code}
|
|
|
954
1223
|
}
|
|
955
1224
|
|
|
956
1225
|
// The output format may have specific things to add at the start of the bundle (e.g. imports).
|
|
957
|
-
let [
|
|
958
|
-
|
|
959
|
-
outputFormatLines,
|
|
960
|
-
] = this.outputFormat.buildBundlePrelude();
|
|
1226
|
+
let [outputFormatPrelude, outputFormatLines] =
|
|
1227
|
+
this.outputFormat.buildBundlePrelude();
|
|
961
1228
|
res += outputFormatPrelude;
|
|
962
1229
|
lines += outputFormatLines;
|
|
963
1230
|
|
|
@@ -967,9 +1234,13 @@ ${code}
|
|
|
967
1234
|
}
|
|
968
1235
|
|
|
969
1236
|
for (let helper of this.usedHelpers) {
|
|
970
|
-
|
|
1237
|
+
let currentHelper = helpers[helper];
|
|
1238
|
+
if (typeof currentHelper === 'function') {
|
|
1239
|
+
currentHelper = helpers[helper](this.bundle.env);
|
|
1240
|
+
}
|
|
1241
|
+
res += currentHelper;
|
|
971
1242
|
if (enableSourceMaps) {
|
|
972
|
-
lines += countLines(
|
|
1243
|
+
lines += countLines(currentHelper) - 1;
|
|
973
1244
|
}
|
|
974
1245
|
}
|
|
975
1246
|
|
|
@@ -984,7 +1255,7 @@ ${code}
|
|
|
984
1255
|
.getBundleGroupsContainingBundle(this.bundle)
|
|
985
1256
|
.some(g => this.bundleGraph.isEntryBundleGroup(g)) ||
|
|
986
1257
|
this.bundle.env.isIsolated() ||
|
|
987
|
-
|
|
1258
|
+
this.bundle.bundleBehavior === 'isolated';
|
|
988
1259
|
|
|
989
1260
|
if (mightBeFirstJS) {
|
|
990
1261
|
let preludeCode = prelude(this.parcelRequireName);
|
|
@@ -992,24 +1263,38 @@ ${code}
|
|
|
992
1263
|
if (enableSourceMaps) {
|
|
993
1264
|
lines += countLines(preludeCode) - 1;
|
|
994
1265
|
}
|
|
1266
|
+
|
|
1267
|
+
if (this.shouldBundleQueue(this.bundle)) {
|
|
1268
|
+
let bundleQueuePreludeCode = bundleQueuePrelude(this.bundle.env);
|
|
1269
|
+
res += bundleQueuePreludeCode;
|
|
1270
|
+
if (enableSourceMaps) {
|
|
1271
|
+
lines += countLines(bundleQueuePreludeCode) - 1;
|
|
1272
|
+
}
|
|
1273
|
+
}
|
|
995
1274
|
} else {
|
|
996
1275
|
// Otherwise, get the current parcelRequire global.
|
|
997
|
-
|
|
998
|
-
|
|
999
|
-
|
|
1276
|
+
const escaped = JSON.stringify(this.parcelRequireName);
|
|
1277
|
+
res += `var parcelRequire = $parcel$global[${escaped}];\n`;
|
|
1278
|
+
lines++;
|
|
1279
|
+
res += `var parcelRegister = parcelRequire.register;\n`;
|
|
1000
1280
|
lines++;
|
|
1001
1281
|
}
|
|
1002
1282
|
}
|
|
1003
1283
|
|
|
1004
1284
|
// Add importScripts for sibling bundles in workers.
|
|
1005
|
-
if (this.bundle.env.isWorker()) {
|
|
1285
|
+
if (this.bundle.env.isWorker() || this.bundle.env.isWorklet()) {
|
|
1006
1286
|
let importScripts = '';
|
|
1007
1287
|
let bundles = this.bundleGraph.getReferencedBundles(this.bundle);
|
|
1008
1288
|
for (let b of bundles) {
|
|
1009
|
-
|
|
1010
|
-
|
|
1011
|
-
b
|
|
1012
|
-
|
|
1289
|
+
if (this.bundle.env.outputFormat === 'esmodule') {
|
|
1290
|
+
// importScripts() is not allowed in native ES module workers.
|
|
1291
|
+
importScripts += `import "${relativeBundlePath(this.bundle, b)}";\n`;
|
|
1292
|
+
} else {
|
|
1293
|
+
importScripts += `importScripts("${relativeBundlePath(
|
|
1294
|
+
this.bundle,
|
|
1295
|
+
b,
|
|
1296
|
+
)}");\n`;
|
|
1297
|
+
}
|
|
1013
1298
|
}
|
|
1014
1299
|
|
|
1015
1300
|
res += importScripts;
|
|
@@ -1037,10 +1322,28 @@ ${code}
|
|
|
1037
1322
|
}
|
|
1038
1323
|
|
|
1039
1324
|
shouldSkipAsset(asset: Asset): boolean {
|
|
1325
|
+
if (this.isScriptEntry(asset)) {
|
|
1326
|
+
return true;
|
|
1327
|
+
}
|
|
1328
|
+
|
|
1040
1329
|
return (
|
|
1041
1330
|
asset.sideEffects === false &&
|
|
1042
|
-
this.bundleGraph.getUsedSymbols(asset).size == 0 &&
|
|
1043
|
-
!this.bundleGraph.
|
|
1331
|
+
nullthrows(this.bundleGraph.getUsedSymbols(asset)).size == 0 &&
|
|
1332
|
+
!this.bundleGraph.isAssetReferenced(this.bundle, asset)
|
|
1333
|
+
);
|
|
1334
|
+
}
|
|
1335
|
+
|
|
1336
|
+
isScriptEntry(asset: Asset): boolean {
|
|
1337
|
+
return (
|
|
1338
|
+
this.bundle.env.outputFormat === 'global' &&
|
|
1339
|
+
this.bundle.env.sourceType === 'script' &&
|
|
1340
|
+
asset === this.bundle.getMainEntry()
|
|
1044
1341
|
);
|
|
1045
1342
|
}
|
|
1343
|
+
|
|
1344
|
+
buildFunctionExpression(args: Array<string>, expr: string): string {
|
|
1345
|
+
return this.bundle.env.supports('arrow-functions', true)
|
|
1346
|
+
? `(${args.join(', ')}) => ${expr}`
|
|
1347
|
+
: `function (${args.join(', ')}) { return ${expr}; }`;
|
|
1348
|
+
}
|
|
1046
1349
|
}
|