Skip to content

Commit

Permalink
feat: explicit globalLoadEventRetrigger option (#414)
Browse files Browse the repository at this point in the history
  • Loading branch information
guybedford committed Mar 28, 2024
1 parent e890fcb commit fe3630a
Show file tree
Hide file tree
Showing 4 changed files with 19 additions and 7 deletions.
20 changes: 15 additions & 5 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -243,7 +243,7 @@ Browser compatibility **without** ES Module Shims:
| [CSS Modules](#css-modules) | 95+ | :x: | :x: |
| [Wasm Modules](#wasm-modules) | :x: | :x: | :x: |
| [import.meta.resolve](#resolve) | :x: | :x: | :x: |
| [Module Workers](#module-workers) | ~68+ | :x: | :x: |
| [Module Workers](#module-workers) | ~68+ | ~113+ | 15+ |
| Top-Level Await | 89+ | 89+ | 15+ |

* ❕<sup>1</sup>: On module redirects, Safari returns the request URL in `import.meta.url` instead of the response URL as per the spec.
Expand Down Expand Up @@ -490,7 +490,7 @@ Node.js also implements a similar API, although it's in the process of shifting

### Module Workers

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+) and Safari(15+).
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+).

By default, when there is no DOM present, ES Module Shims will switch into shim mode. An example of ES Module Shims usage through shim mode in web workers is provided below:

Expand Down Expand Up @@ -528,6 +528,7 @@ Provide a `esmsInitOptions` on the global scope before `es-module-shims` is load
* [mapOverrides](#overriding-import-map-entries)
* [modulepreload](#modulepreload)
* [noLoadEventRetriggers](#no-load-event-retriggers)
* [globalLoadEventRetrigger](#global-load-event-retrigger)
* [nonce](#nonce)
* [onerror](#error-hook)
* [onpolyfill](#polyfill-hook)
Expand All @@ -546,8 +547,10 @@ window.esmsInitOptions = {
polyfillEnable: ['css-modules', 'json-modules'], // default empty
// Custom CSP nonce
nonce: 'n0nce', // default is automatic detection
// Don't retrigger load events on module scripts
// Don't retrigger load events on module scripts (DOMContentLoaded, domready)
noLoadEventRetriggers: true, // default false
// Retrigger window 'load' event (will be combined into load event above on next major)
globalLoadEventRetrigger: true, // default false
// Skip source analysis of certain URLs for full native passthrough
skip: /^https:\/\/cdn\.com/, // defaults to null
// Clean up blob URLs after execution
Expand Down Expand Up @@ -667,7 +670,7 @@ Alternatively, add a `blob:` URL policy with the CSP build to get CSP compatibil

### No Load Event Retriggers

Because of the extra processing done by ES Module Shims it is possible for static module scripts to execute after the `load`, `DOMContentLoaded` or `readystatechange` events they expect, which can cause missed attachment.
Because of the extra processing done by ES Module Shims it is possible for static module scripts to execute after the `DOMContentLoaded` or `readystatechange` events they expect, which can cause missed attachment.

In addition, script elements will also have their load events refired when polyfilled.

Expand All @@ -678,13 +681,20 @@ In such a case, this double event firing can be disabled with the `noLoadEventRe
```js
<script type="esms-options">
{
// do not re-trigger DOM events (load, onreadystatechange, DOMContentLoaded)
// do not re-trigger DOM events (onreadystatechange, DOMContentLoaded)
"noLoadEventRetriggers": true
}
</script>
<script async src="es-module-shims.js"></script>
```

### Global Load Event Retrigger

In ES Module Shims 1.x, load event retriggers only apply to `DOMContentLoaded` and `readystatechange` and not to the window `load` event.
To enable the window / worker `'load'` event, set `globalLoadEventRetrigger: true`.

In the next major version, this will be the default for load events, at which point only `noLoadEventRetriggers` will remain.

### Skip

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.
Expand Down
1 change: 1 addition & 0 deletions resources/testharness.js
Original file line number Diff line number Diff line change
Expand Up @@ -4977,6 +4977,7 @@ table#results span.actual {\

// ADDITIONS:
window.esmsInitOptions = {
globalLoadEventRetrigger: true,
polyfillEnable: ['wasm-modules', 'source-phase']
};
document.write('<' + 'script src="../dist/es-module-shims.js"></script>' + '<' + `script>
Expand Down
2 changes: 1 addition & 1 deletion src/env.js
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ if (!nonce && hasDocument) {

export const onerror = globalHook(esmsInitOptions.onerror || noop);

export const { revokeBlobURLs, noLoadEventRetriggers, enforceIntegrity } = esmsInitOptions;
export const { revokeBlobURLs, noLoadEventRetriggers, globalLoadEventRetrigger, enforceIntegrity } = esmsInitOptions;

function globalHook (name) {
return typeof name === 'string' ? self[name] : name;
Expand Down
3 changes: 2 additions & 1 deletion src/es-module-shims.js
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@ import {
skip,
revokeBlobURLs,
noLoadEventRetriggers,
globalLoadEventRetrigger,
cssModulesEnabled,
jsonModulesEnabled,
wasmModulesEnabled,
Expand Down Expand Up @@ -616,7 +617,7 @@ function domContentLoadedCheck () {
}
let loadCnt = 1;
function loadCheck () {
if (--loadCnt === 0 && !noLoadEventRetriggers && (shimMode || !baselinePassthrough)) {
if (--loadCnt === 0 && globalLoadEventRetrigger && !noLoadEventRetriggers && (shimMode || !baselinePassthrough)) {
if (self.ESMS_DEBUG) console.info(`es-module-shims: load refire`);
window.dispatchEvent(new Event('load'));
}
Expand Down

0 comments on commit fe3630a

Please sign in to comment.