CC 4.0 License
The content of this section is derived from the content of the following links and is subject to the CC BY 4.0 license.
The following contents can be assumed to be the result of modifications and deletions based on the original contents if not specifically stated.
Web Workers
Rspack provides built-in support for Web Workers, which means you don't need any loader to use Web Workers directly.
Usage
Basic Worker creation syntax:
You can customize the Worker's chunk name through the name property (the property value must be statically analyzable). This name will replace the [name] placeholder in the generated chunk filename:
This syntax was chosen for its strong standards compliance. It's built on the standard ECMAScript module specification, which means it works seamlessly even without build tools. For example, it runs natively in modern browsers with ES module support.
For usage examples, see:
Limitations
-
Because Rspack relies on static analysis to identify worker usage, it has the following two limitations:
-
new Workerand other worker-like APIs can usually also accept a string representation of a URL, but Rspack only supports passing a URL object. In practice, you must passnew URL('./worker.js', import.meta.url). -
Rspack cannot statically analyze variables used in
new Worker. For example, the following code will not work:
-
-
The
/* webpackEntryOptions: { filename: "workers/[name].js" } */magic comment is not supported yet.
Built-in syntax
In addition to new Worker(), Rspack also supports the following built-in forms by default:
new SharedWorker(), see SharedWorker
import { Worker } from "worker_threads": commonly used in Node.js environments, see Worker threads
navigator.serviceWorker.register(): used to register Service Workers, see ServiceWorkerContainer
Custom syntax
Use module.parser.javascript.worker to tell Rspack which expressions should be analyzed as worker-like entry creation:
truekeeps the built-in defaults and is equivalent to['...'].falsedisables worker syntax analysis and is equivalent to[].- An array replaces the defaults. Keep
'...'in the array if you want to extend the built-in defaults instead of replacing them.
The built-in syntax is implemented using the same mechanism. The '...' placeholder can be expanded to the following entries:
The following rules explain the custom syntax:
- A trailing
()matches call syntax, while no trailing()matches constructor syntax.'worker'will matchnew worker(new URL("./worker.js", import.meta.url)).'worker()'will matchworker(new URL("./worker.js", import.meta.url)).
- Member syntax is also supported, but the root object must be a free variable.
'foo.bar'will matchnew foo.bar(new URL("./worker.js", import.meta.url)).'foo.bar()'will matchfoo.bar(new URL("./worker.js", import.meta.url)).
- Use
*to match a root object by its exact variable name. Unlike plain member syntax, the root object here is a declared variable rather than a free variable.'*foo.bar()'will matchconst foo = new WorkletContext(); foo.bar(new URL("./processor.js", import.meta.url)).- For now,
*-prefixed syntax supports only call syntax; constructor syntax such as'*foo.bar'is not supported.
- Use
fromto match an imported binding from an exact ESM source.'Foo from pkg'will matchimport { Foo } from 'pkg'; new Foo(new URL("./worker.js", import.meta.url)).'default from pkg'will matchimport Foo from 'pkg'; new Foo(new URL("./worker.js", import.meta.url)).'foo() from pkg'will matchimport { foo } from 'pkg'; foo(new URL("./worker.js", import.meta.url)).
The following examples show how these custom syntax rules work in practice.
The first few examples are based on the built-in syntax. In practice, you do not need to add them to the config because they are already included in the default '...'. They are shown here only to explain how the custom syntax rules work:
-
Built-in constructor syntax:
WorkerandSharedWorkerWorkerandSharedWorkerare constructors, not functions, so the syntax string does not need trailing(). -
Built-in call syntax:
navigator.serviceWorker.register()This example shows why trailing
()matters:register()is a function call, not a constructor. -
Built-in import syntax:
Worker from worker_threadsThis example shows the
fromrule. The import source must match exactly.
The remaining examples show some common patterns in the ecosystem that can be supported through custom syntax:
-
CSS Worklet
The syntax
CSS.paintWorklet.addModule()is a direct member call, so the config string ends with().rspack.config.mjs -
AudioWorklet
Unlike CSS Worklet, the root object in
audioContext.audioWorklet.addModule(...)is not a free variable. It is a variable declared byconst audioContext = new AudioContext();, so the custom syntax needs to start with*to indicate that the root object is a declared variable.rspack.config.mjs -
Importing workers from third-party packages.
These examples show how
fromworks with different import styles.rspack.config.mjs
worker-loader
worker-loader is provided only as a temporary solution to facilitate project migration to Rspack. It is recommended to use the new Worker() syntax instead.
Rspack also supports worker-loader. However, since worker-loader is no longer maintained, please use worker-rspack-loader as a replacement.
Use resolveLoader to replace worker-loader with worker-rspack-loader:

