interface ESMSInitOptions { /** * Enable Shim Mode, where only * * and * * are supported and the native loader is not used directly (no {@link nativePassthrough}). */ shimMode?: boolean; /** * Enable hot reloading */ hotReload?: boolean; /** * Set the hot reload refresh interval in ms */ hotReloadInterval?: number; /** * Enable polyfill features. * * Currently supports: * - 'wasm-modules': Both 'wasm-module-sources' and 'wasm-module-instances' * - 'wasm-module-sources': Support for Wasm source phase imports (import source mod from './mod.wasm') * - 'wasm-module-instances': Support for Wasm instance phase imports (import * as mod from './mod.wasm') * - 'import-defer': Support for import defer syntax (import defer * as ns from './foo.js') */ polyfillEnable?: Array<'wasm-modules' | 'wasm-module-instances' | 'wasm-module-sources' | 'import-defer' | 'all'>; /** * Disable polyfill features: * - 'css-modules': CSS Module imports of the form `import styles from './source.css' with { type: 'css' }` * - 'json-modules': JSON Module imports of the form `import styles from './source.css' with { type: 'css' }` * * These features are enabled by default but only supported in Chrome 123+, so that disabling these features * allows ES Module Shims to avoid unnecessary feature detections and module analysis, * so this will ensure {@link nativePassthrough} for Chrome 89+, Firefox 108+, Safari 16.4+ */ polyfillDisable?: Array<'css-modules' | 'json-modules'>; /** * @default true * * By default, native passthrough is enabled so that modules will be entirely loaded through the native loader * when it is known to be safe to do so. This happens when: * * 1. Polyfill mode is enabled (which is by default, unless shim mode is explicitly enabled) * 2. No hot reloading or hooks options are in use * 3. Then either of: * a) The browser supports the minimum baseline features expected by ES Module Shims * (either by default, or as customized via polyfillEnable / polyfillDisable) * b) Or if the browser does not support the minimum baseline features, ES Module Shims * will analyze the entire subgraph of modules and still use passthrough after that analysis * if every module down the graph is known to be natively supported without causing a static error on load. * * Setting this option to false can avoid some potential double fetching on the polyfill path when modules are * analyzed for support, since the native loader cache is not always shared with the fetch cache in some browser. * * In addition dynamic import() not being polyfilled can also be worked around by using this option since it will * replace all dynamic import() expressions with an importShim() expression by using the polyfill loader instead * of the native loader. * * This option is therefore serving two purposes - firstly to easily disable internally in the case of hot reloading * and hooks, and secondly to allow this kind customization in the case of dynamic import or performance cases. */ nativePassthrough?: boolean; /** * #### Version * * Useful when there are multiple instances of ES Module Shims for whatever reason * interacting in an application. * * When set, ES Module Shims will early exit if its own version is not the expected version. * Note that this feature is only supported from version 2.4.0 upwards. */ version?: string; /** * #### Enforce Integrity * * Set to *true* to enable secure mode to not support loading modules without integrity (integrity is always verified though). * */ enforceIntegrity?: boolean; /** * Nonce for CSP compatibility * * When set, feature detection scripts that run in a separate feature detection * iframe will use this nonce to ensure CSP compatibility. */ nonce?: boolean; /** * Disable retriggering of document readystate, DOMContentLoaded and the window load event. * * ES Module Shims will re-trigger these events because normally * runs under static defer semantics and results in delaying these events until it completes. * * When modules are polyfilled, the top-level load will first complete and the events will trigger * before the modules have run, which may result in missing attachments. * * By retriggering these events we ensure later attachment. * * The consequence of this approach is that it does assume that attachments are idempotent, and in * where that is not the case this can result in duplicate DOM injections or attachments. * * This option can therefore be used to disable this feature when those problems arise. */ noLoadEventRetriggers?: boolean; /** * * 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 any analysis and rewriting, effectively forcing {@link nativePassthrough} * only for these modules and their dependencies. This improves performance because * those modules then do not need to be processed or transformed at all, so that * e.g. only local application code is handled and not library code. * * This can be configured by setting the importShim.skip URL regular * expression: * * ```js * importShim.skip = /^https:\/\/cdn\.com/; * ``` * */ skip?: RegExp | string[] | string; /** * #### Error hook * * Register a callback for any ES Module Shims module errors. * */ onerror?: (e: any) => any; /** * #### Polyfill hook * * Register a callback invoked when polyfill mode first engages. * */ onpolyfill?: () => void; /** * #### Resolve Hook * * Only supported in Shim Mode. * * Provide a custom resolver function. */ resolve?: (id: string, parentUrl: string, parentResolve: (id: string, parentUrl: string) => string) => string; /** * #### Fetch Hook * * Only supported in Shim Mode. * * > Stability: Non-spec feature * * This is provided as a convenience feature since the pipeline handles * the same data URL rewriting and circular handling of the module graph * that applies when trying to implement any module transform system. * * The ES Module Shims fetch hook can be used to implement transform * plugins. * * For example: * * ```js * importShim.fetch = async function (url) { * const response = await fetch(url); * if (response.url.endsWith('.ts')) { * const source = await response.body(); * const transformed = tsCompile(source); * return new Response(new Blob([transformed], { type: 'application/javascript' })); * } * return response; * }; * ``` * * Because the dependency analysis applies by ES Module Shims takes care * of ensuring all dependencies run through the same fetch hook, the above * is all that is needed to implement custom plugins. * * Streaming support is also provided, for example here is a hook with * streaming support for JSON: * * ```js * importShim.fetch = async function (url) { * const response = await fetch(url); * if (!response.ok) * throw new Error(`${response.status} ${response.statusText} ${response.url}`); * const contentType = response.headers.get('content-type'); * if (!/^application\/json($|;)/.test(contentType)) * return response; * const reader = response.body.getReader(); * return new Response(new ReadableStream({ * async start (controller) { * let done, value; * controller.enqueue(new Uint8Array([...'export default '].map(c => c.charCodeAt(0)))); * while (({ done, value } = await reader.read()) && !done) { * controller.enqueue(value); * } * controller.close(); * } * }), { * status: 200, * headers: { * "Content-Type": "application/javascript" * } * }); * } * ``` * * @deprecated use the {@link source} hook instead. */ fetch?: (input: RequestInfo, init?: RequestInit) => Promise; /** * #### Source Hook * * Source hook used to obtain the module source for a given URL. * Can be used to implement virtual modules. * * Note that only valid fetch scheme URLs are supported - http(s): / data: / blob: / file: * * https: or file: is therefore recommended for virtual module paths. * * @example * ``` * * ``` * * For support in hot reloading workflows, note that the ?v={Number} version query * string suffix will be passed so needs to be checked and removed if applicable. * * For JS, CSS, JSON and TypeScript, it provides the source text string. * For WebAssembly, it provides the compiled WebAssembly.Module record. * * The default implementation uses globalThis.fetch to obtain the response and then * the 'content-type' MIME type header to infer the module type, per HTML semantics. * * URL may be returned differently from the request URL because responseURL * is allowed to be distinct from requestURL in the module system even thoough * requestURL is used as the registry key only. * * @param url The URL of the module source being requested * @param fetchOpts Any custom fetch options (including integrity) * @param parent The parent importer URL for debug messages * @param defaultSourceHook The default source hook, to be used as the fallback */ source?: ( url: string, fetchOpts: RequestInit, parent: string, defaultSourceHook: ( url, fetchOptions, parent ) => Promise<{ url: string; type: 'js' | 'wasm' | 'css' | 'json' | 'ts'; source: string | WebAssembly.Module; }> ) => Promise<{ url?: string | undefined; type: 'js' | 'wasm' | 'css' | 'json' | 'ts'; source: string | WebAssembly.Module; }>; /** * #### Revoke Blob URLs * * Set to *true* to cleanup blob URLs from memory after execution. * Can cost some compute time for large loads. * * @deprecated this option is now on by default and will be removed in a future version. */ revokeBlobURLs?: boolean; /** * #### Map Overrides * * Set to *true* to permit overrides to import maps. * */ mapOverrides?: boolean; /** * #### Meta hook * * Register a callback for import.meta construction. * * @param meta The import.meta object to mutate * @param url The URL of the module */ meta?: (meta: any, url: string) => void; /** * #### On import hook * * Register a callback for top-level imports. * * @param url The top-level module being imported * @param fetchOptions the {@link RequestInit} fetch options to used, to also be used for dependencies as well */ onimport?: (url: string, fetchOptions: RequestInit, parentUrl: string) => void; } interface ImportMap { imports: Record; scopes: Record>; integrity: Record; } /** * Dynamic import(...) within any modules loaded will be rewritten as * importShim(...) automatically providing full support for all es-module-shims * features through dynamic import. * * To load code dynamically (say from the browser console), importShim can be * called similarly: * * ```js * importShim('/path/to/module.js').then(x => console.log(x)); * ``` */ declare function importShim( specifier: string, parentUrl?: string ): Promise<{ default: Default } & Exports>; declare namespace importShim { const resolve: (id: string, parentURL?: string) => string; const addImportMap: (importMap: Partial) => void; const getImportMap: () => ImportMap; const hotReload: ((url: string) => boolean) | undefined; const version: string; } interface Window { esmsInitOptions?: ESMSInitOptions; importShim: typeof importShim; }