@atlaspack/runtime-js 2.12.1-canary.3581 → 2.12.1-canary.3583

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/JSRuntime.js CHANGED
@@ -93,6 +93,19 @@ const CONFIG_SCHEMA = {
93
93
  properties: {
94
94
  splitManifestThreshold: {
95
95
  type: 'number'
96
+ },
97
+ domainSharding: {
98
+ type: 'object',
99
+ properties: {
100
+ maxShards: {
101
+ type: 'number'
102
+ },
103
+ cookieName: {
104
+ type: 'string'
105
+ }
106
+ },
107
+ additionalProperties: false,
108
+ required: ['maxShards', 'cookieName']
96
109
  }
97
110
  },
98
111
  additionalProperties: false
@@ -181,7 +194,8 @@ var _default = exports.default = new (_plugin().Runtime)({
181
194
  dependency,
182
195
  bundleGraph,
183
196
  bundleGroup: resolved.value,
184
- options
197
+ options,
198
+ shardingConfig: config.domainSharding
185
199
  });
186
200
  if (loaderRuntime != null) {
187
201
  assets.push(loaderRuntime);
@@ -257,7 +271,7 @@ var _default = exports.default = new (_plugin().Runtime)({
257
271
  }
258
272
 
259
273
  // URL dependency or not, fall back to including a runtime that exports the url
260
- assets.push(getURLRuntime(dependency, bundle, mainBundle, options));
274
+ assets.push(getURLRuntime(dependency, bundle, mainBundle, options, config.domainSharding));
261
275
  }
262
276
 
263
277
  // In development, bundles can be created lazily. This means that the parent bundle may not
@@ -275,7 +289,7 @@ var _default = exports.default = new (_plugin().Runtime)({
275
289
  continue;
276
290
  }
277
291
  let relativePathExpr = getRelativePathExpr(bundle, referencedBundle, options);
278
- let loaderCode = `require(${JSON.stringify(loader)})( ${getAbsoluteUrlExpr(relativePathExpr, bundle)})`;
292
+ let loaderCode = `require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, bundle, referencedBundle, config.domainSharding)})`;
279
293
  assets.push({
280
294
  filePath: __filename,
281
295
  code: loaderCode,
@@ -338,7 +352,8 @@ function getLoaderRuntime({
338
352
  dependency,
339
353
  bundleGroup,
340
354
  bundleGraph,
341
- options
355
+ options,
356
+ shardingConfig
342
357
  }) {
343
358
  let loaders = getLoaders(bundle.env);
344
359
  if (loaders == null) {
@@ -372,7 +387,7 @@ function getLoaderRuntime({
372
387
  let needsDynamicImportPolyfill = !bundle.env.isLibrary && !bundle.env.supports('dynamic-import', true);
373
388
  let needsEsmLoadPrelude = false;
374
389
  let loaderModules = [];
375
- function getLoaderForBundle(bundle, to) {
390
+ function getLoaderForBundle(bundle, to, shardingConfig) {
376
391
  let loader = loaders[to.type];
377
392
  if (!loader) {
378
393
  return;
@@ -392,7 +407,7 @@ function getLoaderRuntime({
392
407
  } else if (to.type === 'js' && to.env.outputFormat === 'commonjs') {
393
408
  return `Promise.resolve(__parcel__require__("./" + ${relativePathExpr}))`;
394
409
  }
395
- let absoluteUrlExpr = shouldUseRuntimeManifest(bundle, options) ? `require('./helpers/bundle-manifest').resolve(${JSON.stringify(to.publicId)})` : getAbsoluteUrlExpr(relativePathExpr, bundle);
410
+ let absoluteUrlExpr = shouldUseRuntimeManifest(bundle, options) ? `require('./helpers/bundle-manifest').resolve(${JSON.stringify(to.publicId)})` : getAbsoluteUrlExpr(relativePathExpr, bundle, to, shardingConfig);
396
411
  let code = `require(${JSON.stringify(loader)})(${absoluteUrlExpr})`;
397
412
 
398
413
  // In development, clear the require cache when an error occurs so the
@@ -415,7 +430,7 @@ function getLoaderRuntime({
415
430
  }
416
431
  }
417
432
  for (let to of externalBundles) {
418
- let loaderModule = getLoaderForBundle(bundle, to);
433
+ let loaderModule = getLoaderForBundle(bundle, to, shardingConfig);
419
434
  if (loaderModule !== undefined) loaderModules.push(loaderModule);
420
435
  }
421
436
 
@@ -513,7 +528,7 @@ function getHintLoaders(bundleGraph, from, bundleGroups, loader, options) {
513
528
  for (let bundleToPreload of bundlesToPreload) {
514
529
  let relativePathExpr = getRelativePathExpr(from, bundleToPreload, options);
515
530
  let priority = TYPE_TO_RESOURCE_PRIORITY[bundleToPreload.type];
516
- hintLoaders.push(`require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, from)}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(bundleToPreload.target.env.outputFormat === 'esmodule')})`);
531
+ hintLoaders.push(`require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(relativePathExpr, from, bundleToPreload)}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(bundleToPreload.target.env.outputFormat === 'esmodule')})`);
517
532
  }
518
533
  }
519
534
  return hintLoaders;
@@ -523,7 +538,7 @@ function isNewContext(bundle, bundleGraph) {
523
538
  let isInEntryBundleGroup = bundleGraph.getBundleGroupsContainingBundle(bundle).some(g => bundleGraph.isEntryBundleGroup(g));
524
539
  return isInEntryBundleGroup || parents.length === 0 || parents.some(parent => parent.env.context !== bundle.env.context || parent.type !== 'js');
525
540
  }
526
- function getURLRuntime(dependency, from, to, options) {
541
+ function getURLRuntime(dependency, from, to, options, shardingConfig) {
527
542
  let relativePathExpr = getRelativePathExpr(from, to, options);
528
543
  let code;
529
544
  if (dependency.meta.webworker === true && !from.env.isLibrary) {
@@ -537,7 +552,7 @@ function getURLRuntime(dependency, from, to, options) {
537
552
  code += `module.exports = workerURL(url, bundleURL.getOrigin(url), ${String(from.env.outputFormat === 'esmodule')});`;
538
553
  }
539
554
  } else {
540
- code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from)};`;
555
+ code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from, to, shardingConfig)};`;
541
556
  }
542
557
  return {
543
558
  filePath: __filename,
@@ -585,13 +600,16 @@ function getRelativePathExpr(from, to, options) {
585
600
  }
586
601
  return res;
587
602
  }
588
- function getAbsoluteUrlExpr(relativePathExpr, bundle) {
589
- if (bundle.env.outputFormat === 'esmodule' && bundle.env.supports('import-meta-url') || bundle.env.outputFormat === 'commonjs') {
603
+ function getAbsoluteUrlExpr(relativePathExpr, fromBundle, toBundle, shardingConfig) {
604
+ if (fromBundle.env.outputFormat === 'esmodule' && fromBundle.env.supports('import-meta-url') || fromBundle.env.outputFormat === 'commonjs') {
590
605
  // This will be compiled to new URL(url, import.meta.url) or new URL(url, 'file:' + __filename).
591
606
  return `new __parcel__URL__(${relativePathExpr}).toString()`;
592
- } else {
593
- return `require('./helpers/bundle-url').getBundleURL('${bundle.publicId}') + ${relativePathExpr}`;
594
607
  }
608
+ if (shardingConfig) {
609
+ const bundleUrlArgs = [`'${toBundle.name}'`, `'${shardingConfig.cookieName}'`, 'document.cookie', shardingConfig.maxShards].join(', ');
610
+ return `require('./helpers/bundle-url-shards').getShardedBundleURL(${bundleUrlArgs}) + ${relativePathExpr}`;
611
+ }
612
+ return `require('./helpers/bundle-url').getBundleURL('${fromBundle.publicId}') + ${relativePathExpr}`;
595
613
  }
596
614
  function shouldUseRuntimeManifest(bundle, options) {
597
615
  let env = bundle.env;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@atlaspack/runtime-js",
3
- "version": "2.12.1-canary.3581+f0f92f212",
3
+ "version": "2.12.1-canary.3583+3054dda39",
4
4
  "license": "(MIT OR Apache-2.0)",
5
5
  "publishConfig": {
6
6
  "access": "public"
@@ -12,15 +12,15 @@
12
12
  "main": "lib/JSRuntime.js",
13
13
  "source": "src/JSRuntime.js",
14
14
  "engines": {
15
- "atlaspack": "2.12.1-canary.3581+f0f92f212",
15
+ "atlaspack": "2.12.1-canary.3583+3054dda39",
16
16
  "node": ">= 16.0.0"
17
17
  },
18
18
  "dependencies": {
19
- "@atlaspack/diagnostic": "2.12.1-canary.3581+f0f92f212",
20
- "@atlaspack/feature-flags": "2.12.1-canary.3581+f0f92f212",
21
- "@atlaspack/plugin": "2.12.1-canary.3581+f0f92f212",
22
- "@atlaspack/utils": "2.12.1-canary.3581+f0f92f212",
19
+ "@atlaspack/diagnostic": "2.12.1-canary.3583+3054dda39",
20
+ "@atlaspack/feature-flags": "2.12.1-canary.3583+3054dda39",
21
+ "@atlaspack/plugin": "2.12.1-canary.3583+3054dda39",
22
+ "@atlaspack/utils": "2.12.1-canary.3583+3054dda39",
23
23
  "nullthrows": "^1.1.1"
24
24
  },
25
- "gitHead": "f0f92f21248b1577c6ad3673e2eca9a9bb39940c"
25
+ "gitHead": "3054dda39b54666caba268f09cadf801b43ce3a5"
26
26
  }
package/src/JSRuntime.js CHANGED
@@ -74,6 +74,10 @@ let bundleDependencies = new WeakMap<
74
74
 
75
75
  type JSRuntimeConfig = {|
76
76
  splitManifestThreshold: number,
77
+ domainSharding?: {|
78
+ maxShards: number,
79
+ cookieName: string,
80
+ |},
77
81
  |};
78
82
 
79
83
  let defaultConfig: JSRuntimeConfig = {
@@ -86,6 +90,19 @@ const CONFIG_SCHEMA: SchemaEntity = {
86
90
  splitManifestThreshold: {
87
91
  type: 'number',
88
92
  },
93
+ domainSharding: {
94
+ type: 'object',
95
+ properties: {
96
+ maxShards: {
97
+ type: 'number',
98
+ },
99
+ cookieName: {
100
+ type: 'string',
101
+ },
102
+ },
103
+ additionalProperties: false,
104
+ required: ['maxShards', 'cookieName'],
105
+ },
89
106
  },
90
107
  additionalProperties: false,
91
108
  };
@@ -181,6 +198,7 @@ export default (new Runtime({
181
198
  bundleGraph,
182
199
  bundleGroup: resolved.value,
183
200
  options,
201
+ shardingConfig: config.domainSharding,
184
202
  });
185
203
 
186
204
  if (loaderRuntime != null) {
@@ -271,7 +289,15 @@ export default (new Runtime({
271
289
  }
272
290
 
273
291
  // URL dependency or not, fall back to including a runtime that exports the url
274
- assets.push(getURLRuntime(dependency, bundle, mainBundle, options));
292
+ assets.push(
293
+ getURLRuntime(
294
+ dependency,
295
+ bundle,
296
+ mainBundle,
297
+ options,
298
+ config.domainSharding,
299
+ ),
300
+ );
275
301
  }
276
302
 
277
303
  // In development, bundles can be created lazily. This means that the parent bundle may not
@@ -297,7 +323,12 @@ export default (new Runtime({
297
323
  );
298
324
  let loaderCode = `require(${JSON.stringify(
299
325
  loader,
300
- )})( ${getAbsoluteUrlExpr(relativePathExpr, bundle)})`;
326
+ )})(${getAbsoluteUrlExpr(
327
+ relativePathExpr,
328
+ bundle,
329
+ referencedBundle,
330
+ config.domainSharding,
331
+ )})`;
301
332
  assets.push({
302
333
  filePath: __filename,
303
334
  code: loaderCode,
@@ -376,12 +407,14 @@ function getLoaderRuntime({
376
407
  bundleGroup,
377
408
  bundleGraph,
378
409
  options,
410
+ shardingConfig,
379
411
  }: {|
380
412
  bundle: NamedBundle,
381
413
  dependency: Dependency,
382
414
  bundleGroup: BundleGroup,
383
415
  bundleGraph: BundleGraph<NamedBundle>,
384
416
  options: PluginOptions,
417
+ shardingConfig: JSRuntimeConfig['domainSharding'],
385
418
  |}): ?RuntimeAsset {
386
419
  let loaders = getLoaders(bundle.env);
387
420
  if (loaders == null) {
@@ -423,6 +456,7 @@ function getLoaderRuntime({
423
456
  function getLoaderForBundle(
424
457
  bundle: NamedBundle,
425
458
  to: NamedBundle,
459
+ shardingConfig: JSRuntimeConfig['domainSharding'],
426
460
  ): string | void {
427
461
  let loader = loaders[to.type];
428
462
  if (!loader) {
@@ -459,7 +493,7 @@ function getLoaderRuntime({
459
493
  ? `require('./helpers/bundle-manifest').resolve(${JSON.stringify(
460
494
  to.publicId,
461
495
  )})`
462
- : getAbsoluteUrlExpr(relativePathExpr, bundle);
496
+ : getAbsoluteUrlExpr(relativePathExpr, bundle, to, shardingConfig);
463
497
  let code = `require(${JSON.stringify(loader)})(${absoluteUrlExpr})`;
464
498
 
465
499
  // In development, clear the require cache when an error occurs so the
@@ -508,7 +542,7 @@ function getLoaderRuntime({
508
542
  }
509
543
 
510
544
  for (let to of externalBundles) {
511
- let loaderModule = getLoaderForBundle(bundle, to);
545
+ let loaderModule = getLoaderForBundle(bundle, to, shardingConfig);
512
546
  if (loaderModule !== undefined) loaderModules.push(loaderModule);
513
547
  }
514
548
 
@@ -650,6 +684,7 @@ function getHintLoaders(
650
684
  `require(${JSON.stringify(loader)})(${getAbsoluteUrlExpr(
651
685
  relativePathExpr,
652
686
  from,
687
+ bundleToPreload,
653
688
  )}, ${priority ? JSON.stringify(priority) : 'null'}, ${JSON.stringify(
654
689
  bundleToPreload.target.env.outputFormat === 'esmodule',
655
690
  )})`,
@@ -683,6 +718,7 @@ function getURLRuntime(
683
718
  from: NamedBundle,
684
719
  to: NamedBundle,
685
720
  options: PluginOptions,
721
+ shardingConfig: JSRuntimeConfig['domainSharding'],
686
722
  ): RuntimeAsset {
687
723
  let relativePathExpr = getRelativePathExpr(from, to, options);
688
724
  let code;
@@ -705,7 +741,12 @@ function getURLRuntime(
705
741
  )});`;
706
742
  }
707
743
  } else {
708
- code = `module.exports = ${getAbsoluteUrlExpr(relativePathExpr, from)};`;
744
+ code = `module.exports = ${getAbsoluteUrlExpr(
745
+ relativePathExpr,
746
+ from,
747
+ to,
748
+ shardingConfig,
749
+ )};`;
709
750
  }
710
751
 
711
752
  return {
@@ -775,17 +816,33 @@ function getRelativePathExpr(
775
816
  return res;
776
817
  }
777
818
 
778
- function getAbsoluteUrlExpr(relativePathExpr: string, bundle: NamedBundle) {
819
+ function getAbsoluteUrlExpr(
820
+ relativePathExpr: string,
821
+ fromBundle: NamedBundle,
822
+ toBundle: NamedBundle,
823
+ shardingConfig: JSRuntimeConfig['domainSharding'],
824
+ ) {
779
825
  if (
780
- (bundle.env.outputFormat === 'esmodule' &&
781
- bundle.env.supports('import-meta-url')) ||
782
- bundle.env.outputFormat === 'commonjs'
826
+ (fromBundle.env.outputFormat === 'esmodule' &&
827
+ fromBundle.env.supports('import-meta-url')) ||
828
+ fromBundle.env.outputFormat === 'commonjs'
783
829
  ) {
784
830
  // This will be compiled to new URL(url, import.meta.url) or new URL(url, 'file:' + __filename).
785
831
  return `new __parcel__URL__(${relativePathExpr}).toString()`;
786
- } else {
787
- return `require('./helpers/bundle-url').getBundleURL('${bundle.publicId}') + ${relativePathExpr}`;
788
832
  }
833
+
834
+ if (shardingConfig) {
835
+ const bundleUrlArgs = [
836
+ `'${toBundle.name}'`,
837
+ `'${shardingConfig.cookieName}'`,
838
+ 'document.cookie',
839
+ shardingConfig.maxShards,
840
+ ].join(', ');
841
+
842
+ return `require('./helpers/bundle-url-shards').getShardedBundleURL(${bundleUrlArgs}) + ${relativePathExpr}`;
843
+ }
844
+
845
+ return `require('./helpers/bundle-url').getBundleURL('${fromBundle.publicId}') + ${relativePathExpr}`;
789
846
  }
790
847
 
791
848
  function shouldUseRuntimeManifest(
@@ -0,0 +1,10 @@
1
+ // Get the URL without the filename (last / segment)
2
+ function getBaseURL(url: string) {
3
+ return url.slice(0, url.lastIndexOf('/')) + '/';
4
+ }
5
+
6
+ const stackTraceUrlRegexp =
7
+ /(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^)\n]+/g;
8
+
9
+ exports.getBaseURL = getBaseURL;
10
+ exports.stackTraceUrlRegexp = stackTraceUrlRegexp;
@@ -0,0 +1,95 @@
1
+ const {getBaseURL, stackTraceUrlRegexp} = require('./bundle-url-common');
2
+
3
+ const bundleURL: Record<string, string> = {};
4
+
5
+ function getShardedBundleURL(
6
+ bundleName: string,
7
+ cookieName: string,
8
+ cookieString: string,
9
+ maxShards: number,
10
+ inputError?: string,
11
+ ): string {
12
+ let value = bundleURL[bundleName];
13
+
14
+ if (value) {
15
+ return value;
16
+ }
17
+
18
+ try {
19
+ throw inputError ?? new Error();
20
+ } catch (err) {
21
+ var matches = ('' + err.stack).match(stackTraceUrlRegexp);
22
+
23
+ if (!matches) {
24
+ return '/';
25
+ }
26
+
27
+ // The first stack frame will be this function.
28
+ // Use the 2nd one, which will be a runtime in the original bundle.
29
+ const stackUrl = matches[1];
30
+ const baseUrl = getBaseURL(stackUrl);
31
+
32
+ // If the cookie doesn't exist then we don't need to shard
33
+ if (cookieString.indexOf(cookieName) === -1) {
34
+ return baseUrl;
35
+ }
36
+
37
+ const shardNumber = getDomainShardIndex(bundleName, maxShards);
38
+ const url = new URL(baseUrl);
39
+
40
+ const shardedDomain = getShardedDomain(url.hostname, shardNumber);
41
+ url.hostname = shardedDomain;
42
+
43
+ value = url.toString();
44
+
45
+ bundleURL[bundleName] = value;
46
+ return value;
47
+ }
48
+ }
49
+
50
+ function getDomainShardIndex(str: string, maxShards: number) {
51
+ let shard = str.split('').reduce((a, b) => {
52
+ const n = (a << maxShards) - a + b.charCodeAt(0);
53
+
54
+ // The value returned by << is 64 bit, the & operator coerces to 32,
55
+ // prevents overflow as we iterate.
56
+ return n & n;
57
+ }, 0);
58
+
59
+ shard = shard % maxShards;
60
+
61
+ // Make number positive
62
+ if (shard < 0) {
63
+ shard += maxShards;
64
+ }
65
+
66
+ return shard;
67
+ }
68
+
69
+ function getShardedDomain(domain: string, shard: number) {
70
+ let i = domain.indexOf('.');
71
+
72
+ // Domains like localhost have no . separators
73
+ if (i === -1) {
74
+ return `${removeTrailingShard(domain)}-${shard}`;
75
+ }
76
+
77
+ // If this domain already has a shard number in it, strip it out before adding
78
+ // the new one
79
+ const firstSubdomain = removeTrailingShard(domain.slice(0, i));
80
+
81
+ return `${firstSubdomain}-${shard}${domain.slice(i)}`;
82
+ }
83
+
84
+ const trailingShardRegex = /-\d+$/;
85
+
86
+ function removeTrailingShard(subdomain: string) {
87
+ if (!trailingShardRegex.test(subdomain)) {
88
+ return subdomain;
89
+ }
90
+
91
+ const shardIdx = subdomain.lastIndexOf('-');
92
+ return subdomain.slice(0, shardIdx);
93
+ }
94
+
95
+ exports.getShardedBundleURL = getShardedBundleURL;
@@ -0,0 +1,36 @@
1
+ const {getBaseURL, stackTraceUrlRegexp} = require('./bundle-url-common');
2
+
3
+ const bundleURL = {};
4
+
5
+ function getBundleURLCached(id: string) {
6
+ let value = bundleURL[id];
7
+
8
+ if (!value) {
9
+ value = getBundleURL();
10
+ bundleURL[id] = value;
11
+ }
12
+
13
+ return value;
14
+ }
15
+
16
+ function getBundleURL() {
17
+ try {
18
+ throw new Error();
19
+ } catch (err) {
20
+ var matches = ('' + err.stack).match(stackTraceUrlRegexp);
21
+ if (matches) {
22
+ // The first two stack frames will be this function and getBundleURLCached.
23
+ // Use the 3rd one, which will be a runtime in the original bundle.
24
+ return getBaseURL(matches[2]);
25
+ }
26
+ }
27
+
28
+ return '/';
29
+ }
30
+
31
+ function getOrigin(url: string) {
32
+ return new URL(url).origin;
33
+ }
34
+
35
+ exports.getOrigin = getOrigin;
36
+ exports.getBundleURL = getBundleURLCached;
@@ -0,0 +1,27 @@
1
+ import assert from 'assert';
2
+
3
+ import {getBaseURL} from '../src/helpers/bundle-url-common';
4
+
5
+ describe('getBaseUrl', () => {
6
+ it('should return the URL with the filename removed', () => {
7
+ const testUrl =
8
+ 'https://bundle-shard-3.assets.example.com/assets/testBundle.123abc.js';
9
+
10
+ assert.equal(
11
+ getBaseURL(testUrl),
12
+ 'https://bundle-shard-3.assets.example.com/assets/',
13
+ );
14
+ });
15
+
16
+ it('should handle domains with no .', () => {
17
+ const testUrl = 'http://localhost/assets/testBundle.123abc.js';
18
+
19
+ assert.equal(getBaseURL(testUrl), 'http://localhost/assets/');
20
+ });
21
+
22
+ it('should handle domains with ports', () => {
23
+ const testUrl = 'http://localhost:8081/assets/testBundle.123abc.js';
24
+
25
+ assert.equal(getBaseURL(testUrl), 'http://localhost:8081/assets/');
26
+ });
27
+ });
@@ -0,0 +1,139 @@
1
+ import assert from 'assert';
2
+
3
+ import {fsFixture, overlayFS, bundle} from '@atlaspack/test-utils';
4
+
5
+ import {getShardedBundleURL} from '../src/helpers/bundle-url-shards';
6
+
7
+ const testingCookieName = 'DOMAIN_SHARDING_TEST';
8
+
9
+ const createErrorStack = (url) => {
10
+ // This error stack is copied from a local dev, with a bunch
11
+ // of lines trimmed off the end so it's not unnecessarily long
12
+ return `
13
+ Error
14
+ at Object.getShardedBundleURL (http://localhost:8081/main-bundle.1a2fa8b7.js:15688:29)
15
+ at a7u9v.6d3ceb6ac67fea50 (${url}.1a2fa8b7.js:361466:46)
16
+ at newRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:71:24)
17
+ at localRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:84:35)
18
+ at 7H8wc.react-intl-next (http://localhost:8081/main-bundle.1a2fa8b7.js:279746:28)
19
+ at newRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:71:24)
20
+ at localRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:84:35)
21
+ at 1nL5S../manifest (http://localhost:8081/main-bundle.1a2fa8b7.js:279714:17)
22
+ at newRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:71:24)
23
+ at localRequire (http://localhost:8081/main-bundle.1a2fa8b7.js:84:35)
24
+ `.trim();
25
+ };
26
+
27
+ describe('bundle-url-shards helper', () => {
28
+ describe('getShardedBundleURL', () => {
29
+ it('should shard a URL if the cookie is present', () => {
30
+ const testBundle = 'test-bundle.123abc.js';
31
+
32
+ const err = new Error();
33
+ err.stack = createErrorStack(
34
+ 'https://bundle-shard.assets.example.com/assets/ParentBundle.cba321.js',
35
+ );
36
+
37
+ const result = getShardedBundleURL(
38
+ testBundle,
39
+ testingCookieName,
40
+ `${testingCookieName}=1`,
41
+ 5,
42
+ err,
43
+ );
44
+
45
+ assert.equal(result, 'https://bundle-shard-0.assets.example.com/assets/');
46
+ });
47
+
48
+ it('should re-shard a domain that has already been sharded', () => {
49
+ const testBundle = 'TestBundle.1a2b3c.js';
50
+
51
+ const err = new Error();
52
+ err.stack = createErrorStack(
53
+ 'https://bundle-shard-1.assets.example.com/assets/ParentBundle.cba321.js',
54
+ );
55
+
56
+ const result = getShardedBundleURL(
57
+ testBundle,
58
+ testingCookieName,
59
+ `${testingCookieName}=1`,
60
+ 5,
61
+ err,
62
+ );
63
+
64
+ assert.equal(result, 'https://bundle-shard-4.assets.example.com/assets/');
65
+ });
66
+
67
+ it('should not add a shard if the cookie is not present', () => {
68
+ const testBundle = 'UnshardedBundle.9z8x7y.js';
69
+
70
+ const err = new Error();
71
+ err.stack = createErrorStack(
72
+ 'https://bundle-unsharded.assets.example.com/assets/ParentBundle.cba321.js',
73
+ );
74
+
75
+ const result = getShardedBundleURL(
76
+ testBundle,
77
+ testingCookieName,
78
+ `some.other.cookie=1`,
79
+ 5,
80
+ err,
81
+ );
82
+
83
+ assert.equal(
84
+ result,
85
+ 'https://bundle-unsharded.assets.example.com/assets/',
86
+ );
87
+ });
88
+ });
89
+
90
+ describe('compiled into JS Runtime', () => {
91
+ it('should insert all arguments into compiled output', async () => {
92
+ const maxShards = 8;
93
+ await fsFixture(overlayFS)`
94
+ package.json:
95
+ {
96
+ "name": "bundle-sharding-test",
97
+ "@atlaspack/runtime-js": {
98
+ "domainSharding": {
99
+ "maxShards": ${maxShards},
100
+ "cookieName": "${testingCookieName}"
101
+ }
102
+ }
103
+ }
104
+
105
+ src/index.js:
106
+ async function fn() {
107
+ const a = await import('./a.js');
108
+ const b = await import('./b.js');
109
+ console.log('a', a, b);
110
+ }
111
+ fn();
112
+
113
+ src/a.js:
114
+ export const a = async () => {
115
+ const b = await import('./b');
116
+ return b + 'A';
117
+ }
118
+ src/b.js:
119
+ export const b = 'B';
120
+
121
+ yarn.lock:
122
+ `;
123
+
124
+ const bundleGraph = await bundle('src/index.js', {inputFS: overlayFS});
125
+
126
+ const mainBundle = bundleGraph
127
+ .getBundles()
128
+ .find((b) => b.name === 'index.js');
129
+
130
+ const code = await overlayFS.readFile(mainBundle.filePath, 'utf-8');
131
+ assert.ok(
132
+ code.includes(
133
+ `require("449af90f11ccd363").getShardedBundleURL('b.8575baaf.js', '${testingCookieName}', document.cookie, ${maxShards}) + "b.8575baaf.js"`,
134
+ ),
135
+ 'Expected generated code for getShardedBundleURL was not found',
136
+ );
137
+ });
138
+ });
139
+ });
@@ -1,39 +0,0 @@
1
- "use strict";
2
-
3
- var bundleURL = {};
4
- function getBundleURLCached(id) {
5
- var value = bundleURL[id];
6
- if (!value) {
7
- value = getBundleURL();
8
- bundleURL[id] = value;
9
- }
10
- return value;
11
- }
12
- function getBundleURL() {
13
- try {
14
- throw new Error();
15
- } catch (err) {
16
- var matches = ('' + err.stack).match(/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^)\n]+/g);
17
- if (matches) {
18
- // The first two stack frames will be this function and getBundleURLCached.
19
- // Use the 3rd one, which will be a runtime in the original bundle.
20
- return getBaseURL(matches[2]);
21
- }
22
- }
23
- return '/';
24
- }
25
- function getBaseURL(url) {
26
- return ('' + url).replace(/^((?:https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/.+)\/[^/]+$/, '$1') + '/';
27
- }
28
-
29
- // TODO: Replace uses with `new URL(url).origin` when ie11 is no longer supported.
30
- function getOrigin(url) {
31
- var matches = ('' + url).match(/(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^/]+/);
32
- if (!matches) {
33
- throw new Error('Origin not found');
34
- }
35
- return matches[0];
36
- }
37
- exports.getBundleURL = getBundleURLCached;
38
- exports.getBaseURL = getBaseURL;
39
- exports.getOrigin = getOrigin;
@@ -1,51 +0,0 @@
1
- var bundleURL = {};
2
- function getBundleURLCached(id) {
3
- var value = bundleURL[id];
4
- if (!value) {
5
- value = getBundleURL();
6
- bundleURL[id] = value;
7
- }
8
-
9
- return value;
10
- }
11
-
12
- function getBundleURL() {
13
- try {
14
- throw new Error();
15
- } catch (err) {
16
- var matches = ('' + err.stack).match(
17
- /(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^)\n]+/g,
18
- );
19
- if (matches) {
20
- // The first two stack frames will be this function and getBundleURLCached.
21
- // Use the 3rd one, which will be a runtime in the original bundle.
22
- return getBaseURL(matches[2]);
23
- }
24
- }
25
-
26
- return '/';
27
- }
28
-
29
- function getBaseURL(url) {
30
- return (
31
- ('' + url).replace(
32
- /^((?:https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/.+)\/[^/]+$/,
33
- '$1',
34
- ) + '/'
35
- );
36
- }
37
-
38
- // TODO: Replace uses with `new URL(url).origin` when ie11 is no longer supported.
39
- function getOrigin(url) {
40
- let matches = ('' + url).match(
41
- /(https?|file|ftp|(chrome|moz|safari-web)-extension):\/\/[^/]+/,
42
- );
43
- if (!matches) {
44
- throw new Error('Origin not found');
45
- }
46
- return matches[0];
47
- }
48
-
49
- exports.getBundleURL = getBundleURLCached;
50
- exports.getBaseURL = getBaseURL;
51
- exports.getOrigin = getOrigin;