Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(web-workers): Add rollup-plugin-web-worker-loader #757

Closed
wants to merge 7 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
24 changes: 24 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -253,6 +253,29 @@ This can be customized by passing the command line argument `--css-modules "[nam
| true | import './my-file.css'; | :white_check_mark: |
| true | import './my-file.module.css'; | :white_check_mark: |

### Building web workers as inline blobs

Through the [rollup-plugin-web-worker-loader](https://github.com/darionco/rollup-plugin-web-worker-loader), microbundle can be instructed to create inlined JavaScript source blobs which contain all dependencies to run within a WebWorker execution context. Consider the following minimal example:

```js
// main.js
import MyWorker from 'worker-loader:./my-worker';
const myWorker = new MyWorker();
myWorker.postMessage(3.14159);

// my-worker.js
import { longRunningJob } from 'heavy-calculations'; // Imports will be inlined
self.onmessage = message => self.postMessage(longRunningJob(message.data));
```

And build it like this:

```bash
microbundle --worker-loader
```

**Note** For usage in TypeScript projects, have a look at the [rollup-typescript-webworkers](https://github.com/darionco/rollup-typescript-webworkers) example by the rollup-plugin-web-worker-loader maintainers.

### Mangling Properties

To achieve the smallest possible bundle size, libraries often wish to rename internal object properties or class members to smaller names - transforming `this._internalIdValue` to `this._i`. Microbundle doesn't do this by default, however it can be enabled by creating a `mangle.json` file (or a `"mangle"` property in your package.json). Within that file, you can specify a regular expression pattern to control which properties should be mangled. For example: to mangle all property names beginning an underscore:
Expand Down Expand Up @@ -316,6 +339,7 @@ Options
--generateTypes Whether or not to generate types, if `types` or `typings` is set in `package.json` then it will default to be `true`
--css Where to output CSS: "inline" or "external" (default: "external")
--css-modules Configures .css to be treated as modules (default: null)
--worker-loader Generate inline worker blobs (default false)
-h, --help Displays this message

Examples
Expand Down
20 changes: 18 additions & 2 deletions package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

1 change: 1 addition & 0 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -108,6 +108,7 @@
"rollup-plugin-postcss": "^4.0.0",
"rollup-plugin-terser": "^7.0.2",
"rollup-plugin-typescript2": "^0.29.0",
"rollup-plugin-web-worker-loader": "^1.6.1",
"sade": "^1.7.4",
"terser": "^5.7.0",
"tiny-glob": "^0.2.8",
Expand Down
13 changes: 11 additions & 2 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ import { terser } from 'rollup-plugin-terser';
import alias from '@rollup/plugin-alias';
import postcss from 'rollup-plugin-postcss';
import typescript from 'rollup-plugin-typescript2';
import webWorkerLoader from 'rollup-plugin-web-worker-loader';
import json from '@rollup/plugin-json';
import logError from './log-error';
import { isDir, isFile, stdout, isTruthy, removeScope } from './utils';
Expand Down Expand Up @@ -385,6 +386,7 @@ function createConfig(options, entry, format, writeMeta) {
: () => resolve(options.cwd, 'mangle.json');

const useTypescript = extname(entry) === '.ts' || extname(entry) === '.tsx';
const useWorkerLoader = options['worker-loader'] !== false;
const emitDeclaration =
options.generateTypes == null
? !!(pkg.types || pkg.typings)
Expand Down Expand Up @@ -418,7 +420,7 @@ function createConfig(options, entry, format, writeMeta) {

/** @type {false | import('rollup').RollupCache} */
let cache;
if (modern) cache = false;
if (modern || useWorkerLoader) cache = false;

const absMain = resolve(options.cwd, getMain({ options, entry, format }));
const outputDir = dirname(absMain);
Expand All @@ -427,7 +429,7 @@ function createConfig(options, entry, format, writeMeta) {
let config = {
/** @type {import('rollup').InputOptions} */
inputOptions: {
// disable Rollup's cache for the modern build to prevent re-use of legacy transpiled modules:
// disable Rollup's cache for modern and worker-loader builds to prevent re-use of legacy transpiled modules:
cache,
input: entry,
external: id => {
Expand Down Expand Up @@ -616,6 +618,13 @@ function createConfig(options, entry, format, writeMeta) {
},
},
],
useWorkerLoader &&
webWorkerLoader({
extensions: ['.js'].concat(useTypescript ? '.ts' : []),
external: [],
pattern: /worker-loader:(.+)/,
sourcemap: options.compress === false && options.sourcemap,
}),
/** @type {import('rollup').Plugin} */
({
name: 'postprocessing',
Expand Down
1 change: 1 addition & 0 deletions src/prog.js
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,7 @@ export default handler => {
.option('--cwd', 'Use an alternative working directory', '.')
.option('--sourcemap', 'Generate source map')
.option('--css', 'Where to output CSS: "inline" or "external"', 'external')
.option('--worker-loader', 'Generate inline worker blobs', false)
.option(
'--css-modules',
'Turns on css-modules for all .css imports. Passing a string will override the scopeName. eg --css-modules="_[hash]"',
Expand Down
70 changes: 70 additions & 0 deletions test/__snapshots__/index.test.js.snap
Original file line number Diff line number Diff line change
Expand Up @@ -3016,3 +3016,73 @@ exports[`fixtures build ts-module with microbundle 7`] = `
//# sourceMappingURL=ts-module.umd.js.map
"
`;

exports[`fixtures build worker-loader with microbundle 1`] = `
"Used script: microbundle --worker-loader

