@atlaspack/runtime-js 2.15.0 → 2.15.2
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 +22 -0
- package/lib/JSRuntime.js +21 -5
- package/lib/helpers/browser/sync-js-loader.js +33 -0
- package/lib/helpers/conditional-loader-dev.js +10 -3
- package/lib/helpers/conditional-loader.js +15 -2
- package/package.json +4 -4
- package/src/JSRuntime.js +42 -6
- package/src/helpers/browser/sync-js-loader.js +39 -0
- package/src/helpers/conditional-loader-dev.js +11 -3
- package/src/helpers/conditional-loader.js +18 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,27 @@
|
|
|
1
1
|
# @atlaspack/runtime-js
|
|
2
2
|
|
|
3
|
+
## 2.15.2
|
|
4
|
+
|
|
5
|
+
### Patch Changes
|
|
6
|
+
|
|
7
|
+
- [#702](https://github.com/atlassian-labs/atlaspack/pull/702) [`daaa768`](https://github.com/atlassian-labs/atlaspack/commit/daaa7688786772d7e3713b71c5bba6b89ec704aa) Thanks [@alshdavid](https://github.com/alshdavid)! - Fixes to Flow types
|
|
8
|
+
|
|
9
|
+
- Updated dependencies [[`daaa768`](https://github.com/atlassian-labs/atlaspack/commit/daaa7688786772d7e3713b71c5bba6b89ec704aa), [`1c7865a`](https://github.com/atlassian-labs/atlaspack/commit/1c7865a64451116d94015e248302435839d347c0), [`a0b959f`](https://github.com/atlassian-labs/atlaspack/commit/a0b959fbf61fc3f820ff03c7e8988945fe40a91a)]:
|
|
10
|
+
- @atlaspack/plugin@2.14.20
|
|
11
|
+
- @atlaspack/feature-flags@2.19.2
|
|
12
|
+
- @atlaspack/utils@2.17.2
|
|
13
|
+
|
|
14
|
+
## 2.15.1
|
|
15
|
+
|
|
16
|
+
### Patch Changes
|
|
17
|
+
|
|
18
|
+
- [#692](https://github.com/atlassian-labs/atlaspack/pull/692) [`13aef17`](https://github.com/atlassian-labs/atlaspack/commit/13aef177eea289a6e40d2113b5ec1ac9be18a33d) Thanks [@JakeLane](https://github.com/JakeLane)! - Add fallback behaviour when conditional bundle is missing
|
|
19
|
+
|
|
20
|
+
- Updated dependencies [[`13aef17`](https://github.com/atlassian-labs/atlaspack/commit/13aef177eea289a6e40d2113b5ec1ac9be18a33d)]:
|
|
21
|
+
- @atlaspack/feature-flags@2.19.1
|
|
22
|
+
- @atlaspack/utils@2.17.1
|
|
23
|
+
- @atlaspack/plugin@2.14.19
|
|
24
|
+
|
|
3
25
|
## 2.15.0
|
|
4
26
|
|
|
5
27
|
### Minor Changes
|
package/lib/JSRuntime.js
CHANGED
|
@@ -208,9 +208,19 @@ var _default = exports.default = new (_plugin().Runtime)({
|
|
|
208
208
|
const conditions = bundleGraph.getConditionsForDependencies(conditionalDependencies, bundle);
|
|
209
209
|
for (const cond of conditions) {
|
|
210
210
|
const requireName = (0, _featureFlags().getFeatureFlag)('hmrImprovements') || bundle.env.shouldScopeHoist ? 'parcelRequire' : '__parcel__require__';
|
|
211
|
-
const
|
|
211
|
+
const fallbackUrls = cond => {
|
|
212
|
+
return `[${[...cond.ifTrueBundles, ...cond.ifFalseBundles].map(target => {
|
|
213
|
+
let relativePathExpr = getRelativePathExpr(bundle, target, options);
|
|
214
|
+
return getAbsoluteUrlExpr(relativePathExpr, bundle, config.domainSharding);
|
|
215
|
+
}).join(',')}]`;
|
|
216
|
+
};
|
|
217
|
+
const shouldUseFallback = options.mode === 'development' ? (0, _featureFlags().getFeatureFlag)('condbDevFallbackDev') : (0, _featureFlags().getFeatureFlag)('condbDevFallbackProd');
|
|
218
|
+
const loaderPath = `./helpers/conditional-loader${options.mode === 'development' ? '-dev' : ''}`;
|
|
219
|
+
const ifTrue = `function (){return ${requireName}('${cond.ifTrueAssetId}')}`;
|
|
220
|
+
const ifFalse = `function (){return ${requireName}('${cond.ifFalseAssetId}')}`;
|
|
221
|
+
const assetCode = `module.exports = require('${loaderPath}')('${cond.key}', ${ifTrue}, ${ifFalse}${shouldUseFallback ? `, {loader: require('./helpers/browser/sync-js-loader'), urls: ${fallbackUrls(cond)}}` : ''})`;
|
|
212
222
|
assets.push({
|
|
213
|
-
filePath: _path().default.join(__dirname, `/conditions
|
|
223
|
+
filePath: _path().default.join(__dirname, `/conditions-${cond.publicId}.js`),
|
|
214
224
|
code: assetCode,
|
|
215
225
|
// This dependency is important, as it's the last symbol handled in scope hoisting.
|
|
216
226
|
// That means that scope hoisting will use the module id for this asset to replace the symbol
|
|
@@ -270,7 +280,9 @@ var _default = exports.default = new (_plugin().Runtime)({
|
|
|
270
280
|
}
|
|
271
281
|
|
|
272
282
|
// URL dependency or not, fall back to including a runtime that exports the url
|
|
273
|
-
assets.push(getURLRuntime(dependency, bundle, mainBundle, options,
|
|
283
|
+
assets.push(getURLRuntime(dependency, bundle, mainBundle, options,
|
|
284
|
+
// $FlowFixMe
|
|
285
|
+
config.domainSharding));
|
|
274
286
|
}
|
|
275
287
|
|
|
276
288
|
// In development, bundles can be created lazily. This means that the parent bundle may not
|
|
@@ -288,7 +300,9 @@ var _default = exports.default = new (_plugin().Runtime)({
|
|
|
288
300
|
continue;
|
|
289
301
|
}
|
|
290
302
|
let relativePathExpr = getRelativePathExpr(bundle, referencedBundle, options);
|
|
291
|
-
let loaderCode = `require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, bundle,
|
|
303
|
+
let loaderCode = `require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, bundle,
|
|
304
|
+
// $FlowFixMe
|
|
305
|
+
config.domainSharding)})`;
|
|
292
306
|
assets.push({
|
|
293
307
|
filePath: __filename,
|
|
294
308
|
code: loaderCode,
|
|
@@ -307,7 +321,9 @@ var _default = exports.default = new (_plugin().Runtime)({
|
|
|
307
321
|
env: {
|
|
308
322
|
sourceType: 'module'
|
|
309
323
|
},
|
|
310
|
-
priority: getManifestBundlePriority(bundleGraph, bundle,
|
|
324
|
+
priority: getManifestBundlePriority(bundleGraph, bundle,
|
|
325
|
+
// $FlowFixMe
|
|
326
|
+
config.splitManifestThreshold)
|
|
311
327
|
});
|
|
312
328
|
}
|
|
313
329
|
return assets;
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
|
|
3
|
+
const cacheLoader = require('../cacheLoader');
|
|
4
|
+
module.exports = function loadJSBundle(bundle) {
|
|
5
|
+
// Don't insert the same script twice (e.g. if it was already in the HTML)
|
|
6
|
+
let existingScripts = document.getElementsByTagName('script');
|
|
7
|
+
let isCurrentBundle = function (script) {
|
|
8
|
+
return script.src === bundle;
|
|
9
|
+
};
|
|
10
|
+
if ([].concat(existingScripts).some(isCurrentBundle)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Request using XHR because it's synchronous and we can't use promises here
|
|
15
|
+
// This has extremely poor performance because we're idle during this fetch, so we only use this so that the app won't crash
|
|
16
|
+
const xhr = new XMLHttpRequest();
|
|
17
|
+
xhr.open('GET', bundle, false);
|
|
18
|
+
try {
|
|
19
|
+
xhr.send();
|
|
20
|
+
if (xhr.status === 200) {
|
|
21
|
+
const script = document.createElement('script');
|
|
22
|
+
script.type = 'text/javascript';
|
|
23
|
+
script.text = xhr.responseText;
|
|
24
|
+
|
|
25
|
+
// Execute the script synchronously
|
|
26
|
+
document.head.appendChild(script);
|
|
27
|
+
} else {
|
|
28
|
+
throw new TypeError(`Failed to fetch dynamically imported module: ${bundle}. Status: ${xhr.status}`);
|
|
29
|
+
}
|
|
30
|
+
} catch (e) {
|
|
31
|
+
throw new TypeError(`Failed to fetch dynamically imported module: ${bundle}. Error: ${e.message}`);
|
|
32
|
+
}
|
|
33
|
+
};
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
3
|
+
module.exports = function loadCond(cond, ifTrue, ifFalse, fallback) {
|
|
4
4
|
if (typeof globalThis.__MCOND !== 'function') {
|
|
5
5
|
throw new TypeError('"globalThis.__MCOND" was not set to an object. Ensure the function is set to return the key condition for conditional bundles to load with.');
|
|
6
6
|
}
|
|
@@ -10,7 +10,14 @@ module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
|
10
10
|
try {
|
|
11
11
|
return globalThis.__MCOND(cond) ? ifTrue() : ifFalse();
|
|
12
12
|
} catch (err) {
|
|
13
|
-
console.error('Conditional dependency was
|
|
14
|
-
|
|
13
|
+
console.error('Conditional dependency was not registered when executing. Ensure the server sends the correct scripts to the client. Falling back to synchronous bundle loading.');
|
|
14
|
+
if (fallback) {
|
|
15
|
+
for (const url of fallback.urls) {
|
|
16
|
+
fallback.loader(url);
|
|
17
|
+
}
|
|
18
|
+
return globalThis.__MCOND(cond) ? ifTrue() : ifFalse();
|
|
19
|
+
} else {
|
|
20
|
+
throw new Error('No fallback urls specified, cannot fallback safely');
|
|
21
|
+
}
|
|
15
22
|
}
|
|
16
23
|
};
|
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
4
|
-
|
|
3
|
+
module.exports = function loadCond(cond, ifTrue, ifFalse, fallback) {
|
|
4
|
+
let result = globalThis.__MCOND(cond);
|
|
5
|
+
try {
|
|
6
|
+
return result ? ifTrue() : ifFalse();
|
|
7
|
+
} catch (err) {
|
|
8
|
+
if (fallback) {
|
|
9
|
+
console.error('Conditional dependency was not registered when executing. Falling back to synchronous bundle loading.');
|
|
10
|
+
for (const url of fallback.urls) {
|
|
11
|
+
fallback.loader(url);
|
|
12
|
+
}
|
|
13
|
+
return result ? ifTrue() : ifFalse();
|
|
14
|
+
} else {
|
|
15
|
+
throw err;
|
|
16
|
+
}
|
|
17
|
+
}
|
|
5
18
|
};
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@atlaspack/runtime-js",
|
|
3
|
-
"version": "2.15.
|
|
3
|
+
"version": "2.15.2",
|
|
4
4
|
"license": "(MIT OR Apache-2.0)",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
@@ -17,9 +17,9 @@
|
|
|
17
17
|
"dependencies": {
|
|
18
18
|
"@atlaspack/diagnostic": "2.14.1",
|
|
19
19
|
"@atlaspack/domain-sharding": "2.14.1",
|
|
20
|
-
"@atlaspack/feature-flags": "2.19.
|
|
21
|
-
"@atlaspack/plugin": "2.14.
|
|
22
|
-
"@atlaspack/utils": "2.17.
|
|
20
|
+
"@atlaspack/feature-flags": "2.19.2",
|
|
21
|
+
"@atlaspack/plugin": "2.14.20",
|
|
22
|
+
"@atlaspack/utils": "2.17.2",
|
|
23
23
|
"nullthrows": "^1.1.1"
|
|
24
24
|
},
|
|
25
25
|
"type": "commonjs"
|
package/src/JSRuntime.js
CHANGED
|
@@ -221,14 +221,47 @@ export default (new Runtime({
|
|
|
221
221
|
? 'parcelRequire'
|
|
222
222
|
: '__parcel__require__';
|
|
223
223
|
|
|
224
|
-
const
|
|
224
|
+
const fallbackUrls = (cond) => {
|
|
225
|
+
return `[${[...cond.ifTrueBundles, ...cond.ifFalseBundles]
|
|
226
|
+
.map((target) => {
|
|
227
|
+
let relativePathExpr = getRelativePathExpr(
|
|
228
|
+
bundle,
|
|
229
|
+
target,
|
|
230
|
+
options,
|
|
231
|
+
);
|
|
232
|
+
return getAbsoluteUrlExpr(
|
|
233
|
+
relativePathExpr,
|
|
234
|
+
bundle,
|
|
235
|
+
config.domainSharding,
|
|
236
|
+
);
|
|
237
|
+
})
|
|
238
|
+
.join(',')}]`;
|
|
239
|
+
};
|
|
240
|
+
|
|
241
|
+
const shouldUseFallback =
|
|
242
|
+
options.mode === 'development'
|
|
243
|
+
? getFeatureFlag('condbDevFallbackDev')
|
|
244
|
+
: getFeatureFlag('condbDevFallbackProd');
|
|
245
|
+
|
|
246
|
+
const loaderPath = `./helpers/conditional-loader${
|
|
225
247
|
options.mode === 'development' ? '-dev' : ''
|
|
226
|
-
}
|
|
227
|
-
|
|
228
|
-
|
|
248
|
+
}`;
|
|
249
|
+
|
|
250
|
+
const ifTrue = `function (){return ${requireName}('${cond.ifTrueAssetId}')}`;
|
|
251
|
+
const ifFalse = `function (){return ${requireName}('${cond.ifFalseAssetId}')}`;
|
|
252
|
+
|
|
253
|
+
const assetCode = `module.exports = require('${loaderPath}')('${
|
|
254
|
+
cond.key
|
|
255
|
+
}', ${ifTrue}, ${ifFalse}${
|
|
256
|
+
shouldUseFallback
|
|
257
|
+
? `, {loader: require('./helpers/browser/sync-js-loader'), urls: ${fallbackUrls(
|
|
258
|
+
cond,
|
|
259
|
+
)}}`
|
|
260
|
+
: ''
|
|
261
|
+
})`;
|
|
229
262
|
|
|
230
263
|
assets.push({
|
|
231
|
-
filePath: path.join(__dirname, `/conditions
|
|
264
|
+
filePath: path.join(__dirname, `/conditions-${cond.publicId}.js`),
|
|
232
265
|
code: assetCode,
|
|
233
266
|
// This dependency is important, as it's the last symbol handled in scope hoisting.
|
|
234
267
|
// That means that scope hoisting will use the module id for this asset to replace the symbol
|
|
@@ -296,6 +329,7 @@ export default (new Runtime({
|
|
|
296
329
|
bundle,
|
|
297
330
|
mainBundle,
|
|
298
331
|
options,
|
|
332
|
+
// $FlowFixMe
|
|
299
333
|
config.domainSharding,
|
|
300
334
|
),
|
|
301
335
|
);
|
|
@@ -327,6 +361,7 @@ export default (new Runtime({
|
|
|
327
361
|
)})(${getAbsoluteUrlExpr(
|
|
328
362
|
relativePathExpr,
|
|
329
363
|
bundle,
|
|
364
|
+
// $FlowFixMe
|
|
330
365
|
config.domainSharding,
|
|
331
366
|
)})`;
|
|
332
367
|
assets.push({
|
|
@@ -353,6 +388,7 @@ export default (new Runtime({
|
|
|
353
388
|
priority: getManifestBundlePriority(
|
|
354
389
|
bundleGraph,
|
|
355
390
|
bundle,
|
|
391
|
+
// $FlowFixMe
|
|
356
392
|
config.splitManifestThreshold,
|
|
357
393
|
),
|
|
358
394
|
});
|
|
@@ -360,7 +396,7 @@ export default (new Runtime({
|
|
|
360
396
|
|
|
361
397
|
return assets;
|
|
362
398
|
},
|
|
363
|
-
}): Runtime);
|
|
399
|
+
}): Runtime<JSRuntimeConfig>);
|
|
364
400
|
|
|
365
401
|
function getDependencies(bundle: NamedBundle): {|
|
|
366
402
|
asyncDependencies: Array<Dependency>,
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
const cacheLoader = require('../cacheLoader');
|
|
2
|
+
|
|
3
|
+
module.exports = function loadJSBundle(bundle) {
|
|
4
|
+
// Don't insert the same script twice (e.g. if it was already in the HTML)
|
|
5
|
+
let existingScripts = document.getElementsByTagName('script');
|
|
6
|
+
let isCurrentBundle = function (script) {
|
|
7
|
+
return script.src === bundle;
|
|
8
|
+
};
|
|
9
|
+
|
|
10
|
+
if ([].concat(existingScripts).some(isCurrentBundle)) {
|
|
11
|
+
return;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
// Request using XHR because it's synchronous and we can't use promises here
|
|
15
|
+
// This has extremely poor performance because we're idle during this fetch, so we only use this so that the app won't crash
|
|
16
|
+
const xhr = new XMLHttpRequest();
|
|
17
|
+
xhr.open('GET', bundle, false);
|
|
18
|
+
|
|
19
|
+
try {
|
|
20
|
+
xhr.send();
|
|
21
|
+
|
|
22
|
+
if (xhr.status === 200) {
|
|
23
|
+
const script = document.createElement('script');
|
|
24
|
+
script.type = 'text/javascript';
|
|
25
|
+
script.text = xhr.responseText;
|
|
26
|
+
|
|
27
|
+
// Execute the script synchronously
|
|
28
|
+
document.head.appendChild(script);
|
|
29
|
+
} else {
|
|
30
|
+
throw new TypeError(
|
|
31
|
+
`Failed to fetch dynamically imported module: ${bundle}. Status: ${xhr.status}`,
|
|
32
|
+
);
|
|
33
|
+
}
|
|
34
|
+
} catch (e) {
|
|
35
|
+
throw new TypeError(
|
|
36
|
+
`Failed to fetch dynamically imported module: ${bundle}. Error: ${e.message}`,
|
|
37
|
+
);
|
|
38
|
+
}
|
|
39
|
+
};
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
1
|
+
module.exports = function loadCond(cond, ifTrue, ifFalse, fallback) {
|
|
2
2
|
if (typeof globalThis.__MCOND !== 'function') {
|
|
3
3
|
throw new TypeError(
|
|
4
4
|
'"globalThis.__MCOND" was not set to an object. Ensure the function is set to return the key condition for conditional bundles to load with.',
|
|
@@ -15,9 +15,17 @@ module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
|
15
15
|
return globalThis.__MCOND(cond) ? ifTrue() : ifFalse();
|
|
16
16
|
} catch (err) {
|
|
17
17
|
console.error(
|
|
18
|
-
'Conditional dependency was
|
|
18
|
+
'Conditional dependency was not registered when executing. Ensure the server sends the correct scripts to the client. Falling back to synchronous bundle loading.',
|
|
19
19
|
);
|
|
20
20
|
|
|
21
|
-
|
|
21
|
+
if (fallback) {
|
|
22
|
+
for (const url of fallback.urls) {
|
|
23
|
+
fallback.loader(url);
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
return globalThis.__MCOND(cond) ? ifTrue() : ifFalse();
|
|
27
|
+
} else {
|
|
28
|
+
throw new Error('No fallback urls specified, cannot fallback safely');
|
|
29
|
+
}
|
|
22
30
|
}
|
|
23
31
|
};
|
|
@@ -1,3 +1,19 @@
|
|
|
1
|
-
module.exports = function loadCond(cond, ifTrue, ifFalse) {
|
|
2
|
-
|
|
1
|
+
module.exports = function loadCond(cond, ifTrue, ifFalse, fallback) {
|
|
2
|
+
let result = globalThis.__MCOND(cond);
|
|
3
|
+
try {
|
|
4
|
+
return result ? ifTrue() : ifFalse();
|
|
5
|
+
} catch (err) {
|
|
6
|
+
if (fallback) {
|
|
7
|
+
console.error(
|
|
8
|
+
'Conditional dependency was not registered when executing. Falling back to synchronous bundle loading.',
|
|
9
|
+
);
|
|
10
|
+
for (const url of fallback.urls) {
|
|
11
|
+
fallback.loader(url);
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
return result ? ifTrue() : ifFalse();
|
|
15
|
+
} else {
|
|
16
|
+
throw err;
|
|
17
|
+
}
|
|
18
|
+
}
|
|
3
19
|
};
|