tooling.report

feature

Between new worker type

Can entry bundles be created for other contexts?

Person in shorts with blue hair walking left

Introduction

There are a number of different scenarios where it's necessary to bundle some code separately for a different JavaScript context. Web Workers are perhaps the most popular case, however the same underlying functionality is necessary in order to bundle code for use in Service Workers, Module Workers and Worklets. Since many tools apply special handling to Web Workers, it can take time to catch up with new worker variants.

The Test

This test checks that it's possible to reuse the underlying functionality of code splitting between workers for new or custom context types, without having to wait for a new release of the build tool. Effectively, it tests that it's possible to create an entry point and obtain its bundled URL at runtime.

index.js

import workerURL from 'get-worker-url-somehow';
import { logCaps } from './utils.js';

new InterestingNewWorkerType(workerURL);
logCaps('This is index');

worker.js

import { logCaps } from './utils.js';
logCaps('This is worker');

utils.js

export function logCaps(msg) {
  console.log(msg.toUpperCase());
}

The result of bundling these modules should be two or three files: one bundle for the main thread and one for the worker thread, and ideally a shared bundle for the logCaps utility method that can be used by both bundles.

Conclusion

browserify

As Browserify does not support loading code dynamically, it cannot provide a JS file as a URL.

Issues

  • N/A
parcel

Parcel supports the worklet: scheme to get a URL to a worklet file. This can be used to build for a new worklet type. It also automatically detects the CSS.paintWorklet.addModule(new URL('worklet.js', import.meta.url)) syntax for paint worklets, along with standard new Worker() and navigator.serviceWorker.register.

This is a partial pass because the shared module utils.js is not currently split into a separate bundle.

rollup

rollup-plugin-off-main-thread allows you to import a JS file as a worker and returns the URL. Rollup makes this simple via its emitFile method which lets you create a new chunk dynamically and get its eventual URL. Since workers are just another entry point, this primitive is a perfect and extensible fit.

webpack

It's possible to extend webpack's integrated Web Worker support to new or custom Worker types, as long as importScripts() is supported.

This makes it possible to bundle code for use in new worker-like environments like Service Worker. Code splitting between the "host" and "child" sets of bundles is also supported. Currently, bundles are loaded using importScripts(), which means code splitting cannot be used with Module Workers or Worklets.