es-module-shims 2.5.0 → 2.6.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 CHANGED
@@ -30,7 +30,7 @@ Because we are still using the native module loader the edge cases work out comp
30
30
  Include ES Module Shims with a `async` attribute on the script, then include an import map and module scripts normally:
31
31
 
32
32
  ```html
33
- <script async src="https://ga.jspm.io/npm:es-module-shims@2.5.0/dist/es-module-shims.js"></script>
33
+ <script async src="https://ga.jspm.io/npm:es-module-shims@2.6.0/dist/es-module-shims.js"></script>
34
34
 
35
35
  <!-- https://generator.jspm.io/#U2NhYGBkDM0rySzJSU1hKEpNTC5xMLTQM9Az0C1K1jMAAKFS5w0gAA -->
36
36
  <script type="importmap">
@@ -520,7 +520,7 @@ In addition CSS files need to be served with a valid CSS content type.
520
520
 
521
521
  Implements the [WebAssembly ESM Integration](https://github.com/WebAssembly/esm-integration) spec, including support for source phase imports.
522
522
 
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
+ In shim mode, Wasm modules are always supported. In polyfill mode, Wasm modules require the `polyfillEnable: ['wasm-module-sources']` (or `'wasm-module-instances'` for instance imports) [init option](#polyfill-enable-option).
524
524
 
525
525
  WebAssembly module exports are made available as module exports and WebAssembly module imports will be resolved using the browser module loader.
526
526
 
@@ -686,19 +686,19 @@ const worker = new Worker(getWorkerScriptURL('myEsModule.js'));
686
686
 
687
687
  Provide a `esmsInitOptions` on the global scope before `es-module-shims` is loaded to configure various aspects of the module loading process:
688
688
 
689
- * [polyfillEnable](#polyfill-enable)
689
+ * [polyfillEnable](#polyfill-enable-option)
690
+ * [polyfillDisable](#polyfill-disable-option)
690
691
  * [enforceIntegrity](#enforce-integrity)
691
692
  * [fetch](#fetch-hook)
692
693
  * [mapOverrides](#overriding-import-map-entries)
693
694
  * [nativePassthrough](#native-passthrough)
694
695
  * [modulepreload](#modulepreload)
695
696
  * [noLoadEventRetriggers](#no-load-event-retriggers)
696
- * [globalLoadEventRetrigger](#global-load-event-retrigger)
697
697
  * [nonce](#nonce)
698
698
  * [onerror](#error-hook)
699
699
  * [onpolyfill](#polyfill-hook)
700
700
  * [resolve](#resolve-hook)
701
- * [revokeBlobURLs](#revoke-blob-urls)
701
+ * [source](#source-hook)
702
702
  * [shimMode](#shim-mode-option)
703
703
  * [skip](#skip)
704
704
  * [version](#version)
@@ -710,14 +710,14 @@ window.esmsInitOptions = {
710
710
  shimMode: true, // default false
711
711
  // Enable newer modules features
712
712
  polyfillEnable: ['wasm-module-sources'], // default empty
713
+ // Disable features that are unused
714
+ polyfillDisable: ['css-modules'], // default empty
713
715
  // Custom CSP nonce
714
716
  nonce: 'n0nce', // default is automatic detection
715
717
  // Don't retrigger load events on module scripts (DOMContentLoaded, domready, window 'onload')
716
718
  noLoadEventRetriggers: true, // default false
717
719
  // Skip source analysis of certain URLs for full native passthrough
718
720
  skip: /^https:\/\/cdn\.com/, // defaults to null
719
- // Clean up blob URLs after execution
720
- revokeBlobURLs: true, // default false
721
721
  // Secure mode to not support loading modules without integrity
722
722
  // (integrity is always verified even when disabled though)
723
723
  enforceIntegrity: true, // default false
@@ -734,6 +734,8 @@ window.esmsInitOptions = {
734
734
  onpolyfill: () => {}, // default logs to the console
735
735
  // Hook all module resolutions
736
736
  resolve: (id, parentUrl, resolve) => resolve(id, parentUrl), // default is spec resolution
737
+ // Hook module source loading
738
+ source: (url, options, parentUrl, defaultSourceHook) => ({ type: 'js', source: 'export var p = 5' }),
737
739
  // Hook source fetch function
738
740
  fetch: (url, options) => fetch(url, options), // default is native
739
741
  // Hook import.meta construction
@@ -794,15 +796,27 @@ In adddition, the `"all"` option will enable all features.
794
796
  </script>
795
797
  ```
