Web worker support
Cloudpack provides built-in support for web workers with import maps, allowing you to use modern ES modules and the same bundled dependencies in your worker code as in your main application.
Overview
Web workers in Cloudpack work by automatically shimming import maps and providing the necessary polyfills to enable ES module imports within worker contexts. This allows you to:
- Use the same bundled packages in workers as in your main application
- Import modules directly in worker code
- Maintain consistent dependency versions across main thread and worker threads
- Leverage Cloudpack's bundling and caching for worker scripts
Enabling web worker support
Web worker support is enabled by default through the enableModuleWorkers feature flag:
{
"$schema": "https://unpkg.com/@ms-cloudpack/cli/schema/AppConfig.json",
"features": {
"enableModuleWorkers": true
}
}How it works
When a worker script is requested, Cloudpack automatically:
- Detects worker files - Identifies when a bundled file is intended to be used as a Web Worker
- Injects import map shim - Adds the
es-module-shimslibrary to enable import map support - Provides window polyfills - Shims
window, andprocess.browserfor compatibility - Handles messages - Sets up temporary message handlers to queue messages during worker initialization as it loads asynchronously
- Loads the worker module - Uses
importShim()to load your worker code with full import map support
Basic usage
Worker code example
You can see an example in Cloudpack's onedrive-mock app.
Package configuration
For packages that contain Web Workers, you may need specific bundler configuration:
{
"packageSettings": [
{
"match": "my-worker-package",
"bundler": "rspack"
}
]
}Note: Currently, only webpack and rspack bundlers fully support worker detection through the isWorker flag in bundle results.
Advanced Features
Shared Dependencies
Workers automatically have access to the same import map as your main application, meaning:
// Both main thread and worker can import the same version
import { library } from 'shared-dependency'Window object shimming
Cloudpack provides window object compatibility:
// These all work in workers
console.log(typeof window !== 'undefined') // true
console.log(process.browser) // trueDefine flags
Worker contexts automatically receive the same define flags as your main application:
{
"define": {
"FEATURE_FLAGS.enableNewFeature": true,
"API_ENDPOINT": "https://api.example.com"
}
}// Available in worker code
if (FEATURE_FLAGS.enableNewFeature) {
// Use new feature
}Message queue handling
Cloudpack handles the timing issue where messages might be sent before the worker is fully initialized:
// Messages sent immediately after worker creation are queued
const worker = new Worker('/worker')
worker.postMessage('immediate message') // This won't be lost
// The worker's initialization code handles this automaticallyTroubleshooting
Worker not loading
- Check the
enableModuleWorkersis enabled - Ensure this feature is enabled in your configuration - Verify bundler support - Use webpack or rspack for worker support
- Check console errors - Look for import or initialization errors
- Debug worker script - Use
edge://inspect/#workersin Edge orchrome://inspect/#workersin Chrome to debug worker scripts
Worker hangs or never executes
When your package shares code between worker and main thread contexts, you may encounter issues with webpack's chunk splitting optimization. Web workers cannot load additional chunks at runtime, which can cause the worker to hang while waiting for shared chunks to load.
Symptoms:
- Worker code never executes
- No error messages, but worker remains idle
- Network tab shows worker script loading but not executing
- Worker shows up in the browser's DevTools but does not respond
Solutions:
Disable chunk splitting using bundlerOptions:
{
"packageSettings": [
{
"match": "my-worker-package",
"bundler": "rspack",
"bundlerOptions": {
"optimization": {
"splitChunks": false
}
}
}
]
}Alternative approaches:
- Use dynamic imports in workers:
const { sharedCode } = await import('../shared.js'); - Move shared utilities to separate packages that can be imported independently by both contexts
Worker fails with browser API errors
If your worker or its dependencies attempt to use browser-only APIs (like DOMParser, document properties), you may need to configure the bundler target for web worker compatibility. This setting is only available for webpack and rspack bundlers.
Symptoms:
ReferenceError: DOMParser is not definedReferenceError: document is not defined- Other browser API not available errors in worker context
Solution:
Configure the bundler target to webworker for packages that have browser API dependencies:
{
"packageSettings": [
{
"match": "my-worker-package",
"bundler": "rspack",
"bundlerOptions": {
"target": "webworker"
}
}
]
}This setting is also needed for packages that are dependencies of worker packages and contain browser-specific code.
Note: The webworker target tells the bundler to exclude or polyfill browser APIs that are not available in the worker context, preventing runtime errors.
CSS loader
Web workers cannot access the DOM, which causes issues when packages attempt to import CSS files. This is particularly problematic with the ori bundler, which does not properly handle CSS imports in worker contexts.
Symptoms:
- Error occurs when loading CSS files like
import 'styles.css' Uncaught ReferenceError: document is not defined at styles.cssin worker context- Worker fails to initialize when dependencies include CSS imports
General workarounds:
- Use
rspack,webpack, orrollupas the bundler, which handle CSS imports in workers more gracefully