es-module-shims 1.6.0 → 1.6.1
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 +37 -21
- package/dist/es-module-shims.js +3 -3
- package/dist/es-module-shims.wasm.js +3 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -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.6.
|
|
32
|
+
<script async src="https://ga.jspm.io/npm:es-module-shims@1.6.1/dist/es-module-shims.js"></script>
|
|
33
33
|
|
|
34
34
|
<!-- https://generator.jspm.io/#U2NhYGBkDM0rySzJSU1hKEpNTC5xMLTQM9Az0C1K1jMAAKFS5w0gAA -->
|
|
35
35
|
<script type="importmap">
|
|
@@ -62,21 +62,15 @@ This execution failure is a feature - it avoids the polyfill causing double exec
|
|
|
62
62
|
|
|
63
63
|
This is because the polyfill cannot disable the native loader - instead it will only execute modules that would otherwise fail resolving or parsing to avoid duplicate fetches or executions that would cause performance and reliability issues.
|
|
64
64
|
|
|
65
|
-
|
|
65
|
+
## Polyfill Mode
|
|
66
66
|
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
In shim mode, only the above `importmap-shim` and `module-shim` tags will be parsed and executed by ES Module Shims.
|
|
70
|
-
|
|
71
|
-
Shim mode also provides some additional features that aren't yet natively supported such as supporting multiple import maps, [external import maps](#external-import-maps) with a `"src"` attribute, [dynamically injecting import maps](#dynamic-import-maps), and [reading current import map state](#reading-current-import-map-state), which can be useful in certain applications.
|
|
72
|
-
|
|
73
|
-
## Polyfill Mode Details
|
|
67
|
+
The typical polyfill scenario is to have a static import to a bare specifier fail, which will then be polyfilled by ES Module Shims.
|
|
74
68
|
|
|
75
69
|
In polyfill mode, feature detections are performed for ES modules features. In browsers with full feature support no further processing is done.
|
|
76
70
|
|
|
77
71
|
In browsers with variable feature support, sources are analyzed with module specifiers rewritten using the very fast Wasm / asm.js lexer while sharing the source network fetch cache with the native loader.
|
|
78
72
|
|
|
79
|
-
|
|
73
|
+
### Polyfill Features
|
|
80
74
|
|
|
81
75
|
The current default native baseline for the ES module shims polyfill mode is browsers supporting import maps.
|
|
82
76
|
|
|
@@ -90,9 +84,9 @@ window.esmsInitOptions = { polyfillEnable: ['css-modules', 'json-modules'] }
|
|
|
90
84
|
|
|
91
85
|
To verify when the polyfill is actively engaging as opposed to relying on the native loader, [a `polyfill` hook](#polyfill-hook) is also provided.
|
|
92
86
|
|
|
93
|
-
|
|
87
|
+
### Polyfill Edge Case: Dynamic Import
|
|
94
88
|
|
|
95
|
-
|
|
89
|
+
Module feature errors that are not _static errors_ but rather _runtime errors_ cause edge cases with the polyfill feature detection. For example when using dynamic imports:
|
|
96
90
|
|
|
97
91
|
```html
|
|
98
92
|
<script type="module">
|
|
@@ -130,11 +124,11 @@ If a static failure is not possible and dynamic import must be used, rather use
|
|
|
130
124
|
|
|
131
125
|
`importShim` will automatically pass-through to native dynamic import or polyfill as necessary, just like it does for script tags.
|
|
132
126
|
|
|
133
|
-
|
|
127
|
+
### Polyfill Edge Case: Instance Sharing
|
|
134
128
|
|
|
135
129
|
When running in polyfill mode, it can be thought of that are effectively two loaders running on the page - the ES Module Shims polyfill loader, and the native loader.
|
|
136
130
|
|
|
137
|
-
Note that instances are not shared between these loaders for consistency and performance.
|
|
131
|
+
Note that instances are not shared between these loaders for consistency and performance, since some browsers do not properly share the fetch cache and native loader cache resulting in a double fetch which would be inefficient.
|
|
138
132
|
|
|
139
133
|
As a result, if you have two module graphs - one native and one polyfilled, they will not share the same dependency instance, for example:
|
|
140
134
|
|
|
@@ -154,15 +148,29 @@ import 'dep';
|
|
|
154
148
|
</script>
|
|
155
149
|
```
|
|
156
150
|
|
|
157
|
-
|
|
151
|
+
```dep
|
|
152
|
+
console.log('DEP');
|
|
153
|
+
```
|
|
158
154
|
|
|
159
|
-
ES Module Shims will pick up on the second import and reexecute `/dep.js
|
|
155
|
+
When polyfilling import maps, ES Module Shims will pick up on the second import failure and reexecute `/dep.js` as a new instance, logging `"DEP"` twice.
|
|
160
156
|
|
|
161
157
|
For this reason it is important to always ensure all modules hit the polyfill path, either by having all graphs use import maps at the top-level, or via `importShim` directly.
|
|
162
158
|
|
|
163
|
-
|
|
159
|
+
If you really need to support instance sharing with the native loader, a useful workaround is to use the [`skip` option](#skip) to list modules which should always be loaded via the native loader:
|
|
164
160
|
|
|
165
|
-
|
|
161
|
+
```html
|
|
162
|
+
<script type="esms-options">
|
|
163
|
+
{
|
|
164
|
+
"skip": ["/dep.js"]
|
|
165
|
+
}
|
|
166
|
+
</script>
|
|
167
|
+
```
|
|
168
|
+
|
|
169
|
+
The above would then fully cause dependency module instance to be shared between ES Module Shims and the native loader, with the polyfill then logging `"DEP"` only once.
|
|
170
|
+
|
|
171
|
+
#### No Shim Scripts
|
|
172
|
+
|
|
173
|
+
If the polyfill is analyzing or applying to a module script that doesn't need to or shouldn't be polyfilled, adding the `"noshim"` attribute to the script tag will ensure that ES Module Shims ignores processing this script entirely:
|
|
166
174
|
|
|
167
175
|
```html
|
|
168
176
|
<script type="module" noshim>
|
|
@@ -170,6 +178,14 @@ Adding the `"noshim"` attribute to the script tag will also ensure that ES Modul
|
|
|
170
178
|
</script>
|
|
171
179
|
```
|
|
172
180
|
|
|
181
|
+
## Shim Mode
|
|
182
|
+
|
|
183
|
+
Shim mode is an alternative to polyfill mode and doesn't rely on native modules erroring - instead it is triggered by the existence of any `<script type="importmap-shim">` or `<script type="module-shim">`, or when explicitly setting the [`shimMode` init option](#shim-mode-option).
|
|
184
|
+
|
|
185
|
+
In shim mode, only the above `importmap-shim` and `module-shim` tags will be parsed and executed by ES Module Shims.
|
|
186
|
+
|
|
187
|
+
Shim mode also provides some additional features that aren't yet natively supported such as supporting multiple import maps, [external import maps](#external-import-maps) with a `"src"` attribute, [dynamically injecting import maps](#dynamic-import-maps), and [reading current import map state](#reading-current-import-map-state), which can be useful in certain applications.
|
|
188
|
+
|
|
173
189
|
## Benchmarks
|
|
174
190
|
|
|
175
191
|
ES Module Shims is designed for production performance. A [comprehensive benchmark suite](bench/README.md) tracks multiple loading scenarios for the project.
|
|
@@ -469,7 +485,7 @@ Provide a `esmsInitOptions` on the global scope before `es-module-shims` is load
|
|
|
469
485
|
* [enforceIntegrity](#enforce-integrity)
|
|
470
486
|
* [nonce](#nonce)
|
|
471
487
|
* [noLoadEventRetriggers](#no-load-event-retriggers)
|
|
472
|
-
* [skip](#skip
|
|
488
|
+
* [skip](#skip)
|
|
473
489
|
* [onerror](#error-hook)
|
|
474
490
|
* [onpolyfill](#polyfill-hook)
|
|
475
491
|
* [resolve](#resolve-hook)
|
|
@@ -622,9 +638,9 @@ In such a case, this double event firing can be disabled with the `noLoadEventRe
|
|
|
622
638
|
<script async src="es-module-shims.js"></script>
|
|
623
639
|
```
|
|
624
640
|
|
|
625
|
-
### Skip
|
|
641
|
+
### Skip
|
|
626
642
|
|
|
627
|
-
When loading modules that you know will only use baseline modules features, it is possible to set a rule to explicitly opt-out modules from
|
|
643
|
+
When loading modules that you know will only use baseline modules features, it is possible to set a rule to explicitly opt-out modules from being polyfilled to always load and be referenced through the native loader only. This enables instance sharing with the native loader and also improves performance because those modules then do not need to be processed or transformed at all, so that only local application code is handled and not library code.
|
|
628
644
|
|
|
629
645
|
The `skip` option supports a string regular expression or array of exact module URLs to check:
|
|
630
646
|
|
package/dist/es-module-shims.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* ES Module Shims 1.6.
|
|
1
|
+
/* ES Module Shims 1.6.1 */
|
|
2
2
|
(function () {
|
|
3
3
|
|
|
4
4
|
const hasWindow = typeof window !== 'undefined';
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
else if (typeof skip === 'string') {
|
|
60
60
|
const r = new RegExp(skip);
|
|
61
|
-
skip = s =>
|
|
61
|
+
skip = s => r.test(s);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const eoop = err => setTimeout(() => { throw err });
|
|
@@ -786,7 +786,7 @@
|
|
|
786
786
|
if (b && (!supportsImportMaps || importMapSrcOrLazy))
|
|
787
787
|
load.n = true;
|
|
788
788
|
if (d !== -1) return;
|
|
789
|
-
if (skip && skip
|
|
789
|
+
if (skip && skip(r)) return { b: r };
|
|
790
790
|
if (childFetchOpts.integrity)
|
|
791
791
|
childFetchOpts = Object.assign({}, childFetchOpts, { integrity: undefined });
|
|
792
792
|
return getOrCreateLoad(r, childFetchOpts, load.r).f;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
/* ES Module Shims Wasm 1.6.
|
|
1
|
+
/* ES Module Shims Wasm 1.6.1 */
|
|
2
2
|
(function () {
|
|
3
3
|
|
|
4
4
|
const hasWindow = typeof window !== 'undefined';
|
|
@@ -58,7 +58,7 @@
|
|
|
58
58
|
}
|
|
59
59
|
else if (typeof skip === 'string') {
|
|
60
60
|
const r = new RegExp(skip);
|
|
61
|
-
skip = s =>
|
|
61
|
+
skip = s => r.test(s);
|
|
62
62
|
}
|
|
63
63
|
|
|
64
64
|
const eoop = err => setTimeout(() => { throw err });
|
|
@@ -786,7 +786,7 @@
|
|
|
786
786
|
if (b && (!supportsImportMaps || importMapSrcOrLazy))
|
|
787
787
|
load.n = true;
|
|
788
788
|
if (d !== -1) return;
|
|
789
|
-
if (skip && skip
|
|
789
|
+
if (skip && skip(r)) return { b: r };
|
|
790
790
|
if (childFetchOpts.integrity)
|
|
791
791
|
childFetchOpts = Object.assign({}, childFetchOpts, { integrity: undefined });
|
|
792
792
|
return getOrCreateLoad(r, childFetchOpts, load.r).f;
|