796
798
 
797
- The above is necessary to enable CSS modules and JSON modules alongside TypeScript type stripping support.
799
+ The reason the `polyfillEnable` option is needed is because ES Module Shims implements a performance optimization where if a browser supports modern modules features to an expected baseline of import maps support, it will skip all polyfill source analysis resulting in full native passthrough performance.
798
800
 
799
- #### Baseline Support Analysis Opt-Out
801
+ ### Pollyfill Disable Option
800
802
 
801
- The reason the `polyfillEnable` option is needed is because ES Module Shims implements a performance optimization where if a browser supports modern modules features to an expected baseline of import maps support, it will skip all polyfill source analysis resulting in full native passthrough performance.
803
+ Conversely to `polyfillEnable` it can be beneficial to dissable unused features where excluding those features from the baseline allows avoiding unnecessary feature detections or unnecessary analysis of module graphs.
804
+
805
+ This option effectively lowers the baseline support allowing wider passthrough cases.
802
806
 
803
- If the application code then tries to use modern features like CSS modules beyond this baseline it won't support those features. As a result all modules features which are considered newer or beyond the recommended baseline require explicit enabling. This common baseline itself will change to track the common future modules baseline supported by this project for each release cycle.
807
+ The supported options currently are just `css-modules` and `json-modules`.
808
+
809
+ For example:
810
+
811
+ ```html
812
+ <script type="esms-options">
813
+ {
814
+ "polyfillDisable": ["css-modules", "json-modules"]
815
+ }
816
+ </script>
817
+ ```
804
818
 
805
- This option can also be set to `true` to entirely disable the native passthrough system and ensure all sources are fetched and analyzed through ES Module Shims. This will still avoid duplicate execution since module graphs are still only reexecuted when they use unsupported native features, but there is a small extra cost in doing the analysis.
819
+ will disable the CSS and JSON feature detections, and lower the baseline passthrough modules support from Chrome 123, Firefox 138 and Safari 17.2 down to Chrome 64, Safari 11.1 and Firefox 67.
806
820
 
807
821
  ### Enforce Integrity
808
822
 
@@ -989,6 +1003,8 @@ Overriding this hook with an empty function will disable the default polyfill lo
989
1003
 
990
1004
  In the above, running in latest Chromium browsers, nothing will be logged, while running in an older browser that does not support newer features like import maps the console log will be output.
991
1005
 
1006
+ > As this hook does not affect execution, it is recommended for use in polyfill mode.
1007
+
992
1008
  #### Error hook
993
1009
 
994
1010
  You can provide a function to handle errors during the module loading process by providing an `onerror` option:
@@ -1002,6 +1018,8 @@ You can provide a function to handle errors during the module loading process by
1002
1018
  <script async src="es-module-shims.js"></script>
1003
1019
  ```
1004
1020
 
1021
+ > As this hook does not affect execution, it is recommended for use in polyfill mode.
1022
+
1005
1023
  #### Import Hook
1006
1024
 
1007
1025
  The import hook is supported for both shim and polyfill modes and provides an async hook which can ensure any necessary work is done before a top-level module import or dynamic `import()` starts further processing.
@@ -1019,15 +1037,12 @@ The import hook is supported for both shim and polyfill modes and provides an as
1019
1037
  </script>
1020
1038
  ```
1021
1039
 
1040
+ > It is usually recommended to use shim mode with module customization hooks. When the resolve hook is enabled in polyfill mode (or any other hooks), native passthrough will be disabled and modules may be executed twice if they correctly execute without the hook.
1041
+
1022
1042
  #### Resolve Hook
1023
1043
 
1024
1044
  The resolve hook is supported for both shim and polyfill modes and allows full customization of the resolver, while still having access to the original resolve function.
1025
1045
 
