Ecosyste.ms: Awesome
An open API service indexing awesome lists of open source software.
https://github.com/googlechromelabs/worker-plugin
👩🏭 Adds native Web Worker bundling support to Webpack.
https://github.com/googlechromelabs/worker-plugin
web-worker webpack webpack-plugin webworker workers
Last synced: 26 days ago
JSON representation
👩🏭 Adds native Web Worker bundling support to Webpack.
- Host: GitHub
- URL: https://github.com/googlechromelabs/worker-plugin
- Owner: GoogleChromeLabs
- License: apache-2.0
- Created: 2018-09-18T15:45:18.000Z (about 6 years ago)
- Default Branch: master
- Last Pushed: 2021-05-27T18:48:43.000Z (over 3 years ago)
- Last Synced: 2024-10-14T10:03:41.567Z (26 days ago)
- Topics: web-worker, webpack, webpack-plugin, webworker, workers
- Language: JavaScript
- Homepage: https://npm.im/worker-plugin
- Size: 125 KB
- Stars: 1,916
- Watchers: 24
- Forks: 79
- Open Issues: 26
-
Metadata Files:
- Readme: README.md
- Contributing: CONTRIBUTING.md
- License: LICENSE
Awesome Lists containing this project
README
👩🏭 worker-plugin
Automatically bundle & compile Web Workers within Webpack.
### Features
Automatically compiles modules loaded in Web Workers:
```js
const worker = new Worker('./foo.js', { type: 'module' });
^^^^^^^^^^
gets bundled using webpack
```The best part? That worker constructor works just fine without bundling turned on, but when bundled the result is **supported in all browsers** that support Web Workers - all the way back to IE 10!
Workers with fully dynamic URLs, Blob URLs, data URLs or with no `{ type:'module' }` option are left unchanged.
> _**Compatibility Note:** Webpack 5 now includes worker bundling. It uses a slightly different syntax:_
> _`new Worker(new URL("./my_worker.js", import.meta.url))`_## Installation
```sh
npm install -D worker-plugin
```Then drop it into your **webpack.config.js:**
```diff
+ const WorkerPlugin = require('worker-plugin');module.exports = {
<...>
plugins: [
+ new WorkerPlugin()
]
<...>
}
```> **Note:** If you're planning on having more than one worker, you'll need to make sure [`output.filename`](https://webpack.js.org/configuration/output/#outputfilename) is set to something dynamic, e.g. `"[name].bundle.js"` otherwise the generated filenames will overwrite one another.
## Usage
**worker.js**: _(our worker module)_
```js
// This is a module worker, so we can use imports (in the browser too!)
import { calculatePi } from './some-other-module';addEventListener('message', event => {
postMessage(calculatePi(event.data));
});
```**main.js**: _(our demo, on the main thread)_
```js
const piWorker = new Worker('./worker.js', { type: 'module' });
piWorker.onmessage = event => {
console.log('pi: ' + event.data);
};
piWorker.postMessage(42);
```> **Note:** in order to ensure WorkerPlugin bundles your worker, make sure you're passing a **string** URL/filename to the Worker constructor. WorkerPlugin cannot bundle workers with dynamic/variable filenames, Blob or data URLs - it will leave them unmodified and print a warning during your build.
## Options
In most cases, no options are necessary to use WorkerPlugin.
### `globalObject` _(string | false)_
WorkerPlugin will print a warning if your Webpack configuration has `output.globalObject` set to `window`, since doing so breaks Hot Module Replacement in web workers.
If you're not using HMR and want to disable this warning, pass `globalObject:false`:
```js
new WorkerPlugin({
// disable warnings about "window" breaking HMR:
globalObject: false
})
```To configure the value of `output.globalObject` for WorkerPlugin's internal Webpack Compiler, set `globalObject` to any String:
```js
new WorkerPlugin({
// use "self" as the global object when receiving hot updates.
globalObject: 'self' // <-- this is the default value
})
```### `plugins` _(array)_
By default, WorkerPlugin doesn't run any of your configured Webpack plugins when bundling worker code - this avoids running things like `html-webpack-plugin` twice. For cases where it's necessary to apply a plugin to Worker code, use the `plugins` option.
Here you can specify the names of plugins to "copy" from your existing Webpack configuration, or provide specific plugins to apply only to worker code:
```js
module.exports = {
<...>
plugins: [
// an example of a plugin already being used:
new SomeExistingPlugin({ <...> }),new WorkerPlugin({
plugins: [
// A string here will copy the named plugin from your configuration:
'SomeExistingPlugin',
// Or you can specify a plugin directly, only applied to Worker code:
new SomePluginToApplyOnlyToWorkers({ <...> })
]
})
]
<...>
}
```### `sharedWorker` _(boolean)_
If set to `true`, this option enables the bundling of [SharedWorker](https://developer.mozilla.org/en-US/docs/Web/API/SharedWorker):
```js
const shared = new SharedWorker('./my-shared-worker.js', { type: 'module' });
```### `worker` _(boolean)_
If set to `false`, this option disables the bundling of [Worker]. Intended to be used with `{ sharedWorker: true }` to allow bundling of [SharedWorker] only without also bundling [Worker].
### `preserveTypeModule` _(boolean)_
### `workerType` _(string)_Normally, WorkerPlugin will transform `new Worker('./a.js', { type: 'module' })` to completely remove the `type` option, outputting something like `new Worker('a.worker.js')`. This allows the plugin to compile Module Workers to Classic Workers, which are supported in all browsers.
To instead retain `{type:'module'}` in bundled output, set the `preserveTypeModule` option to `true`:
```js
plugins: [
new WorkerPlugin({
preserveTypeModule: true
})
]
```Similarly, if you need to have WorkerPlugin output a specific `type` value, use the `workerType` option to specify it:
```js
plugins: [
new WorkerPlugin({
workerType: 'foo' // note: this isn't a thing!
})
]
```## Loader
At its core, worker-plugin provides two features: parsing and handling of `new Worker()`, and standalone bundling of modules for use in a different JavaScript context.
If all you want is to compile separate bundles for a module, `worker-plugin/loader` provides the bundling functionality of worker-plugin as a standalone Webpack loader. This is useful for generating bundles for use in iframes, Service Workers or Worklets. Applying `worker-plugin/loader` to an import will bundle that module and return its URL:
```js
import workerUrl from 'worker-plugin/loader!./my-worker';console.log(workerUrl); // "/0.worker.js"
CSS.paintWorklet.addModule(workerUrl);
```Two options are available:
| Option | Type | Description
|---|---|:--|
| `name` | _string_ | Controls the name of the generated chunk.
The name is used to generate a URL according to `output.chunkFilename`.
| `esModule` | _boolean_ | Export the URL from an ES Module (`export default url`).
The default is CommonJS (`module.exports = url`).Options can be supplied inline:
```js
import url from 'worker-plugin/loader?name=foo&esModule!./foo';
```... or by setting up a loader alias:
```js
// webpack.config.js to enable this:
// import url from 'worker!./foo';
{
resolveLoader: {
alias: {
worker: 'worker-plugin/loader?esModule'
}
}
}
```## License
Apache-2.0