es-module-shims 2.1.2 → 2.3.0
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 +126 -36
- package/dist/es-module-shims.debug.js +609 -395
- package/dist/es-module-shims.js +601 -390
- package/dist/es-module-shims.wasm.js +601 -390
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -9,10 +9,11 @@ For the remaining ~4% of users, the highly performant (see [benchmarks](#benchma
|
|
|
9
9
|
The following modules features are polyfilled:
|
|
10
10
|
|
|
11
11
|
* [Import Maps](#import-maps) polyfill.
|
|
12
|
-
* [JSON](#json-modules) and [CSS modules](#css-modules) with import assertions
|
|
13
|
-
* [Wasm modules](#wasm-modules) with support for Source Phase Imports when enabled.
|
|
14
|
-
* [Import defer](#import-defer) via syntax stripping to allow usage in modern browsers with a polyfill fallback when enabled.
|
|
15
|
-
* [TypeScript](#typescript-type-stripping) type stripping
|
|
12
|
+
* [JSON](#json-modules) and [CSS modules](#css-modules) polyfill with import assertions.
|
|
13
|
+
* [Wasm modules](#wasm-modules) with support for Source Phase Imports, when enabled.
|
|
14
|
+
* [Import defer](#import-defer) via syntax stripping to allow usage in modern browsers with a polyfill fallback, when enabled.
|
|
15
|
+
* [TypeScript](#typescript-type-stripping) type stripping.
|
|
16
|
+
* [Hot Reloading](#hot-reloading) with a Vite-style `import.meta.hot` API.
|
|
16
17
|
|
|
17
18
|
When running in shim mode, module rewriting is applied for all users and custom [resolve](#resolve-hook) and [fetch](#fetch-hook) hooks can be implemented allowing for custom resolution and streaming in-browser transform workflows.
|
|
18
19
|
|
|
@@ -29,7 +30,7 @@ Because we are still using the native module loader the edge cases work out comp
|
|
|
29
30
|
Include ES Module Shims with a `async` attribute on the script, then include an import map and module scripts normally:
|
|
30
31
|
|
|
31
32
|
```html
|
|
32
|
-
<script async src="https://ga.jspm.io/npm:es-module-shims@2.
|
|
33
|
+
<script async src="https://ga.jspm.io/npm:es-module-shims@2.3.0/dist/es-module-shims.js"></script>
|
|
33
34
|
|
|
34
35
|
<!-- https://generator.jspm.io/#U2NhYGBkDM0rySzJSU1hKEpNTC5xMLTQM9Az0C1K1jMAAKFS5w0gAA -->
|
|
35
36
|
<script type="importmap">
|
|
@@ -188,22 +189,20 @@ If the polyfill is analyzing or applying to a module script that doesn't need to
|
|
|
188
189
|
|
|
189
190
|
### Polyfill Features
|
|
190
191
|
|
|
191
|
-
If using more modern features like
|
|
192
|
+
If using more modern features like [Import Defer](#import-defer) or [Wasm Modules](#wasm-modules), these need to be manually enabled via the [`polyfillEnable` init option](#polyfill-enable-option) to raise the native baseline from just checking import maps to also checking that browsers support these features:
|
|
192
193
|
|
|
193
194
|
```html
|
|
194
195
|
<script>
|
|
195
|
-
window.esmsInitOptions = { polyfillEnable: ['
|
|
196
|
+
window.esmsInitOptions = { polyfillEnable: ['wasm-module-sources', 'import-defer'] }
|
|
196
197
|
</script>
|
|
197
198
|
```
|
|
198
199
|
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
Alternatively options can be set via the `esms-options` script type:
|
|
200
|
+
Alternatively options can be set via the `esms-options` script type JSON:
|
|
202
201
|
|
|
203
202
|
```html
|
|
204
203
|
<script type="esms-options">
|
|
205
204
|
{
|
|
206
|
-
"polyfillEnable": "
|
|
205
|
+
"polyfillEnable": ["wasm-module-sources", "import-defer"]
|
|
207
206
|
}
|
|
208
207
|
</script>
|
|
209
208
|
```
|
|
@@ -224,7 +223,7 @@ ES Module Shims is designed for production performance. A [comprehensive benchma
|
|
|
224
223
|
|
|
225
224
|
Benchmark summary:
|
|
226
225
|
|
|
227
|
-
* [ES Module Shims Chrome Passthrough](bench/README.md#chrome-passthrough-performance) (for [94% 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
|
|
226
|
+
* [ES Module Shims Chrome Passthrough](bench/README.md#chrome-passthrough-performance) (for [94% 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 13KB compressed download as expected.
|
|
228
227
|
* [ES Module Shims Polyfilling](bench/README.md#native-v-polyfill-performance) (for the remaining [3% 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.
|
|
229
228
|
* [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.
|
|
230
229
|
|
|
@@ -254,7 +253,7 @@ Browser compatibility **without** ES Module Shims:
|
|
|
254
253
|
| [modulepreload](#modulepreload) | 66+ | 115+ | 17.5+ |
|
|
255
254
|
| [Import Maps](#import-maps) | 89+ | 108+ | 16.4+ |
|
|
256
255
|
| [Import Map Integrity](#import-map-integrity) | 127+ | :x: | :x: |
|
|
257
|
-
| [Multiple Import Maps](#multiple-import-maps) |
|
|
256
|
+
| [Multiple Import Maps](#multiple-import-maps) | 135+ | :x: | :x: |
|
|
258
257
|
| [JSON Modules](#json-modules) | 123+ | :x: | 17.2+ |
|
|
259
258
|
| [CSS Modules](#css-modules) | 123+ | :x: | :x: |
|
|
260
259
|
| [Wasm Modules](#wasm-modules) | Pending | :x: | :x: |
|
|
@@ -483,11 +482,13 @@ Note integrity can only be validated when in shim mode or when the polyfill is d
|
|
|
483
482
|
|
|
484
483
|
### JSON Modules
|
|
485
484
|
|
|
486
|
-
> Stability: WhatWG Standard,
|
|
485
|
+
> Stability: WhatWG Standard, Stable, Multiple Browser Implementers
|
|
487
486
|
|
|
488
|
-
|
|
487
|
+
JSON modules are now enabled by default in ES Module Shims with 85% browser support for native where the polyfill won't engage at all.
|
|
489
488
|
|
|
490
|
-
JSON
|
|
489
|
+
In shim mode, JSON modules are always supported.
|
|
490
|
+
|
|
491
|
+
JSON Modules are supported in Chrome and Safari when using them via an import assertion:
|
|
491
492
|
|
|
492
493
|
```html
|
|
493
494
|
<script type="module">
|
|
@@ -501,9 +502,9 @@ In addition JSON modules need to be served with a valid JSON content type.
|
|
|
501
502
|
|
|
502
503
|
> Stability: WhatWG Standard, Single Browser Implementer
|
|
503
504
|
|
|
504
|
-
|
|
505
|
+
CSS imports are fully supported in both polyfill and shim mode with native passthrough applying in Chrome.
|
|
505
506
|
|
|
506
|
-
|
|
507
|
+
Use them by adding the `type: 'css'` import assertion when importing a CSS file:
|
|
507
508
|
|
|
508
509
|
```html
|
|
509
510
|
<script type="module">
|
|
@@ -511,7 +512,7 @@ import sheet from 'https://site.com/sheet.css' with { type: 'css' };
|
|
|
511
512
|
</script>
|
|
512
513
|
```
|
|
513
514
|
|
|
514
|
-
In addition CSS
|
|
515
|
+
In addition CSS files need to be served with a valid CSS content type.
|
|
515
516
|
|
|
516
517
|
### Wasm Modules
|
|
517
518
|
|
|
@@ -519,13 +520,11 @@ In addition CSS modules need to be served with a valid CSS content type.
|
|
|
519
520
|
|
|
520
521
|
Implements the [WebAssembly ESM Integration](https://github.com/WebAssembly/esm-integration) spec, including support for source phase imports.
|
|
521
522
|
|
|
522
|
-
In shim mode, Wasm modules are always supported. In polyfill mode, Wasm modules require the `polyfillEnable: ['wasm-
|
|
523
|
+
In shim mode, Wasm modules are always supported. In polyfill mode, Wasm modules require the `polyfillEnable: ['wasm-module-sources']` (or `'wasm-modules-instances'` for instance imports) [init option](#polyfill-enable-option).
|
|
523
524
|
|
|
524
525
|
WebAssembly module exports are made available as module exports and WebAssembly module imports will be resolved using the browser module loader.
|
|
525
526
|
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
If only using Wasm modules in the source phase set `polyfillEnable: ['wasm-module-sources']` [init option](#polyfill-enable-option) to ensure full native passthrough without the extra code analysis when Chrome ships the source phase.
|
|
527
|
+
If only using Wasm modules in both the instance and source phase set `polyfillEnable: ['wasm-modules']` [init option](#polyfill-enable-option) to enable both modes.
|
|
529
528
|
|
|
530
529
|
When enabling the source phase feature either way, `WebAssembly.Module` is also polyfilled to extend from `AbstractModuleSource` per the source phase proposal.
|
|
531
530
|
|
|
@@ -546,7 +545,7 @@ const instance = await WebAssembly.instantiate(mod, { /* ...imports */ });
|
|
|
546
545
|
</script>
|
|
547
546
|
```
|
|
548
547
|
|
|
549
|
-
If using CSP, make sure to add `'unsafe-wasm-eval'` to `script-src` which is needed when the shim or polyfill engages, note this policy is
|
|
548
|
+
If using CSP, make sure to add `'unsafe-wasm-eval'` to `script-src` which is needed when the shim or polyfill engages, note this policy is safer than normal eval due to the Wasm secure sandbox. See https://developer.mozilla.org/en-US/docs/Web/HTTP/Headers/Content-Security-Policy/script-src#unsafe_webassembly_execution.
|
|
550
549
|
|
|
551
550
|
### Import Defer
|
|
552
551
|
|
|
@@ -558,24 +557,100 @@ The polyfill is simply just a defer syntax stripping, allowing environments that
|
|
|
558
557
|
|
|
559
558
|
### TypeScript Type Stripping
|
|
560
559
|
|
|
561
|
-
|
|
560
|
+
TypeScript type stripping is supported like [in Node.js](https://nodejs.org/api/typescript.html).
|
|
562
561
|
|
|
563
|
-
|
|
562
|
+
To trigger TypeScript type stripping, make sure to either use shim mode, or to add the non-standard `lang="ts"` option to the top-level evaluator. This ensures that the polyfill processing will engage on this graph, while usually module graphs are not processed at all in browsers with full native support.
|
|
564
563
|
|
|
565
|
-
|
|
564
|
+
Modules will then be interpreted as TypeScript when one of the following applied:
|
|
565
|
+
|
|
566
|
+
* It is served with the `application/typescript` MIME type.
|
|
567
|
+
* It ends in `.ts` or `.mts` and is not served with a valid module script MIME type.
|
|
568
|
+
* Or, if it is an inline `lang="ts"` module script.
|
|
569
|
+
|
|
570
|
+
For example the following are all valid TypeScript usage patterns:
|
|
571
|
+
|
|
572
|
+
Shim mode - no `lang=ts` is necessary:
|
|
566
573
|
|
|
567
574
|
```html
|
|
568
|
-
<script
|
|
569
|
-
|
|
575
|
+
<script type="module-shim" src="app.ts">
|
|
576
|
+
```
|
|
577
|
+
|
|
578
|
+
Polyfill mode via `lang=ts`:
|
|
579
|
+
|
|
580
|
+
```html
|
|
581
|
+
<script type="module" lang="ts" src="app.ts"></script>
|
|
582
|
+
```
|
|
583
|
+
|
|
584
|
+
Inline TypeScript with `lang=ts`:
|
|
585
|
+
|
|
586
|
+
```html
|
|
587
|
+
<script type="module" lang="ts">
|
|
588
|
+
import './dep.ts';
|
|
589
|
+
const ts: boolean = true;
|
|
590
|
+
console.log('TypeScript!');
|
|
591
|
+
</script>
|
|
592
|
+
```
|
|
593
|
+
|
|
594
|
+
Indirect static import to a TypeScript module via `lang="ts"`:
|
|
595
|
+
|
|
596
|
+
```html
|
|
597
|
+
<script type="importmap">
|
|
570
598
|
{
|
|
571
|
-
"
|
|
599
|
+
"imports": {
|
|
600
|
+
"app": "/app.mts"
|
|
601
|
+
}
|
|
572
602
|
}
|
|
573
603
|
</script>
|
|
574
|
-
<script type="module"
|
|
604
|
+
<script type="module" lang="ts">
|
|
605
|
+
import 'app';
|
|
606
|
+
</script>
|
|
575
607
|
```
|
|
576
608
|
|
|
609
|
+
Loading TypeScript dynamically:
|
|
610
|
+
|
|
611
|
+
```html
|
|
612
|
+
<script type="module" lang="ts">
|
|
613
|
+
importShim('./app.ts', { lang: 'ts' });
|
|
614
|
+
</script>
|
|
615
|
+
```
|
|
616
|
+
|
|
617
|
+
When processing a TypeScript module, the `es-module-shims-typescript.js` extension must be available as a sibling asset to `es-module-shims.js`. It will then be loaded on-demand to provide the type stripping processing.
|
|
618
|
+
|
|
577
619
|
Note that runtime TypeScript features such as enums are not supported, and type only imports should be used where possible, per the Node.js guidance for TypeScript.
|
|
578
620
|
|
|
621
|
+
### Hot Reloading
|
|
622
|
+
|
|
623
|
+
Hot reloading is supported in both shim and polyfill modes, when explicitly enabled. To enable hot-reloading, enable the `hotReload` init option:
|
|
624
|
+
|
|
625
|
+
test.html
|
|
626
|
+
```html
|
|
627
|
+
<script type="esms-options">
|
|
628
|
+
{
|
|
629
|
+
"hotReload": true,
|
|
630
|
+
"hotReloadInterval": 100
|
|
631
|
+
}
|
|
632
|
+
</script>
|
|
633
|
+
<script async src="es-module-shims.js"></script>
|
|
634
|
+
<script type="module" src="/app.js"></script>
|
|
635
|
+
```
|
|
636
|
+
|
|
637
|
+
In polyfill mode, all modules will be initialized twice when hot reloading to reinitiate with `import.meta.hot`. To avoid this, shim mode is recommended for hot reloading workflows whenever possible.
|
|
638
|
+
|
|
639
|
+
The `hotReloadInterval` option can also be configured which is the interval at which hot reload events are batched together as a single reload operation, with the default of `100`.
|
|
640
|
+
|
|
641
|
+
When enabled, [native passthrough](#native-passthrough) will be automatically disabled, and all modules will be provided with the `import.meta.hot` API fully supporting [Vite's `import.meta.hot`](https://vite.dev/guide/api-hmr), supporting the following methods except for the event handlers:
|
|
642
|
+
|
|
643
|
+
* `hot.accept(cb)`: Accept a hot update.
|
|
644
|
+
* `hot.accept(dep, cb)`: Accept a hot update of a dependency specifier string.
|
|
645
|
+
* `hot.accept(deps, cb)`: Accept a hot update of a list of dependency specifier strings.
|
|
646
|
+
* `hot.dispose(cb)`: Provide a dispose function for when this module is expected to be accepted by others.
|
|
647
|
+
* `hot.data`: Shared data object between hot reload instances.
|
|
648
|
+
* `hot.invalidate()`: Fully invalidate the current module, without accepting. Can be called within accept itself.
|
|
649
|
+
|
|
650
|
+
To trigger a hot reload, call the `importShim.hotReload(url)` API with the URL of the module that has changed. All of CSS, JSON, Wasm and TypeScript imports are supported in hot reloading.
|
|
651
|
+
|
|
652
|
+
This hot reload API can then be attached to a Web Socket, Server Side Events emitter or any other event source to provide a native hot reloading development environment.
|
|
653
|
+
|
|
579
654
|
### Module Workers
|
|
580
655
|
|
|
581
656
|
ES Module Shims can be used in module workers in browsers that provide dynamic import in worker environments, which at the moment are Chrome(80+), Edge(80+), Firefox(~113+) and Safari(15+).
|
|
@@ -615,6 +690,7 @@ Provide a `esmsInitOptions` on the global scope before `es-module-shims` is load
|
|
|
615
690
|
* [enforceIntegrity](#enforce-integrity)
|
|
616
691
|
* [fetch](#fetch-hook)
|
|
617
692
|
* [mapOverrides](#overriding-import-map-entries)
|
|
693
|
+
* [nativePassthrough](#native-passthrough)
|
|
618
694
|
* [modulepreload](#modulepreload)
|
|
619
695
|
* [noLoadEventRetriggers](#no-load-event-retriggers)
|
|
620
696
|
* [globalLoadEventRetrigger](#global-load-event-retrigger)
|
|
@@ -632,7 +708,7 @@ window.esmsInitOptions = {
|
|
|
632
708
|
// Enable Shim Mode
|
|
633
709
|
shimMode: true, // default false
|
|
634
710
|
// Enable newer modules features
|
|
635
|
-
polyfillEnable: ['
|
|
711
|
+
polyfillEnable: ['wasm-module-sources'], // default empty
|
|
636
712
|
// Custom CSP nonce
|
|
637
713
|
nonce: 'n0nce', // default is automatic detection
|
|
638
714
|
// Don't retrigger load events on module scripts (DOMContentLoaded, domready, window 'onload')
|
|
@@ -646,6 +722,9 @@ window.esmsInitOptions = {
|
|
|
646
722
|
enforceIntegrity: true, // default false
|
|
647
723
|
// Permit overrides to import maps
|
|
648
724
|
mapOverrides: true, // default false
|
|
725
|
+
// Whether es-module-shims will defer to the native module loader whenever it can
|
|
726
|
+
// Automatically disabled in hot reloading workflows
|
|
727
|
+
nativePassthrough: false, // default true
|
|
649
728
|
|
|
650
729
|
// -- Hooks --
|
|
651
730
|
// Module load error
|
|
@@ -671,7 +750,7 @@ window.esmsInitOptions = {
|
|
|
671
750
|
<script type="esms-options">
|
|
672
751
|
{
|
|
673
752
|
"shimMode": true,
|
|
674
|
-
"polyfillEnable": ["
|
|
753
|
+
"polyfillEnable": ["wasm-module-sources"],
|
|
675
754
|
"nonce": "n0nce",
|
|
676
755
|
"onpolyfill": "polyfill"
|
|
677
756
|
}
|
|
@@ -700,14 +779,14 @@ DOM `load` events are fired for all `"module-shim"` scripts both for success and
|
|
|
700
779
|
|
|
701
780
|
The `polyfillEnable` option allows enabling polyfill features which are newer and would otherwise result in unnecessary polyfilling in modern browsers that haven't yet updated.
|
|
702
781
|
|
|
703
|
-
This options supports `"
|
|
782
|
+
This options supports `"wasm-modules"`, `"wasm-module-sources"`, `"wasm-module-instances"` and `"import-defer"`.
|
|
704
783
|
|
|
705
|
-
In adddition, the `"all"` option will enable all features
|
|
784
|
+
In adddition, the `"all"` option will enable all features.
|
|
706
785
|
|
|
707
786
|
```html
|
|
708
787
|
<script type="esms-options">
|
|
709
788
|
{
|
|
710
|
-
"polyfillEnable": ["
|
|
789
|
+
"polyfillEnable": ["all"]
|
|
711
790
|
}
|
|
712
791
|
</script>
|
|
713
792
|
```
|
|
@@ -863,6 +942,17 @@ document.body.appendChild(Object.assign(document.createElement('script'), {
|
|
|
863
942
|
|
|
864
943
|
This can be useful for HMR workflows.
|
|
865
944
|
|
|
945
|
+
### Native Passthrough
|
|
946
|
+
|
|
947
|
+
By default, ES Module Shims will always use the native passthrough of calling the native `import()` mechanism to load module graphs, when it has analyzed that that module graph is fully supported in the current environment. This way, the native module registry is fully shared between polyfilled and non-polyfilled graphs,
|
|
948
|
+
and we lean into the native support as much as popssible.
|
|
949
|
+
|
|
950
|
+
In Shim mode, ES Module Shims never uses native pass through regardless of this option - it only applies to polyfill mode.
|
|
951
|
+
|
|
952
|
+
This option is enabled by default, so by turning it off it is possible to ensure that ES Module Shims is rewriting and processing all sources itself.
|
|
953
|
+
|
|
954
|
+
Native passthrough is automatically disabled when using [hot reloading](#hot-reloading).
|
|
955
|
+
|
|
866
956
|
### Hooks
|
|
867
957
|
|
|
868
958
|
#### Polyfill hook
|