Directory tree:

worker-loader
dist
bar.d.ts
index.d.ts
worker-loader.esm.js
worker-loader.esm.js.map
worker-loader.js
worker-loader.js.map
worker-loader.umd.js
worker-loader.umd.js.map
worker.d.ts
node_modules
package.json
src
bar.ts
index.ts
worker.ts
workers.d.ts
tsconfig.json


Build \\"workerLoader\\" to dist:
592 B: worker-loader.js.gz
528 B: worker-loader.js.br
592 B: worker-loader.esm.js.gz
528 B: worker-loader.esm.js.br
618 B: worker-loader.umd.js.gz
538 B: worker-loader.umd.js.br"
`;

exports[`fixtures build worker-loader with microbundle 2`] = `9`;

exports[`fixtures build worker-loader with microbundle 3`] = `
"export declare function bar(): string;
"
`;

exports[`fixtures build worker-loader with microbundle 4`] = `
"export {};
"
`;

exports[`fixtures build worker-loader with microbundle 5`] = `
"var e=null;try{var o=\\"undefined\\"!=typeof module&&\\"function\\"==typeof module.require&&module.require(\\"worker_threads\\")||\\"function\\"==typeof __non_webpack_require__&&__non_webpack_require__(\\"worker_threads\\")||\\"function\\"==typeof require&&require(\\"worker_threads\\");e=o.Worker}catch(e){}var r,n,t,c,i=new(\\"[object process]\\"===Object.prototype.toString.call(\\"undefined\\"!=typeof process?process:0)?(t=(n=Buffer.from(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\",\\"base64\\").toString(\\"utf8\\")).indexOf(\\"\\\\n\\",10)+1,c=n.substring(t)+\\"\\",function(o){return new e(c,Object.assign({},o,{eval:!0}))}):function(e){return r=r||function(e,o,r){var n=atob(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\"),t=n.indexOf(\\"\\\\n\\",10)+1,c=n.substring(t)+\\"\\",i=new Blob([c],{type:\\"application/javascript\\"});return URL.createObjectURL(i)}(),new Worker(r,e)});i.onmessage=function(e){return\\"foobar\\"===e.data},i.postMessage(\\"foo\\");
//# sourceMappingURL=worker-loader.esm.js.map
"
`;

exports[`fixtures build worker-loader with microbundle 6`] = `
"var e=null;try{var o=\\"undefined\\"!=typeof module&&\\"function\\"==typeof module.require&&module.require(\\"worker_threads\\")||\\"function\\"==typeof __non_webpack_require__&&__non_webpack_require__(\\"worker_threads\\")||\\"function\\"==typeof require&&require(\\"worker_threads\\");e=o.Worker}catch(e){}var r,n,t,c,i=new(\\"[object process]\\"===Object.prototype.toString.call(\\"undefined\\"!=typeof process?process:0)?(t=(n=Buffer.from(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\",\\"base64\\").toString(\\"utf8\\")).indexOf(\\"\\\\n\\",10)+1,c=n.substring(t)+\\"\\",function(o){return new e(c,Object.assign({},o,{eval:!0}))}):function(e){return r=r||function(e,o,r){var n=atob(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\"),t=n.indexOf(\\"\\\\n\\",10)+1,c=n.substring(t)+\\"\\",i=new Blob([c],{type:\\"application/javascript\\"});return URL.createObjectURL(i)}(),new Worker(r,e)});i.onmessage=function(e){return\\"foobar\\"===e.data},i.postMessage(\\"foo\\");
//# sourceMappingURL=worker-loader.js.map
"
`;

exports[`fixtures build worker-loader with microbundle 7`] = `
"!function(e){\\"function\\"==typeof define&&define.amd?define(e):e()}(function(){var e=null;try{var o=\\"undefined\\"!=typeof module&&\\"function\\"==typeof module.require&&module.require(\\"worker_threads\\")||\\"function\\"==typeof __non_webpack_require__&&__non_webpack_require__(\\"worker_threads\\")||\\"function\\"==typeof require&&require(\\"worker_threads\\");e=o.Worker}catch(e){}var n,r,t,c,i=new(\\"[object process]\\"===Object.prototype.toString.call(\\"undefined\\"!=typeof process?process:0)?(t=(r=Buffer.from(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\",\\"base64\\").toString(\\"utf8\\")).indexOf(\\"\\\\n\\",10)+1,c=r.substring(t)+\\"\\",function(o){return new e(c,Object.assign({},o,{eval:!0}))}):function(e){return n=n||function(e,o,n){var r=atob(\\"Lyogcm9sbHVwLXBsdWdpbi13ZWItd29ya2VyLWxvYWRlciAqLwohZnVuY3Rpb24oKXsidXNlIHN0cmljdCI7c2VsZi5vbm1lc3NhZ2U9ZnVuY3Rpb24ocyl7cmV0dXJuIHNlbGYucG9zdE1lc3NhZ2Uocy5kYXRhKyJiYXIiKX19KCk7Cgo=\\"),t=r.indexOf(\\"\\\\n\\",10)+1,c=r.substring(t)+\\"\\",i=new Blob([c],{type:\\"application/javascript\\"});return URL.createObjectURL(i)}(),new Worker(n,e)});i.onmessage=function(e){return\\"foobar\\"===e.data},i.postMessage(\\"foo\\")});
//# sourceMappingURL=worker-loader.umd.js.map
"
`;

exports[`fixtures build worker-loader with microbundle 8`] = `
"export {};
"
`;
6 changes: 6 additions & 0 deletions test/fixtures/worker-loader/package.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
{
"name": "worker-loader",
"scripts": {
"build": "microbundle --worker-loader"
}
}
3 changes: 3 additions & 0 deletions test/fixtures/worker-loader/src/bar.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
export function bar() {
return 'bar';
}
6 changes: 6 additions & 0 deletions test/fixtures/worker-loader/src/index.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
import WebWorker from 'worker-loader:./worker';

const webWorker = new WebWorker();

webWorker.onmessage = message => message.data === 'foobar';
webWorker.postMessage('foo');
5 changes: 5 additions & 0 deletions test/fixtures/worker-loader/src/worker.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
import { bar } from './bar';

declare const self: Worker;

self.onmessage = message => self.postMessage(message.data + bar());
4 changes: 4 additions & 0 deletions test/fixtures/worker-loader/src/workers.d.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
declare module 'worker-loader:*' {
const WorkerFactory: new () => Worker;
export default WorkerFactory;
}
7 changes: 7 additions & 0 deletions test/fixtures/worker-loader/tsconfig.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
{
"compilerOptions": {
"baseUrl": "."
},
"files": ["src/index.ts"],
"include": ["src/workers.d.ts"]
}