es-module-shims 1.5.15 → 1.5.16

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/README.md CHANGED
@@ -2,9 +2,9 @@
2
2
 
3
3
  Shims modern ES Modules features like import maps on top of the baseline modules support in browsers supported by [95% of users](https://caniuse.com/#feat=es6-module).
4
4
 
5
- When running in polyfill mode, [the 67% of users](https://caniuse.com/import-maps) with import maps entirely bypass the shim code entirely.
5
+ When running in polyfill mode, [the 72% of users](https://caniuse.com/import-maps) with import maps entirely bypass the shim code entirely.
6
6
 
7
- For the remaining 30% of users, the highly performant (see [benchmarks](#benchmarks)) production and [CSP-compatible](#csp-support) shim kicks in to rewrite module specifiers driven by the [Web Assembly ES Module Lexer](https://github.com/guybedford/es-module-lexer).
7
+ For the remaining 28% of users, the highly performant (see [benchmarks](#benchmarks)) production and [CSP-compatible](#csp-support) shim kicks in to rewrite module specifiers driven by the [Web Assembly ES Module Lexer](https://github.com/guybedford/es-module-lexer).
8
8
 
9
9
  The following modules features are polyfilled:
10
10
 
@@ -29,7 +29,7 @@ Because we are still using the native module loader the edge cases work out comp
29
29
  Include ES Module Shims with a `async` attribute on the script, then include an import map and module scripts normally:
30
30
 
31
31
  ```html
32
- <script async src="https://ga.jspm.io/npm:es-module-shims@1.5.15/dist/es-module-shims.js"></script>
32
+ <script async src="https://ga.jspm.io/npm:es-module-shims@1.5.16/dist/es-module-shims.js"></script>
33
33
 
34
34
  <!-- https://generator.jspm.io/#U2NhYGBkDM0rySzJSU1hKEpNTC5xMLTQM9Az0C1K1jMAAKFS5w0gAA -->
35
35
  <script type="importmap">
@@ -176,8 +176,8 @@ ES Module Shims is designed for production performance. A [comprehensive benchma
176
176
 
177
177
  Benchmark summary:
178
178
 
179
- * [ES Module Shims Chrome Passthrough](bench/README.md#chrome-passthrough-performance) (for [70% of users](https://caniuse.com/import-maps)) results in ~5ms extra initialization time over native for ES Module Shims fetching, execution and initialization, and on a slow connection the additional non-blocking bandwidth cost of its 10KB compressed download as expected.
180
- * [ES Module Shims Polyfilling](bench/README.md#native-v-polyfill-performance) (for the remaining [30% of users](https://caniuse.com/import-maps)) is on average 1.4x - 1.5x slower than native module loading, and up to 1.8x slower on slow networks (most likely due to the browser preloader), both for cached and uncached loads, and this result scales linearly up to 10MB and 20k modules loaded executing on the fastest connection in just over 2 seconds in Firefox.
179
+ * [ES Module Shims Chrome Passthrough](bench/README.md#chrome-passthrough-performance) (for [72% of users](https://caniuse.com/import-maps)) results in ~5ms extra initialization time over native for ES Module Shims fetching, execution and initialization, and on a slow connection the additional non-blocking bandwidth cost of its 10KB compressed download as expected.
180
+ * [ES Module Shims Polyfilling](bench/README.md#native-v-polyfill-performance) (for the remaining [28% of users](https://caniuse.com/import-maps)) is on average 1.4x - 1.5x slower than native module loading, and up to 1.8x slower on slow networks (most likely due to the browser preloader), both for cached and uncached loads, and this result scales linearly up to 10MB and 20k modules loaded executing on the fastest connection in just over 2 seconds in Firefox.
181
181
  * [Very large import maps](bench/README.md#large-import-maps-performance) (100s of entries) cost only a few extra milliseconds upfront for the additional loading cost.
182
182
 
183
183
  ## Features
@@ -1,4 +1,4 @@
1
- /* ES Module Shims 1.5.15 */
1
+ /* ES Module Shims 1.5.16 */
2
2
  (function () {
3
3
 
4
4
  const hasWindow = typeof window !== 'undefined';
@@ -258,40 +258,52 @@
258
258
  }
259
259
  }
260
260
 
261
- let err;
262
- window.addEventListener('error', _err => err = _err);
263
- const inject = (s, errUrl) => new Promise((resolve, reject) => {
264
- err = undefined;
265
- s.ep = true;
266
- if (nonce)
267
- s.setAttribute('nonce', nonce);
268
-
269
- // Safari is unique in supporting module script error events
270
- s.addEventListener('error', cb);
271
- s.addEventListener('load', cb);
272
-
273
- function cb (_err) {
274
- document.head.removeChild(s);
275
- if (self._esmsi) {
276
- resolve(self._esmsi, baseUrl);
277
- self._esmsi = undefined;
278
- }
279
- else {
280
- reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${s.src}).`));
281
- err = undefined;
282
- }
283
- }
284
-
285
- document.head.appendChild(s);
286
- });
261
+ let dynamicImport = !hasDocument && (0, eval)('u=>import(u)');
287
262
 
288
- const dynamicImport = (url, opts) => inject(Object.assign(document.createElement('script'), {
289
- type: 'module',
290
- src: createBlob(`import*as m from'${url}';self._esmsi=m`)
291
- }), opts && opts.errUrl || url);
263
+ let supportsDynamicImport;
292
264
 
293
- // This is done as a script so we don't trigger module loading too early for any loading import maps
294
- const supportsDynamicImportCheck = inject(Object.assign(document.createElement('script'), { src: createBlob('self._esmsi=u => import(u)') })).then(() => true, () => false);
265
+ const dynamicImportCheck = hasDocument && new Promise(resolve => {
266
+ const s = Object.assign(document.createElement('script'), {
267
+ src: createBlob('self._d=u=>import(u)'),
268
+ ep: true
269
+ });
270
+ s.setAttribute('nonce', nonce);
271
+ s.addEventListener('load', () => {
272
+ if (!(supportsDynamicImport = !!(dynamicImport = self._d))) {
273
+ let err;
274
+ window.addEventListener('error', _err => err = _err);
275
+ dynamicImport = (url, opts) => new Promise((resolve, reject) => {
276
+ const s = Object.assign(document.createElement('script'), {
277
+ type: 'module',
278
+ src: createBlob(`import*as m from'${url}';self._esmsi=m`)
279
+ });
280
+ err = undefined;
281
+ s.ep = true;
282
+ if (nonce)
283
+ s.setAttribute('nonce', nonce);
284
+ // Safari is unique in supporting module script error events
285
+ s.addEventListener('error', cb);
286
+ s.addEventListener('load', cb);
287
+ function cb (_err) {
288
+ document.head.removeChild(s);
289
+ if (self._esmsi) {
290
+ resolve(self._esmsi, baseUrl);
291
+ self._esmsi = undefined;
292
+ }
293
+ else {
294
+ reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading ${opts && opts.errUrl || url} (${s.src}).`));
295
+ err = undefined;
296
+ }
297
+ }
298
+ document.head.appendChild(s);
299
+ });
300
+ }
301
+ document.head.removeChild(s);
302
+ delete self._d;
303
+ resolve();
304
+ });
305
+ document.head.appendChild(s);
306
+ });
295
307
 
296
308
  // support browsers without dynamic import support (eg Firefox 6x)
297
309
  let supportsJsonAssertions = false;
@@ -299,53 +311,49 @@
299
311
 
300
312
  let supportsImportMaps = hasDocument && HTMLScriptElement.supports ? HTMLScriptElement.supports('importmap') : false;
301
313
  let supportsImportMeta = supportsImportMaps;
302
- let supportsDynamicImport = false;
303
314
 
304
- const featureDetectionPromise = Promise.resolve(supportsImportMaps || supportsDynamicImportCheck).then(_supportsDynamicImport => {
305
- if (!_supportsDynamicImport)
315
+ const importMetaCheck = 'import.meta';
316
+ const cssModulesCheck = `import"x"assert{type:"css"}`;
317
+ const jsonModulesCheck = `import"x"assert{type:"json"}`;
318
+
319
+ const featureDetectionPromise = Promise.resolve(dynamicImportCheck).then(() => {
320
+ if (!supportsDynamicImport || supportsImportMaps && !cssModulesEnabled && !jsonModulesEnabled)
306
321
  return;
307
- supportsDynamicImport = true;
308
-
309
- if (!supportsImportMaps || cssModulesEnabled || jsonModulesEnabled) {
310
- const importMetaCheck = 'import.meta';
311
- const cssModulesCheck = `import"x"assert{type:"css"}`;
312
- const jsonModulesCheck = `import"x"assert{type:"json"}`;
313
-
314
- if (!hasDocument)
315
- return Promise.all([
316
- supportsImportMaps || dynamicImport(createBlob(importMetaCheck)).then(() => supportsImportMeta = true, noop),
317
- cssModulesEnabled && dynamicImport(createBlob(cssModulesCheck.replace('x', createBlob('', 'text/css')))).then(() => supportsCssAssertions = true, noop),
318
- jsonModulesEnabled && dynamicImport(createBlob(jsonModulescheck.replace('x', createBlob('{}', 'text/json')))).then(() => supportsJsonAssertions = true, noop),
319
- ]);
320
-
321
- return new Promise(resolve => {
322
- const iframe = document.createElement('iframe');
323
- iframe.style.display = 'none';
324
- iframe.setAttribute('nonce', nonce);
325
- function cb ({ data: [a, b, c, d] }) {
326
- supportsImportMaps = a;
327
- supportsImportMeta = b;
328
- supportsCssAssertions = c;
329
- supportsJsonAssertions = d;
330
- resolve();
331
- document.head.removeChild(iframe);
332
- window.removeEventListener('message', cb, false);
333
- }
334
- window.addEventListener('message', cb, false);
335
-
336
- const importMapTest = `<script nonce=${nonce}>const b=(s,type='text/javascript')=>URL.createObjectURL(new Blob([s],{type}));document.head.appendChild(Object.assign(document.createElement('script'),{type:'importmap',nonce:"${nonce}",innerText:\`{"imports":{"x":"\${b('')}"}}\`}));Promise.all([${
337
- supportsImportMaps ? 'true,true' : `'x',b('${importMetaCheck}')`}, ${cssModulesEnabled ? `b('${cssModulesCheck}'.replace('x',b('','text/css')))` : 'false'}, ${
338
- jsonModulesEnabled ? `b('${jsonModulesCheck}'.replace('x',b('{}','text/json')))` : 'false'}].map(x =>typeof x==='string'?import(x).then(x =>!!x,()=>false):x)).then(a=>parent.postMessage(a,'*'))<${''}/script>`;
339
- // setting srcdoc is not supported in React native webviews on iOS
340
- // setting src to a blob URL results in a navigation event in webviews
341
- // document.write gives usability warnings
342
- if ('srcdoc' in iframe)
343
- iframe.srcdoc = importMapTest;
344
- else
345
- iframe.contentDocument.write(importMapTest);
346
- document.head.appendChild(iframe);
347
- });
348
- }
322
+
323
+ if (!hasDocument)
324
+ return Promise.all([
325
+ supportsImportMaps || dynamicImport(createBlob(importMetaCheck)).then(() => supportsImportMeta = true, noop),
326
+ cssModulesEnabled && dynamicImport(createBlob(cssModulesCheck.replace('x', createBlob('', 'text/css')))).then(() => supportsCssAssertions = true, noop),
327
+ jsonModulesEnabled && dynamicImport(createBlob(jsonModulescheck.replace('x', createBlob('{}', 'text/json')))).then(() => supportsJsonAssertions = true, noop),
328
+ ]);
329
+
330
+ return new Promise(resolve => {
331
+ const iframe = document.createElement('iframe');
332
+ iframe.style.display = 'none';
333
+ iframe.setAttribute('nonce', nonce);
334
+ function cb ({ data: [a, b, c, d] }) {
335
+ supportsImportMaps = a;
336
+ supportsImportMeta = b;
337
+ supportsCssAssertions = c;
338
+ supportsJsonAssertions = d;
339
+ resolve();
340
+ document.head.removeChild(iframe);
341
+ window.removeEventListener('message', cb, false);
342
+ }
343
+ window.addEventListener('message', cb, false);
344
+
345
+ const importMapTest = `<script nonce=${nonce}>const b=(s,type='text/javascript')=>URL.createObjectURL(new Blob([s],{type}));document.head.appendChild(Object.assign(document.createElement('script'),{type:'importmap',nonce:"${nonce}",innerText:\`{"imports":{"x":"\${b('')}"}}\`}));Promise.all([${
346
+ supportsImportMaps ? 'true,true' : `'x',b('${importMetaCheck}')`}, ${cssModulesEnabled ? `b('${cssModulesCheck}'.replace('x',b('','text/css')))` : 'false'}, ${
347
+ jsonModulesEnabled ? `b('${jsonModulesCheck}'.replace('x',b('{}','text/json')))` : 'false'}].map(x =>typeof x==='string'?import(x).then(x =>!!x,()=>false):x)).then(a=>parent.postMessage(a,'*'))<${''}/script>`;
348
+ // setting srcdoc is not supported in React native webviews on iOS
349
+ // setting src to a blob URL results in a navigation event in webviews
350
+ // document.write gives usability warnings
351
+ if ('srcdoc' in iframe)
352
+ iframe.srcdoc = importMapTest;
353
+ else
354
+ iframe.contentDocument.write(importMapTest);
355
+ document.head.appendChild(iframe);
356
+ });
349
357
  });
350
358
 
351
359
  /* es-module-lexer 1.0.3 */
@@ -1,4 +1,4 @@
1
- /* ES Module Shims Wasm 1.5.15 */
1
+ /* ES Module Shims Wasm 1.5.16 */
2
2
  (function () {
3
3
 
4
4
  const hasWindow = typeof window !== 'undefined';
@@ -258,48 +258,52 @@
258
258
  }
259
259
  }
260
260
 
261
- let supportsDynamicImportCheck = false;
262
-
263
- // first check basic eval support
264
- try {
265
- eval('');
266
- }
267
- catch (e) {
268
- throw new Error(`The ES Module Shims Wasm build will not work without eval support. Either use the alternative CSP-compatible build or make sure to add both the "unsafe-eval" and "unsafe-wasm-eval" CSP policies.`);
269
- }
270
-
271
- // polyfill dynamic import if not supported
272
- let dynamicImport;
273
- try {
274
- dynamicImport = (0, eval)('u=>import(u)');
275
- supportsDynamicImportCheck = true;
276
- }
277
- catch (e) {}
278
-
279
- if (hasDocument && !supportsDynamicImportCheck) {
280
- let err;
281
- window.addEventListener('error', _err => err = _err);
282
- dynamicImport = (url, { errUrl = url }) => {
283
- err = undefined;
284
- const src = createBlob(`import*as m from'${url}';self._esmsi=m;`);
285
- const s = Object.assign(document.createElement('script'), { type: 'module', src });
286
- s.setAttribute('noshim', '');
287
- document.head.appendChild(s);
288
- return new Promise((resolve, reject) => {
289
- s.addEventListener('load', () => {
290
- document.head.removeChild(s);
291
- if (self._esmsi) {
292
- resolve(_esmsi, baseUrl);
293
- _esmsi = null;
294
- }
295
- else {
296
- reject(err.error || new Error(`Error loading or executing the graph of ${errUrl} (check the console for ${src}).`));
297
- err = undefined;
261
+ let dynamicImport = !hasDocument && (0, eval)('u=>import(u)');
262
+
263
+ let supportsDynamicImport;
264
+
265
+ const dynamicImportCheck = hasDocument && new Promise(resolve => {
266
+ const s = Object.assign(document.createElement('script'), {
267
+ src: createBlob('self._d=u=>import(u)'),
268
+ ep: true
269
+ });
270
+ s.setAttribute('nonce', nonce);
271
+ s.addEventListener('load', () => {
272
+ if (!(supportsDynamicImport = !!(dynamicImport = self._d))) {
273
+ let err;
274
+ window.addEventListener('error', _err => err = _err);
275
+ dynamicImport = (url, opts) => new Promise((resolve, reject) => {
276
+ const s = Object.assign(document.createElement('script'), {
277
+ type: 'module',
278
+ src: createBlob(`import*as m from'${url}';self._esmsi=m`)
279
+ });
280
+ err = undefined;
281
+ s.ep = true;
282
+ if (nonce)
283
+ s.setAttribute('nonce', nonce);
284
+ // Safari is unique in supporting module script error events
285
+ s.addEventListener('error', cb);
286
+ s.addEventListener('load', cb);
287
+ function cb (_err) {
288
+ document.head.removeChild(s);
289
+ if (self._esmsi) {
290
+ resolve(self._esmsi, baseUrl);
291
+ self._esmsi = undefined;
292
+ }
293
+ else {
294
+ reject(!(_err instanceof Event) && _err || err && err.error || new Error(`Error loading ${opts && opts.errUrl || url} (${s.src}).`));
295
+ err = undefined;
296
+ }
298
297
  }
298
+ document.head.appendChild(s);
299
299
  });
300
- });
301
- };
302
- }
300
+ }
301
+ document.head.removeChild(s);
302
+ delete self._d;
303
+ resolve();
304
+ });
305
+ document.head.appendChild(s);
306
+ });
303
307
 
304
308
  // support browsers without dynamic import support (eg Firefox 6x)
305
309
  let supportsJsonAssertions = false;
@@ -307,53 +311,49 @@
307
311
 
308
312
  let supportsImportMaps = hasDocument && HTMLScriptElement.supports ? HTMLScriptElement.supports('importmap') : false;
309
313
  let supportsImportMeta = supportsImportMaps;
310
- let supportsDynamicImport = false;
311
314
 
312
- const featureDetectionPromise = Promise.resolve(supportsImportMaps || supportsDynamicImportCheck).then(_supportsDynamicImport => {
313
- if (!_supportsDynamicImport)
315
+ const importMetaCheck = 'import.meta';
316
+ const cssModulesCheck = `import"x"assert{type:"css"}`;
317
+ const jsonModulesCheck = `import"x"assert{type:"json"}`;
318
+
319
+ const featureDetectionPromise = Promise.resolve(dynamicImportCheck).then(() => {
320
+ if (!supportsDynamicImport || supportsImportMaps && !cssModulesEnabled && !jsonModulesEnabled)
314
321
  return;
315
- supportsDynamicImport = true;
316
-
317
- if (!supportsImportMaps || cssModulesEnabled || jsonModulesEnabled) {
318
- const importMetaCheck = 'import.meta';
319
- const cssModulesCheck = `import"x"assert{type:"css"}`;
320
- const jsonModulesCheck = `import"x"assert{type:"json"}`;
321
-
322
- if (!hasDocument)
323
- return Promise.all([
324
- supportsImportMaps || dynamicImport(createBlob(importMetaCheck)).then(() => supportsImportMeta = true, noop),
325
- cssModulesEnabled && dynamicImport(createBlob(cssModulesCheck.replace('x', createBlob('', 'text/css')))).then(() => supportsCssAssertions = true, noop),
326
- jsonModulesEnabled && dynamicImport(createBlob(jsonModulescheck.replace('x', createBlob('{}', 'text/json')))).then(() => supportsJsonAssertions = true, noop),
327
- ]);
328
-
329
- return new Promise(resolve => {
330
- const iframe = document.createElement('iframe');
331
- iframe.style.display = 'none';
332
- iframe.setAttribute('nonce', nonce);
333
- function cb ({ data: [a, b, c, d] }) {
334
- supportsImportMaps = a;
335
- supportsImportMeta = b;
336
- supportsCssAssertions = c;
337
- supportsJsonAssertions = d;
338
- resolve();
339
- document.head.removeChild(iframe);
340
- window.removeEventListener('message', cb, false);
341
- }
342
- window.addEventListener('message', cb, false);
343
-
344
- const importMapTest = `<script nonce=${nonce}>const b=(s,type='text/javascript')=>URL.createObjectURL(new Blob([s],{type}));document.head.appendChild(Object.assign(document.createElement('script'),{type:'importmap',nonce:"${nonce}",innerText:\`{"imports":{"x":"\${b('')}"}}\`}));Promise.all([${
345
- supportsImportMaps ? 'true,true' : `'x',b('${importMetaCheck}')`}, ${cssModulesEnabled ? `b('${cssModulesCheck}'.replace('x',b('','text/css')))` : 'false'}, ${
346
- jsonModulesEnabled ? `b('${jsonModulesCheck}'.replace('x',b('{}','text/json')))` : 'false'}].map(x =>typeof x==='string'?import(x).then(x =>!!x,()=>false):x)).then(a=>parent.postMessage(a,'*'))<${''}/script>`;
347
- // setting srcdoc is not supported in React native webviews on iOS
348
- // setting src to a blob URL results in a navigation event in webviews
349
- // document.write gives usability warnings
350
- if ('srcdoc' in iframe)
351
- iframe.srcdoc = importMapTest;
352
- else
353
- iframe.contentDocument.write(importMapTest);
354
- document.head.appendChild(iframe);
355
- });
356
- }
322
+
323
+ if (!hasDocument)
324
+ return Promise.all([
325
+ supportsImportMaps || dynamicImport(createBlob(importMetaCheck)).then(() => supportsImportMeta = true, noop),
326
+ cssModulesEnabled && dynamicImport(createBlob(cssModulesCheck.replace('x', createBlob('', 'text/css')))).then(() => supportsCssAssertions = true, noop),
327
+ jsonModulesEnabled && dynamicImport(createBlob(jsonModulescheck.replace('x', createBlob('{}', 'text/json')))).then(() => supportsJsonAssertions = true, noop),
328
+ ]);
329
+
330
+ return new Promise(resolve => {
331
+ const iframe = document.createElement('iframe');
332
+ iframe.style.display = 'none';
333
+ iframe.setAttribute('nonce', nonce);
334
+ function cb ({ data: [a, b, c, d] }) {
335
+ supportsImportMaps = a;
336
+ supportsImportMeta = b;
337
+ supportsCssAssertions = c;
338
+ supportsJsonAssertions = d;
339
+ resolve();
340
+ document.head.removeChild(iframe);
341
+ window.removeEventListener('message', cb, false);
342
+ }
343
+ window.addEventListener('message', cb, false);
344
+
345
+ const importMapTest = `<script nonce=${nonce}>const b=(s,type='text/javascript')=>URL.createObjectURL(new Blob([s],{type}));document.head.appendChild(Object.assign(document.createElement('script'),{type:'importmap',nonce:"${nonce}",innerText:\`{"imports":{"x":"\${b('')}"}}\`}));Promise.all([${
346
+ supportsImportMaps ? 'true,true' : `'x',b('${importMetaCheck}')`}, ${cssModulesEnabled ? `b('${cssModulesCheck}'.replace('x',b('','text/css')))` : 'false'}, ${
347
+ jsonModulesEnabled ? `b('${jsonModulesCheck}'.replace('x',b('{}','text/json')))` : 'false'}].map(x =>typeof x==='string'?import(x).then(x =>!!x,()=>false):x)).then(a=>parent.postMessage(a,'*'))<${''}/script>`;
348
+ // setting srcdoc is not supported in React native webviews on iOS
349
+ // setting src to a blob URL results in a navigation event in webviews
350
+ // document.write gives usability warnings
351
+ if ('srcdoc' in iframe)
352
+ iframe.srcdoc = importMapTest;
353
+ else
354
+ iframe.contentDocument.write(importMapTest);
355
+ document.head.appendChild(iframe);
356
+ });
357
357
  });
358
358
 
359
359
  /* es-module-lexer 1.0.3 */
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "es-module-shims",
3
- "version": "1.5.15",
3
+ "version": "1.5.16",
4
4
  "description": "Shims for the latest ES module features",
5
5
  "main": "dist/es-module-shims.js",
6
6
  "exports": {