I've recently been experimenting with ES modules for service workers, now supported in pre-stable versions of Chrome and Safari.
I've found that without a way to feature detect support, writing code that's backwards compatible can be awkward, and in some browsers, less performant.
Roughly, this is the registration snippet that I was trying out:
async function registerSW() {
try {
await navigator.serviceWorker.register('es-module-sw.js', {
type: 'module',
});
} catch(error) {
await navigator.serviceWorker.register('import-scripts-sw.js');
}
}
Pre-stable versions of Chrome and Safari will successfully run the first registration, and the current stable versions of Chrome will raise an exception immediately because it "knows" that type: 'module' isn't supported.
However, the current stable versions of Firefox and Safari will download and attempt to execute the ES module flavor of service worker, and only raise an exception when there's a syntax error due to the usage of ES module imports. The fallback logic in the catch can successfully register a classic version of the service worker that uses importScripts(), but not until after spending the bandwidth and time needed to download and parse something that we should know in advance won't work.
Am I missing something already implemented in all browsers that would make it possible to feature-detect type: 'module' support ahead of time? If not, consider this a feature request to add in a property, presumably exposed on the ServiceWorkerContainer, that could answer the "are ES module service workers supported?" question in advance of attempting the registration. Either a boolean that was true when ES modules are supported, or alternatively, a list of supported type values, set in this case to ['classic', 'module'], if we think that there might be additional types that will be added in the future.
I've recently been experimenting with ES modules for service workers, now supported in pre-stable versions of Chrome and Safari.
I've found that without a way to feature detect support, writing code that's backwards compatible can be awkward, and in some browsers, less performant.
Roughly, this is the registration snippet that I was trying out:
Pre-stable versions of Chrome and Safari will successfully run the first registration, and the current stable versions of Chrome will raise an exception immediately because it "knows" that
type: 'module'isn't supported.However, the current stable versions of Firefox and Safari will download and attempt to execute the ES module flavor of service worker, and only raise an exception when there's a syntax error due to the usage of ES module imports. The fallback logic in the
catchcan successfully register a classic version of the service worker that usesimportScripts(), but not until after spending the bandwidth and time needed to download and parse something that we should know in advance won't work.Am I missing something already implemented in all browsers that would make it possible to feature-detect
type: 'module'support ahead of time? If not, consider this a feature request to add in a property, presumably exposed on theServiceWorkerContainer, that could answer the "are ES module service workers supported?" question in advance of attempting the registration. Either a boolean that wastruewhen ES modules are supported, or alternatively, a list of supportedtypevalues, set in this case to['classic', 'module'], if we think that there might be additionaltypes that will be added in the future.