UNPKG

12.3 kBMarkdownView Raw
1<div align="center">
2 <a href="https://github.com/webpack/webpack">
3 <img width="200" height="200" src="https://webpack.js.org/assets/icon-square-big.svg">
4 </a>
5</div>
6
7[![npm][npm]][npm-url]
8[![node][node]][node-url]
9[![deps][deps]][deps-url]
10[![tests][tests]][tests-url]
11[![coverage][cover]][cover-url]
12[![chat][chat]][chat-url]
13[![size][size]][size-url]
14
15# worker-loader
16
17worker loader module for webpack
18
19## Getting Started
20
21To begin, you'll need to install `worker-loader`:
22
23```console
24$ npm install worker-loader --save-dev
25```
26
27### Inlined
28
29**App.js**
30
31```js
32import Worker from "worker-loader!./Worker.js";
33```
34
35### Config
36
37**webpack.config.js**
38
39```js
40module.exports = {
41 module: {
42 rules: [
43 {
44 test: /\.worker\.js$/,
45 use: { loader: "worker-loader" },
46 },
47 ],
48 },
49};
50```
51
52**App.js**
53
54```js
55import Worker from "./file.worker.js";
56
57const worker = new Worker();
58
59worker.postMessage({ a: 1 });
60worker.onmessage = function (event) {};
61
62worker.addEventListener("message", function (event) {});
63```
64
65And run `webpack` via your preferred method.
66
67## Options
68
69| Name | Type | Default | Description |
70| :-----------------------------------: | :-------------------------: | :-----------------------------: | :-------------------------------------------------------------------------------- |
71| **[`worker`](#worker)** | `{String\|Object}` | `Worker` | Allows to set web worker constructor name and options |
72| **[`publicPath`](#publicpath)** | `{String\|Function}` | based on `output.publicPath` | specifies the public URL address of the output files when referenced in a browser |
73| **[`filename`](#filename)** | `{String\|Function}` | based on `output.filename` | The filename of entry chunks for web workers |
74| **[`chunkFilename`](#chunkfilename)** | `{String}` | based on `output.chunkFilename` | The filename of non-entry chunks for web workers |
75| **[`inline`](#inline)** | `'no-fallback'\|'fallback'` | `undefined` | Allow to inline the worker as a `BLOB` |
76| **[`esModule`](#esmodule)** | `{Boolean}` | `true` | Use ES modules syntax |
77
78### `worker`
79
80Type: `String|Object`
81Default: `Worker`
82
83Set the worker type.
84
85#### `String`
86
87Allows to set web worker constructor name.
88
89**webpack.config.js**
90
91```js
92module.exports = {
93 module: {
94 rules: [
95 {
96 test: /\.worker\.(c|m)?js$/i,
97 loader: "worker-loader",
98 options: {
99 worker: "SharedWorker",
100 },
101 },
102 ],
103 },
104};
105```
106
107#### `Object`
108
109Allow to set web worker constructor name and options.
110
111**webpack.config.js**
112
113```js
114module.exports = {
115 module: {
116 rules: [
117 {
118 test: /\.worker\.(c|m)?js$/i,
119 loader: "worker-loader",
120 options: {
121 worker: {
122 type: "SharedWorker",
123 options: {
124 type: "classic",
125 credentials: "omit",
126 name: "my-custom-worker-name",
127 },
128 },
129 },
130 },
131 ],
132 },
133};
134```
135
136### `publicPath`
137
138Type: `String|Function`
139Default: based on `output.publicPath`
140
141The `publicPath` specifies the public URL address of the output files when referenced in a browser.
142If not specified, the same public path used for other webpack assets is used.
143
144#### `String`
145
146**webpack.config.js**
147
148```js
149module.exports = {
150 module: {
151 rules: [
152 {
153 test: /\.worker\.(c|m)?js$/i,
154 loader: "worker-loader",
155 options: {
156 publicPath: "/scripts/workers/",
157 },
158 },
159 ],
160 },
161};
162```
163
164#### `Function`
165
166**webpack.config.js**
167
168```js
169module.exports = {
170 module: {
171 rules: [
172 {
173 test: /\.worker\.(c|m)?js$/i,
174 loader: "worker-loader",
175 options: {
176 publicPath: (pathData, assetInfo) => {
177 return `/scripts/${pathData.hash}/workers/`;
178 },
179 },
180 },
181 ],
182 },
183};
184```
185
186### `filename`
187
188Type: `String|Function`
189Default: based on `output.filename`, adding `worker` suffix, for example - `output.filename: '[name].js'` value of this option will be `[name].worker.js`
190
191The filename of entry chunks for web workers.
192
193#### `String`
194
195**webpack.config.js**
196
197```js
198module.exports = {
199 module: {
200 rules: [
201 {
202 test: /\.worker\.(c|m)?js$/i,
203 loader: "worker-loader",
204 options: {
205 filename: "[name].[contenthash].worker.js",
206 },
207 },
208 ],
209 },
210};
211```
212
213#### `Function`
214
215**webpack.config.js**
216
217```js
218module.exports = {
219 module: {
220 rules: [
221 {
222 test: /\.worker\.(c|m)?js$/i,
223 loader: "worker-loader",
224 options: {
225 filename: (pathData) => {
226 if (
227 /\.worker\.(c|m)?js$/i.test(pathData.chunk.entryModule.resource)
228 ) {
229 return "[name].custom.worker.js";
230 }
231
232 return "[name].js";
233 },
234 },
235 },
236 ],
237 },
238};
239```
240
241### `chunkFilename`
242
243Type: `String`
244Default: based on `output.chunkFilename`, adding `worker` suffix, for example - `output.chunkFilename: '[id].js'` value of this option will be `[id].worker.js`
245
246The filename of non-entry chunks for web workers.
247
248**webpack.config.js**
249
250```js
251module.exports = {
252 module: {
253 rules: [
254 {
255 test: /\.worker\.(c|m)?js$/i,
256 loader: "worker-loader",
257 options: {
258 chunkFilename: "[id].[contenthash].worker.js",
259 },
260 },
261 ],
262 },
263};
264```
265
266### `inline`
267
268Type: `'fallback' | 'no-fallback'`
269Default: `undefined`
270
271Allow to inline the worker as a `BLOB`.
272
273Inline mode with the `fallback` value will create file for browsers without support web workers, to disable this behavior just use `no-fallback` value.
274
275**webpack.config.js**
276
277```js
278module.exports = {
279 module: {
280 rules: [
281 {
282 test: /\.worker\.(c|m)?js$/i,
283 loader: "worker-loader",
284 options: {
285 inline: "fallback",
286 },
287 },
288 ],
289 },
290};
291```
292
293### `esModule`
294
295Type: `Boolean`
296Default: `true`
297
298By default, `worker-loader` generates JS modules that use the ES modules syntax.
299
300You can enable a CommonJS modules syntax using:
301
302**webpack.config.js**
303
304```js
305module.exports = {
306 module: {
307 rules: [
308 {
309 test: /\.worker\.(c|m)?js$/i,
310 loader: "worker-loader",
311 options: {
312 esModule: false,
313 },
314 },
315 ],
316 },
317};
318```
319
320## Examples
321
322### Basic
323
324The worker file can import dependencies just like any other file:
325
326**index.js**
327
328```js
329import Worker from "./my.worker.js";
330
331var worker = new Worker();
332
333var result;
334
335worker.onmessage = function (event) {
336 if (!result) {
337 result = document.createElement("div");
338 result.setAttribute("id", "result");
339
340 document.body.append(result);
341 }
342
343 result.innerText = JSON.stringify(event.data);
344};
345
346const button = document.getElementById("button");
347
348button.addEventListener("click", function () {
349 worker.postMessage({ postMessage: true });
350});
351```
352
353**my.worker.js**
354
355```js
356onmessage = function (event) {
357 var workerResult = event.data;
358
359 workerResult.onmessage = true;
360
361 postMessage(workerResult);
362};
363```
364
365**webpack.config.js**
366
367```js
368module.exports = {
369 module: {
370 rules: [
371 {
372 test: /\.worker\.(c|m)?js$/i,
373 loader: "worker-loader",
374 options: {
375 esModule: false,
376 },
377 },
378 ],
379 },
380};
381```
382
383### Integrating with ES6+ features
384
385You can even use ES6+ features if you have the [`babel-loader`](https://github.com/babel/babel-loader) configured.
386
387**index.js**
388
389```js
390import Worker from "./my.worker.js";
391
392const worker = new Worker();
393
394let result;
395
396worker.onmessage = (event) => {
397 if (!result) {
398 result = document.createElement("div");
399 result.setAttribute("id", "result");
400
401 document.body.append(result);
402 }
403
404 result.innerText = JSON.stringify(event.data);
405};
406
407const button = document.getElementById("button");
408
409button.addEventListener("click", () => {
410 worker.postMessage({ postMessage: true });
411});
412```
413
414**my.worker.js**
415
416```js
417onmessage = function (event) {
418 const workerResult = event.data;
419
420 workerResult.onmessage = true;
421
422 postMessage(workerResult);
423};
424```
425
426**webpack.config.js**
427
428```js
429module.exports = {
430 module: {
431 rules: [
432 {
433 test: /\.worker\.(c|m)?js$/i,
434 use: [
435 {
436 loader: "worker-loader",
437 },
438 {
439 loader: "babel-loader",
440 options: {
441 presets: ["@babel/preset-env"],
442 },
443 },
444 ],
445 },
446 ],
447 },
448};
449```
450
451### Integrating with TypeScript
452
453To integrate with TypeScript, you will need to define a custom module for the exports of your worker.
454
455**typings/worker-loader.d.ts**
456
457```typescript
458declare module "worker-loader!*" {
459 // You need to change `Worker`, if you specified a different value for the `workerType` option
460 class WebpackWorker extends Worker {
461 constructor();
462 }
463
464 // Uncomment this if you set the `esModule` option to `false`
465 // export = WebpackWorker;
466 export default WebpackWorker;
467}
468```
469
470**my.worker.ts**
471
472```typescript
473const ctx: Worker = self as any;
474
475// Post data to parent thread
476ctx.postMessage({ foo: "foo" });
477
478// Respond to message from parent thread
479ctx.addEventListener("message", (event) => console.log(event));
480```
481
482**index.ts**
483
484```typescript
485import Worker from "worker-loader!./Worker";
486
487const worker = new Worker();
488
489worker.postMessage({ a: 1 });
490worker.onmessage = (event) => {};
491
492worker.addEventListener("message", (event) => {});
493```
494
495### Cross-Origin Policy
496
497[`WebWorkers`](https://developer.mozilla.org/en-US/docs/Web/API/Web_Workers_API) are restricted by a [same-origin policy](https://en.wikipedia.org/wiki/Same-origin_policy), so if your `webpack` assets are not being served from the same origin as your application, their download may be blocked by your browser.
498This scenario can commonly occur if you are hosting your assets under a CDN domain.
499Even downloads from the `webpack-dev-server` could be blocked.
500
501There are two workarounds:
502
503Firstly, you can inline the worker as a blob instead of downloading it as an external script via the [`inline`](#inline) parameter
504
505**App.js**
506
507```js
508import Worker from "./file.worker.js";
509```
510
511**webpack.config.js**
512
513```js
514module.exports = {
515 module: {
516 rules: [
517 {
518 loader: "worker-loader",
519 options: { inline: "fallback" },
520 },
521 ],
522 },
523};
524```
525
526Secondly, you may override the base download URL for your worker script via the [`publicPath`](#publicpath) option
527
528**App.js**
529
530```js
531// This will cause the worker to be downloaded from `/workers/file.worker.js`
532import Worker from "./file.worker.js";
533```
534
535**webpack.config.js**
536
537```js
538module.exports = {
539 module: {
540 rules: [
541 {
542 loader: "worker-loader",
543 options: { publicPath: "/workers/" },
544 },
545 ],
546 },
547};
548```
549
550## Contributing
551
552Please take a moment to read our contributing guidelines if you haven't yet done so.
553
554[CONTRIBUTING](./.github/CONTRIBUTING.md)
555
556## License
557
558[MIT](./LICENSE)
559
560[npm]: https://img.shields.io/npm/v/worker-loader.svg
561[npm-url]: https://npmjs.com/package/worker-loader
562[node]: https://img.shields.io/node/v/worker-loader.svg
563[node-url]: https://nodejs.org
564[deps]: https://david-dm.org/webpack-contrib/worker-loader.svg
565[deps-url]: https://david-dm.org/webpack-contrib/worker-loader
566[tests]: https://github.com/webpack-contrib/worker-loader/workflows/worker-loader/badge.svg
567[tests-url]: https://github.com/webpack-contrib/worker-loader/actions
568[cover]: https://codecov.io/gh/webpack-contrib/worker-loader/branch/master/graph/badge.svg
569[cover-url]: https://codecov.io/gh/webpack-contrib/worker-loader
570[chat]: https://badges.gitter.im/webpack/webpack.svg
571[chat-url]: https://gitter.im/webpack/webpack
572[size]: https://packagephobia.now.sh/badge?p=worker-loader
573[size-url]: https://packagephobia.now.sh/result?p=worker-loader