@parcel/packager-js 2.0.0-nightly.1358 → 2.0.0-nightly.1359
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/ESMOutputFormat.js +5 -0
- package/lib/ScopeHoistingPackager.js +29 -1
- package/lib/helpers.js +31 -1
- package/lib/index.js +29 -3
- package/package.json +8 -8
- package/src/ESMOutputFormat.js +8 -0
- package/src/ScopeHoistingPackager.js +63 -1
- package/src/helpers.js +68 -0
- package/src/index.js +44 -2
package/lib/ESMOutputFormat.js
CHANGED
|
@@ -88,6 +88,11 @@ class ESMOutputFormat {
|
|
|
88
88
|
res += `\nexport {${exportSpecifiers.join(', ')}};`;
|
|
89
89
|
lines++;
|
|
90
90
|
}
|
|
91
|
+
if (this.packager.shouldBundleQueue(this.packager.bundle)) {
|
|
92
|
+
// Should be last thing the bundle executes on intial eval
|
|
93
|
+
res += `\n$parcel$global.rlb(${JSON.stringify(this.packager.bundle.publicId)})`;
|
|
94
|
+
lines++;
|
|
95
|
+
}
|
|
91
96
|
return [res, lines];
|
|
92
97
|
}
|
|
93
98
|
}
|
|
@@ -94,11 +94,12 @@ class ScopeHoistingPackager {
|
|
|
94
94
|
needsPrelude = false;
|
|
95
95
|
usedHelpers = new Set();
|
|
96
96
|
externalAssets = new Set();
|
|
97
|
-
constructor(options, bundleGraph, bundle, parcelRequireName) {
|
|
97
|
+
constructor(options, bundleGraph, bundle, parcelRequireName, useAsyncBundleRuntime) {
|
|
98
98
|
this.options = options;
|
|
99
99
|
this.bundleGraph = bundleGraph;
|
|
100
100
|
this.bundle = bundle;
|
|
101
101
|
this.parcelRequireName = parcelRequireName;
|
|
102
|
+
this.useAsyncBundleRuntime = useAsyncBundleRuntime;
|
|
102
103
|
let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
|
|
103
104
|
this.outputFormat = new OutputFormat(this);
|
|
104
105
|
this.isAsyncBundle = this.bundleGraph.hasParentBundleOfType(this.bundle, 'js') && !this.bundle.env.isIsolated() && this.bundle.bundleBehavior !== 'isolated';
|
|
@@ -181,6 +182,7 @@ class ScopeHoistingPackager {
|
|
|
181
182
|
});
|
|
182
183
|
mainEntry = null;
|
|
183
184
|
}
|
|
185
|
+
let needsBundleQueue = this.shouldBundleQueue(this.bundle);
|
|
184
186
|
|
|
185
187
|
// If any of the entry assets are wrapped, call parcelRequire so they are executed.
|
|
186
188
|
for (let entry of entries) {
|
|
@@ -189,8 +191,12 @@ class ScopeHoistingPackager {
|
|
|
189
191
|
let parcelRequire = `parcelRequire(${JSON.stringify(this.bundleGraph.getAssetPublicId(entry))});\n`;
|
|
190
192
|
let entryExports = (_entry$symbols$get = entry.symbols.get('*')) === null || _entry$symbols$get === void 0 ? void 0 : _entry$symbols$get.local;
|
|
191
193
|
if (entryExports && entry === mainEntry && this.exportedSymbols.has(entryExports)) {
|
|
194
|
+
(0, _assert().default)(!needsBundleQueue, 'Entry exports are not yet compaitble with async bundles');
|
|
192
195
|
res += `\nvar ${entryExports} = ${parcelRequire}`;
|
|
193
196
|
} else {
|
|
197
|
+
if (needsBundleQueue) {
|
|
198
|
+
parcelRequire = this.runWhenReady(this.bundle, parcelRequire);
|
|
199
|
+
}
|
|
194
200
|
res += `\n${parcelRequire}`;
|
|
195
201
|
}
|
|
196
202
|
lineCount += 2;
|
|
@@ -225,6 +231,18 @@ class ScopeHoistingPackager {
|
|
|
225
231
|
map: sourceMap
|
|
226
232
|
};
|
|
227
233
|
}
|
|
234
|
+
shouldBundleQueue(bundle) {
|
|
235
|
+
return this.useAsyncBundleRuntime && bundle.type === 'js' && bundle.bundleBehavior !== 'inline' && bundle.env.outputFormat === 'esmodule' && !bundle.env.isIsolated() && bundle.bundleBehavior !== 'isolated' && !this.bundleGraph.hasParentBundleOfType(bundle, 'js');
|
|
236
|
+
}
|
|
237
|
+
runWhenReady(bundle, codeToRun) {
|
|
238
|
+
let deps = this.bundleGraph.getReferencedBundles(bundle).filter(b => this.shouldBundleQueue(b)).map(b => b.publicId);
|
|
239
|
+
if (deps.length === 0) {
|
|
240
|
+
// If no deps we can safely execute immediately
|
|
241
|
+
return codeToRun;
|
|
242
|
+
}
|
|
243
|
+
let params = [JSON.stringify(this.bundle.publicId), (0, _helpers.fnExpr)(this.bundle.env, [], [codeToRun]), JSON.stringify(deps)];
|
|
244
|
+
return `$parcel$global.rwr(${params.join(', ')});`;
|
|
245
|
+
}
|
|
228
246
|
async loadAssets() {
|
|
229
247
|
let queue = new (_utils().PromiseQueue)({
|
|
230
248
|
maxConcurrent: 32
|
|
@@ -494,6 +512,9 @@ ${code}
|
|
|
494
512
|
}
|
|
495
513
|
this.needsPrelude = true;
|
|
496
514
|
}
|
|
515
|
+
if (!shouldWrap && this.shouldBundleQueue(this.bundle) && this.bundle.getEntryAssets().some(entry => entry.id === asset.id)) {
|
|
516
|
+
code = this.runWhenReady(this.bundle, code);
|
|
517
|
+
}
|
|
497
518
|
return [code, sourceMap, lineCount];
|
|
498
519
|
}
|
|
499
520
|
buildReplacements(asset, deps) {
|
|
@@ -902,6 +923,13 @@ ${code}
|
|
|
902
923
|
if (enableSourceMaps) {
|
|
903
924
|
lines += (0, _utils().countLines)(preludeCode) - 1;
|
|
904
925
|
}
|
|
926
|
+
if (this.shouldBundleQueue(this.bundle)) {
|
|
927
|
+
let bundleQueuePreludeCode = (0, _helpers.bundleQueuePrelude)(this.bundle.env);
|
|
928
|
+
res += bundleQueuePreludeCode;
|
|
929
|
+
if (enableSourceMaps) {
|
|
930
|
+
lines += (0, _utils().countLines)(bundleQueuePreludeCode) - 1;
|
|
931
|
+
}
|
|
932
|
+
}
|
|
905
933
|
} else {
|
|
906
934
|
// Otherwise, get the current parcelRequire global.
|
|
907
935
|
res += `var parcelRequire = $parcel$global[${JSON.stringify(this.parcelRequireName)}];\n`;
|
package/lib/helpers.js
CHANGED
|
@@ -3,7 +3,7 @@
|
|
|
3
3
|
Object.defineProperty(exports, "__esModule", {
|
|
4
4
|
value: true
|
|
5
5
|
});
|
|
6
|
-
exports.prelude = exports.helpers = void 0;
|
|
6
|
+
exports.prelude = exports.helpers = exports.fnExpr = exports.bundleQueuePrelude = void 0;
|
|
7
7
|
const prelude = parcelRequireName => `
|
|
8
8
|
var $parcel$modules = {};
|
|
9
9
|
var $parcel$inits = {};
|
|
@@ -35,6 +35,36 @@ if (parcelRequire == null) {
|
|
|
35
35
|
}
|
|
36
36
|
`;
|
|
37
37
|
exports.prelude = prelude;
|
|
38
|
+
const fnExpr = (env, params, body) => {
|
|
39
|
+
let block = `{ ${body.join(' ')} }`;
|
|
40
|
+
if (env.supports('arrow-functions')) {
|
|
41
|
+
return `(${params.join(', ')}) => ${block}`;
|
|
42
|
+
}
|
|
43
|
+
return `function (${params.join(', ')}) ${block}`;
|
|
44
|
+
};
|
|
45
|
+
exports.fnExpr = fnExpr;
|
|
46
|
+
const bundleQueuePrelude = env => `
|
|
47
|
+
if (!$parcel$global.lb) {
|
|
48
|
+
// Set of loaded bundles
|
|
49
|
+
$parcel$global.lb = new Set();
|
|
50
|
+
// Queue of bundles to execute once they're dep bundles are loaded
|
|
51
|
+
$parcel$global.bq = [];
|
|
52
|
+
|
|
53
|
+
// Register loaded bundle
|
|
54
|
+
$parcel$global.rlb = ${fnExpr(env, ['bundle'], ['$parcel$global.lb.add(bundle);', '$parcel$global.pq();'])}
|
|
55
|
+
|
|
56
|
+
// Run when ready
|
|
57
|
+
$parcel$global.rwr = ${fnExpr(env,
|
|
58
|
+
// b = bundle public id
|
|
59
|
+
// r = run function to execute the bundle entry
|
|
60
|
+
// d = list of dependent bundles this bundle requires before executing
|
|
61
|
+
['b', 'r', 'd'], ['$parcel$global.bq.push({b, r, d});', '$parcel$global.pq();'])}
|
|
62
|
+
|
|
63
|
+
// Process queue
|
|
64
|
+
$parcel$global.pq = ${fnExpr(env, [], [`var runnableEntry = $parcel$global.bq.find(${fnExpr(env, ['i'], [`return i.d.every(${fnExpr(env, ['dep'], ['return $parcel$global.lb.has(dep);'])});`])});`, 'if (runnableEntry) {', `$parcel$global.bq = $parcel$global.bq.filter(${fnExpr(env, ['i'], ['return i.b !== runnableEntry.b;'])});`, 'runnableEntry.r();', '$parcel$global.pq();', '}'])}
|
|
65
|
+
}
|
|
66
|
+
`;
|
|
67
|
+
exports.bundleQueuePrelude = bundleQueuePrelude;
|
|
38
68
|
const $parcel$export = `
|
|
39
69
|
function $parcel$export(e, n, v, s) {
|
|
40
70
|
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
package/lib/index.js
CHANGED
|
@@ -18,6 +18,13 @@ function _utils() {
|
|
|
18
18
|
};
|
|
19
19
|
return data;
|
|
20
20
|
}
|
|
21
|
+
function _diagnostic() {
|
|
22
|
+
const data = require("@parcel/diagnostic");
|
|
23
|
+
_diagnostic = function () {
|
|
24
|
+
return data;
|
|
25
|
+
};
|
|
26
|
+
return data;
|
|
27
|
+
}
|
|
21
28
|
function _hash() {
|
|
22
29
|
const data = require("@parcel/hash");
|
|
23
30
|
_hash = function () {
|
|
@@ -42,18 +49,37 @@ function _nullthrows() {
|
|
|
42
49
|
var _DevPackager = require("./DevPackager");
|
|
43
50
|
var _ScopeHoistingPackager = require("./ScopeHoistingPackager");
|
|
44
51
|
function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
|
|
52
|
+
const CONFIG_SCHEMA = {
|
|
53
|
+
type: 'object',
|
|
54
|
+
properties: {
|
|
55
|
+
unstable_asyncBundleRuntime: {
|
|
56
|
+
type: 'boolean'
|
|
57
|
+
}
|
|
58
|
+
},
|
|
59
|
+
additionalProperties: false
|
|
60
|
+
};
|
|
45
61
|
var _default = new (_plugin().Packager)({
|
|
46
62
|
async loadConfig({
|
|
47
63
|
config,
|
|
48
64
|
options
|
|
49
65
|
}) {
|
|
50
|
-
var _pkg$contents$name, _pkg$contents;
|
|
66
|
+
var _pkg$contents$name, _pkg$contents, _pkg$contents$package;
|
|
51
67
|
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
52
68
|
// This allows multiple parcel builds to coexist on the same page.
|
|
53
69
|
let pkg = await config.getConfigFrom(_path().default.join(options.projectRoot, 'index'), ['package.json']);
|
|
70
|
+
let packageKey = '@parcel/packager-js';
|
|
71
|
+
if (pkg !== null && pkg !== void 0 && pkg.contents[packageKey]) {
|
|
72
|
+
_utils().validateSchema.diagnostic(CONFIG_SCHEMA, {
|
|
73
|
+
data: pkg === null || pkg === void 0 ? void 0 : pkg.contents[packageKey],
|
|
74
|
+
source: await options.inputFS.readFile(pkg.filePath, 'utf8'),
|
|
75
|
+
filePath: pkg.filePath,
|
|
76
|
+
prependKey: `/${(0, _diagnostic().encodeJSONKeyComponent)(packageKey)}`
|
|
77
|
+
}, packageKey, `Invalid config for ${packageKey}`);
|
|
78
|
+
}
|
|
54
79
|
let name = (_pkg$contents$name = pkg === null || pkg === void 0 ? void 0 : (_pkg$contents = pkg.contents) === null || _pkg$contents === void 0 ? void 0 : _pkg$contents.name) !== null && _pkg$contents$name !== void 0 ? _pkg$contents$name : '';
|
|
55
80
|
return {
|
|
56
|
-
parcelRequireName: 'parcelRequire' + (0, _hash().hashString)(name).slice(-4)
|
|
81
|
+
parcelRequireName: 'parcelRequire' + (0, _hash().hashString)(name).slice(-4),
|
|
82
|
+
unstable_asyncBundleRuntime: Boolean(pkg === null || pkg === void 0 ? void 0 : (_pkg$contents$package = pkg.contents[packageKey]) === null || _pkg$contents$package === void 0 ? void 0 : _pkg$contents$package.unstable_asyncBundleRuntime)
|
|
57
83
|
};
|
|
58
84
|
},
|
|
59
85
|
async package({
|
|
@@ -75,7 +101,7 @@ var _default = new (_plugin().Packager)({
|
|
|
75
101
|
}
|
|
76
102
|
}
|
|
77
103
|
if (contents == null) {
|
|
78
|
-
let packager = bundle.env.shouldScopeHoist ? new _ScopeHoistingPackager.ScopeHoistingPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName) : new _DevPackager.DevPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName);
|
|
104
|
+
let packager = bundle.env.shouldScopeHoist ? new _ScopeHoistingPackager.ScopeHoistingPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName, (0, _nullthrows().default)(config).unstable_asyncBundleRuntime) : new _DevPackager.DevPackager(options, bundleGraph, bundle, (0, _nullthrows().default)(config).parcelRequireName);
|
|
79
105
|
({
|
|
80
106
|
contents,
|
|
81
107
|
map
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@parcel/packager-js",
|
|
3
|
-
"version": "2.0.0-nightly.
|
|
3
|
+
"version": "2.0.0-nightly.1359+0b5edcfaf",
|
|
4
4
|
"license": "MIT",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,17 +17,17 @@
|
|
|
17
17
|
"source": "src/index.js",
|
|
18
18
|
"engines": {
|
|
19
19
|
"node": ">= 12.0.0",
|
|
20
|
-
"parcel": "2.0.0-nightly.
|
|
20
|
+
"parcel": "2.0.0-nightly.1357+0b5edcfaf"
|
|
21
21
|
},
|
|
22
22
|
"dependencies": {
|
|
23
|
-
"@parcel/diagnostic": "2.0.0-nightly.
|
|
24
|
-
"@parcel/hash": "2.9.4-nightly.
|
|
25
|
-
"@parcel/plugin": "2.0.0-nightly.
|
|
23
|
+
"@parcel/diagnostic": "2.0.0-nightly.1359+0b5edcfaf",
|
|
24
|
+
"@parcel/hash": "2.9.4-nightly.2982+0b5edcfaf",
|
|
25
|
+
"@parcel/plugin": "2.0.0-nightly.1359+0b5edcfaf",
|
|
26
26
|
"@parcel/source-map": "^2.1.1",
|
|
27
|
-
"@parcel/types": "2.0.0-nightly.
|
|
28
|
-
"@parcel/utils": "2.0.0-nightly.
|
|
27
|
+
"@parcel/types": "2.0.0-nightly.1359+0b5edcfaf",
|
|
28
|
+
"@parcel/utils": "2.0.0-nightly.1359+0b5edcfaf",
|
|
29
29
|
"globals": "^13.2.0",
|
|
30
30
|
"nullthrows": "^1.1.1"
|
|
31
31
|
},
|
|
32
|
-
"gitHead": "
|
|
32
|
+
"gitHead": "0b5edcfaf174a62f454f774d1c78cbf0004cb457"
|
|
33
33
|
}
|
package/src/ESMOutputFormat.js
CHANGED
|
@@ -106,6 +106,14 @@ export class ESMOutputFormat implements OutputFormat {
|
|
|
106
106
|
lines++;
|
|
107
107
|
}
|
|
108
108
|
|
|
109
|
+
if (this.packager.shouldBundleQueue(this.packager.bundle)) {
|
|
110
|
+
// Should be last thing the bundle executes on intial eval
|
|
111
|
+
res += `\n$parcel$global.rlb(${JSON.stringify(
|
|
112
|
+
this.packager.bundle.publicId,
|
|
113
|
+
)})`;
|
|
114
|
+
lines++;
|
|
115
|
+
}
|
|
116
|
+
|
|
109
117
|
return [res, lines];
|
|
110
118
|
}
|
|
111
119
|
}
|
|
@@ -27,7 +27,7 @@ import path from 'path';
|
|
|
27
27
|
import {ESMOutputFormat} from './ESMOutputFormat';
|
|
28
28
|
import {CJSOutputFormat} from './CJSOutputFormat';
|
|
29
29
|
import {GlobalOutputFormat} from './GlobalOutputFormat';
|
|
30
|
-
import {prelude, helpers} from './helpers';
|
|
30
|
+
import {prelude, helpers, bundleQueuePrelude, fnExpr} from './helpers';
|
|
31
31
|
import {replaceScriptDependencies, getSpecifier} from './utils';
|
|
32
32
|
|
|
33
33
|
// https://262.ecma-international.org/6.0/#sec-names-and-keywords
|
|
@@ -74,6 +74,7 @@ export class ScopeHoistingPackager {
|
|
|
74
74
|
bundleGraph: BundleGraph<NamedBundle>;
|
|
75
75
|
bundle: NamedBundle;
|
|
76
76
|
parcelRequireName: string;
|
|
77
|
+
useAsyncBundleRuntime: boolean;
|
|
77
78
|
outputFormat: OutputFormat;
|
|
78
79
|
isAsyncBundle: boolean;
|
|
79
80
|
globalNames: $ReadOnlySet<string>;
|
|
@@ -101,11 +102,13 @@ export class ScopeHoistingPackager {
|
|
|
101
102
|
bundleGraph: BundleGraph<NamedBundle>,
|
|
102
103
|
bundle: NamedBundle,
|
|
103
104
|
parcelRequireName: string,
|
|
105
|
+
useAsyncBundleRuntime: boolean,
|
|
104
106
|
) {
|
|
105
107
|
this.options = options;
|
|
106
108
|
this.bundleGraph = bundleGraph;
|
|
107
109
|
this.bundle = bundle;
|
|
108
110
|
this.parcelRequireName = parcelRequireName;
|
|
111
|
+
this.useAsyncBundleRuntime = useAsyncBundleRuntime;
|
|
109
112
|
|
|
110
113
|
let OutputFormat = OUTPUT_FORMATS[this.bundle.env.outputFormat];
|
|
111
114
|
this.outputFormat = new OutputFormat(this);
|
|
@@ -202,6 +205,8 @@ export class ScopeHoistingPackager {
|
|
|
202
205
|
mainEntry = null;
|
|
203
206
|
}
|
|
204
207
|
|
|
208
|
+
let needsBundleQueue = this.shouldBundleQueue(this.bundle);
|
|
209
|
+
|
|
205
210
|
// If any of the entry assets are wrapped, call parcelRequire so they are executed.
|
|
206
211
|
for (let entry of entries) {
|
|
207
212
|
if (this.wrappedAssets.has(entry.id) && !this.isScriptEntry(entry)) {
|
|
@@ -210,13 +215,22 @@ export class ScopeHoistingPackager {
|
|
|
210
215
|
)});\n`;
|
|
211
216
|
|
|
212
217
|
let entryExports = entry.symbols.get('*')?.local;
|
|
218
|
+
|
|
213
219
|
if (
|
|
214
220
|
entryExports &&
|
|
215
221
|
entry === mainEntry &&
|
|
216
222
|
this.exportedSymbols.has(entryExports)
|
|
217
223
|
) {
|
|
224
|
+
invariant(
|
|
225
|
+
!needsBundleQueue,
|
|
226
|
+
'Entry exports are not yet compaitble with async bundles',
|
|
227
|
+
);
|
|
218
228
|
res += `\nvar ${entryExports} = ${parcelRequire}`;
|
|
219
229
|
} else {
|
|
230
|
+
if (needsBundleQueue) {
|
|
231
|
+
parcelRequire = this.runWhenReady(this.bundle, parcelRequire);
|
|
232
|
+
}
|
|
233
|
+
|
|
220
234
|
res += `\n${parcelRequire}`;
|
|
221
235
|
}
|
|
222
236
|
|
|
@@ -264,6 +278,38 @@ export class ScopeHoistingPackager {
|
|
|
264
278
|
};
|
|
265
279
|
}
|
|
266
280
|
|
|
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
|
+
|
|
267
313
|
async loadAssets(): Promise<Array<Asset>> {
|
|
268
314
|
let queue = new PromiseQueue({maxConcurrent: 32});
|
|
269
315
|
let wrapped = [];
|
|
@@ -599,6 +645,14 @@ ${code}
|
|
|
599
645
|
this.needsPrelude = true;
|
|
600
646
|
}
|
|
601
647
|
|
|
648
|
+
if (
|
|
649
|
+
!shouldWrap &&
|
|
650
|
+
this.shouldBundleQueue(this.bundle) &&
|
|
651
|
+
this.bundle.getEntryAssets().some(entry => entry.id === asset.id)
|
|
652
|
+
) {
|
|
653
|
+
code = this.runWhenReady(this.bundle, code);
|
|
654
|
+
}
|
|
655
|
+
|
|
602
656
|
return [code, sourceMap, lineCount];
|
|
603
657
|
}
|
|
604
658
|
|
|
@@ -1199,6 +1253,14 @@ ${code}
|
|
|
1199
1253
|
if (enableSourceMaps) {
|
|
1200
1254
|
lines += countLines(preludeCode) - 1;
|
|
1201
1255
|
}
|
|
1256
|
+
|
|
1257
|
+
if (this.shouldBundleQueue(this.bundle)) {
|
|
1258
|
+
let bundleQueuePreludeCode = bundleQueuePrelude(this.bundle.env);
|
|
1259
|
+
res += bundleQueuePreludeCode;
|
|
1260
|
+
if (enableSourceMaps) {
|
|
1261
|
+
lines += countLines(bundleQueuePreludeCode) - 1;
|
|
1262
|
+
}
|
|
1263
|
+
}
|
|
1202
1264
|
} else {
|
|
1203
1265
|
// Otherwise, get the current parcelRequire global.
|
|
1204
1266
|
res += `var parcelRequire = $parcel$global[${JSON.stringify(
|
package/src/helpers.js
CHANGED
|
@@ -32,6 +32,74 @@ if (parcelRequire == null) {
|
|
|
32
32
|
}
|
|
33
33
|
`;
|
|
34
34
|
|
|
35
|
+
export const fnExpr = (
|
|
36
|
+
env: Environment,
|
|
37
|
+
params: Array<string>,
|
|
38
|
+
body: Array<string>,
|
|
39
|
+
): string => {
|
|
40
|
+
let block = `{ ${body.join(' ')} }`;
|
|
41
|
+
|
|
42
|
+
if (env.supports('arrow-functions')) {
|
|
43
|
+
return `(${params.join(', ')}) => ${block}`;
|
|
44
|
+
}
|
|
45
|
+
|
|
46
|
+
return `function (${params.join(', ')}) ${block}`;
|
|
47
|
+
};
|
|
48
|
+
|
|
49
|
+
export const bundleQueuePrelude = (env: Environment): string => `
|
|
50
|
+
if (!$parcel$global.lb) {
|
|
51
|
+
// Set of loaded bundles
|
|
52
|
+
$parcel$global.lb = new Set();
|
|
53
|
+
// Queue of bundles to execute once they're dep bundles are loaded
|
|
54
|
+
$parcel$global.bq = [];
|
|
55
|
+
|
|
56
|
+
// Register loaded bundle
|
|
57
|
+
$parcel$global.rlb = ${fnExpr(
|
|
58
|
+
env,
|
|
59
|
+
['bundle'],
|
|
60
|
+
['$parcel$global.lb.add(bundle);', '$parcel$global.pq();'],
|
|
61
|
+
)}
|
|
62
|
+
|
|
63
|
+
// Run when ready
|
|
64
|
+
$parcel$global.rwr = ${fnExpr(
|
|
65
|
+
env,
|
|
66
|
+
// b = bundle public id
|
|
67
|
+
// r = run function to execute the bundle entry
|
|
68
|
+
// d = list of dependent bundles this bundle requires before executing
|
|
69
|
+
['b', 'r', 'd'],
|
|
70
|
+
['$parcel$global.bq.push({b, r, d});', '$parcel$global.pq();'],
|
|
71
|
+
)}
|
|
72
|
+
|
|
73
|
+
// Process queue
|
|
74
|
+
$parcel$global.pq = ${fnExpr(
|
|
75
|
+
env,
|
|
76
|
+
[],
|
|
77
|
+
[
|
|
78
|
+
`var runnableEntry = $parcel$global.bq.find(${fnExpr(
|
|
79
|
+
env,
|
|
80
|
+
['i'],
|
|
81
|
+
[
|
|
82
|
+
`return i.d.every(${fnExpr(
|
|
83
|
+
env,
|
|
84
|
+
['dep'],
|
|
85
|
+
['return $parcel$global.lb.has(dep);'],
|
|
86
|
+
)});`,
|
|
87
|
+
],
|
|
88
|
+
)});`,
|
|
89
|
+
'if (runnableEntry) {',
|
|
90
|
+
`$parcel$global.bq = $parcel$global.bq.filter(${fnExpr(
|
|
91
|
+
env,
|
|
92
|
+
['i'],
|
|
93
|
+
['return i.b !== runnableEntry.b;'],
|
|
94
|
+
)});`,
|
|
95
|
+
'runnableEntry.r();',
|
|
96
|
+
'$parcel$global.pq();',
|
|
97
|
+
'}',
|
|
98
|
+
],
|
|
99
|
+
)}
|
|
100
|
+
}
|
|
101
|
+
`;
|
|
102
|
+
|
|
35
103
|
const $parcel$export = `
|
|
36
104
|
function $parcel$export(e, n, v, s) {
|
|
37
105
|
Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});
|
package/src/index.js
CHANGED
|
@@ -2,24 +2,65 @@
|
|
|
2
2
|
import type {Async} from '@parcel/types';
|
|
3
3
|
import type SourceMap from '@parcel/source-map';
|
|
4
4
|
import {Packager} from '@parcel/plugin';
|
|
5
|
-
import {
|
|
5
|
+
import {
|
|
6
|
+
replaceInlineReferences,
|
|
7
|
+
replaceURLReferences,
|
|
8
|
+
validateSchema,
|
|
9
|
+
type SchemaEntity,
|
|
10
|
+
} from '@parcel/utils';
|
|
11
|
+
import {encodeJSONKeyComponent} from '@parcel/diagnostic';
|
|
6
12
|
import {hashString} from '@parcel/hash';
|
|
7
13
|
import path from 'path';
|
|
8
14
|
import nullthrows from 'nullthrows';
|
|
9
15
|
import {DevPackager} from './DevPackager';
|
|
10
16
|
import {ScopeHoistingPackager} from './ScopeHoistingPackager';
|
|
11
17
|
|
|
18
|
+
type JSPackagerConfig = {|
|
|
19
|
+
parcelRequireName: string,
|
|
20
|
+
unstable_asyncBundleRuntime: boolean,
|
|
21
|
+
|};
|
|
22
|
+
|
|
23
|
+
const CONFIG_SCHEMA: SchemaEntity = {
|
|
24
|
+
type: 'object',
|
|
25
|
+
properties: {
|
|
26
|
+
unstable_asyncBundleRuntime: {
|
|
27
|
+
type: 'boolean',
|
|
28
|
+
},
|
|
29
|
+
},
|
|
30
|
+
additionalProperties: false,
|
|
31
|
+
};
|
|
32
|
+
|
|
12
33
|
export default (new Packager({
|
|
13
|
-
async loadConfig({config, options}) {
|
|
34
|
+
async loadConfig({config, options}): Promise<JSPackagerConfig> {
|
|
14
35
|
// Generate a name for the global parcelRequire function that is unique to this project.
|
|
15
36
|
// This allows multiple parcel builds to coexist on the same page.
|
|
16
37
|
let pkg = await config.getConfigFrom(
|
|
17
38
|
path.join(options.projectRoot, 'index'),
|
|
18
39
|
['package.json'],
|
|
19
40
|
);
|
|
41
|
+
|
|
42
|
+
let packageKey = '@parcel/packager-js';
|
|
43
|
+
|
|
44
|
+
if (pkg?.contents[packageKey]) {
|
|
45
|
+
validateSchema.diagnostic(
|
|
46
|
+
CONFIG_SCHEMA,
|
|
47
|
+
{
|
|
48
|
+
data: pkg?.contents[packageKey],
|
|
49
|
+
source: await options.inputFS.readFile(pkg.filePath, 'utf8'),
|
|
50
|
+
filePath: pkg.filePath,
|
|
51
|
+
prependKey: `/${encodeJSONKeyComponent(packageKey)}`,
|
|
52
|
+
},
|
|
53
|
+
packageKey,
|
|
54
|
+
`Invalid config for ${packageKey}`,
|
|
55
|
+
);
|
|
56
|
+
}
|
|
57
|
+
|
|
20
58
|
let name = pkg?.contents?.name ?? '';
|
|
21
59
|
return {
|
|
22
60
|
parcelRequireName: 'parcelRequire' + hashString(name).slice(-4),
|
|
61
|
+
unstable_asyncBundleRuntime: Boolean(
|
|
62
|
+
pkg?.contents[packageKey]?.unstable_asyncBundleRuntime,
|
|
63
|
+
),
|
|
23
64
|
};
|
|
24
65
|
},
|
|
25
66
|
async package({
|
|
@@ -51,6 +92,7 @@ export default (new Packager({
|
|
|
51
92
|
bundleGraph,
|
|
52
93
|
bundle,
|
|
53
94
|
nullthrows(config).parcelRequireName,
|
|
95
|
+
nullthrows(config).unstable_asyncBundleRuntime,
|
|
54
96
|
)
|
|
55
97
|
: new DevPackager(
|
|
56
98
|
options,
|