1026
- Note that in polyfill mode the resolve hook may not be called for all modules when native passthrough is occurring and that it still will not affect
1027
- the native passthrough executions.
1028
-
1029
- If the resolve hook should apply for all modules in the entire module graph, make sure to set `polyfillEnable: true` to [disable the baseline support analysis opt-out](#baseline-support-analysis-opt-out).
1030
-
1031
1046
  ```js
1032
1047
  <script>
1033
1048
  window.esmsInitOptions = {
@@ -1043,6 +1058,59 @@ If the resolve hook should apply for all modules in the entire module graph, mak
1043
1058
  </script>
1044
1059
  ```
1045
1060
 
1061
+ > It is usually recommended to use shim mode with module customization hooks. When the resolve hook is enabled in polyfill mode (or any other hooks), native passthrough will be disabled and modules may be executed twice if they correctly execute without the hook.
1062
+
1063
+ #### Source Hook
1064
+
1065
+ The source hook used to obtain the module source for a given URL, allowing for the implementation
1066
+ of virtual module sources.
1067
+
1068
+ Note that only valid fetch scheme URLs are supported - `http:` / `https:` / `data:` / `blob:` / `file:`.
1069
+ `https:` or `file:` is therefore recommended for virtual module paths.
1070
+
1071
+ For example:
1072
+
1073
+ ```html
1074
+ <script>
1075
+ const virtualFs = {
1076
+ 'index.js': `import './src/dep.js';`,
1077
+ 'src/dep.js': 'console.log("virtual source execution!")'
1078
+ };
1079
+ esmsInitOptions = {
1080
+ source (url, fetchOpts, parent, defaultSourceHook) {
1081
+ // Only virtualize sources under the URL file:///virtual-pkg/ (i.e. via
1082
+ // `import 'file:///virtual-pkg/index.js'`.
1083
+ if (!url.startsWith('file:///virtual-pkg/')) return defaultSourceHook(url, fetchOpts, parent);
1084
+
1085
+ // Strip the query string prefix for hot reloading workflow support
1086
+ const versionQueryParam = url.match(/\?v=\d+$/);
1087
+ if (versionQueryParam) url = url.slice(0, -versionQueryParam[0].length);
1088
+
1089
+ // Lookup the virtual source from the virtual filesystem and return if found
1090
+ const virtualSource = virtualFs[url.slice('file:///virtual-pkg/'.length)];
1091
+ if (!virtualSource) throw new Error(`Virtual module ${url} not found, imported from ${parent}`);
1092
+ return {
1093
+ type: 'js',
1094
+ source: virtualSource
1095
+ };
1096
+ }
1097
+ };
1098
+ </script>
1099
+ ```
1100
+
1101
+ For support in hot reloading workflows, note that the ?v={Number} version query
1102
+ string suffix will be passed so needs to be checked and removed if applicable.
1103
+
1104
+ For JS, CSS, JSON and TypeScript, it provides the source text string.
1105
+ For WebAssembly, it provides the compiled WebAssembly.Module record.
1106
+
1107
+ The default implementation uses globalThis.fetch to obtain the response and then
1108
+ the 'content-type' MIME type header to infer the module type, per HTML semantics.
1109
+
1110
+ URL may be returned differently from the request URL because responseURL
1111
+ is allowed to be distinct from requestURL in the module system even thoough
1112
+ requestURL is used as the registry key only.
1113
+
1046
1114
  #### Meta Hook
1047
1115
 
1048
1116
  The meta hook allows customizing the `import.meta` object in each module scope.
@@ -1069,6 +1137,8 @@ import assert from 'assert';
1069
1137
  assert.ok(import.meta.custom.startsWith('custom value'));
1070
1138
  ```
1071
1139
 
1140
+ > It is usually recommended to use shim mode with module customization hooks. When the resolve hook is enabled in polyfill mode (or any other hooks), native passthrough will be disabled and modules may be executed twice if they correctly execute without the hook.
1141
+
1072
1142
  #### Fetch Hook
1073
1143
 
1074
1144
  The fetch hook is supported for shim mode only.
@@ -1126,6 +1196,8 @@ window.esmsInitOptions = {
1126
1196
  }
1127
1197
  ```
1128
1198
 
1199
+ > It is usually recommended to use shim mode with module customization hooks. When the resolve hook is enabled in polyfill mode (or any other hooks), native passthrough will be disabled and modules may be executed twice if they correctly execute without the hook.
1200
+
1129
1201
  ## Implementation Details
1130
1202
 
1131
1203
  ### Import Rewriting