Skip to content

Commit

Permalink
Merge branch 'master' into patch-1
Browse files Browse the repository at this point in the history
  • Loading branch information
developit authored Jun 16, 2020
2 parents 4aa0559 + 68ea667 commit 86cd7c0
Show file tree
Hide file tree
Showing 8 changed files with 130 additions and 23 deletions.
20 changes: 20 additions & 0 deletions .github/workflows/main.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,20 @@
name: CI

on: [push, pull_request]

jobs:
build:
runs-on: ubuntu-latest

steps:
- uses: actions/checkout@v1
- uses: actions/setup-node@v1
with:
node-version: 12
- name: npm install, build, and test
run: |
npm install
npm run prepare --if-present
npm test
env:
CI: true
10 changes: 4 additions & 6 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,9 +1,7 @@
node_modules
.DS_Store
.cache
.mocha-puppeteer
*.log
build
dist
package-lock.json
yarn.lock
dist
coverage
.DS_Store
*.log
34 changes: 34 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -85,6 +85,40 @@ If you're using [Babel](https://babeljs.io/) in your build, make sure you disabl
}
```

### Testing

To test a module that is normally imported via `workerize-loader` when not using Webpack, import the module directly in your test:

```diff
-const worker = require('workerize-loader!./worker.js');
+const worker = () => require('./worker.js');

const instance = worker();
```

To test modules that rely on workerized imports when not using Webpack, you'll need to dig into your test runner a bit. For Jest, it's possible to define a custom `transform` that emulates workerize-loader on the main thread:

```js
// in your Jest configuration
{
"transform": {
"workerize-loader(\\?.*)?!(.*)": "<rootDir>/workerize-jest.js"
}
}
```

... then add the `workerize-jest.js` shim to your project:

```js
module.exports = {
process(src, filename, config, options) {
return 'module.exports = () => require(' + JSON.stringify(filename.replace(/.+!/,'')) + ')';
},
};
```

Now your tests and any modules they import can use `workerize-loader!` prefixes.

### Credit

The inner workings here are heavily inspired by [worker-loader](https://github.com/webpack-contrib/worker-loader). It's worth a read!
Expand Down
22 changes: 13 additions & 9 deletions package.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{
"name": "workerize-loader",
"version": "1.0.4",
"version": "1.2.1",
"description": "Automatically move a module into a Web Worker (Webpack loader)",
"main": "dist/index.js",
"repository": "developit/workerize-loader",
"scripts": {
"build": "microbundle --target node --format cjs --no-compress src/*.js",
"build": "microbundle --format cjs --no-compress --inline none src/*.js",
"prepublishOnly": "npm run build",
"dev": "karmatic watch --no-headless",
"test": "npm run build && karmatic",
"test": "npm run build && karmatic && NODE_ENV=production karmatic -p",
"release": "npm t && git commit -am $npm_package_version && git tag $npm_package_version && git push && git push --tags && npm publish"
},
"browserslist": [
"IE 10",
"node 8"
],
"eslintConfig": {
"extends": "eslint-config-developit",
"rules": {
Expand All @@ -33,14 +37,14 @@
"author": "Jason Miller <[email protected]> (http://jasonformat.com)",
"license": "MIT",
"devDependencies": {
"eslint": "^5.0.0",
"eslint-config-developit": "^1.1.1",
"karmatic": "^1.2.0",
"microbundle": "^0.6.0",
"webpack": "^4.17.1"
"eslint": "^7.2.0",
"eslint-config-developit": "^1.2.0",
"karmatic": "^1.4.0",
"microbundle": "^0.12.1",
"webpack": "^4.43.0"
},
"dependencies": {
"loader-utils": "^1.1.0"
"loader-utils": "^2.0.0"
},
"peerDependencies": {
"webpack": "*"
Expand Down
32 changes: 29 additions & 3 deletions src/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,25 @@ loader.pitch = function(request) {
(new NodeTargetPlugin()).apply(worker.compiler);
}

// webpack >= v4 supports webassembly
let wasmPluginPath = null;
try {
wasmPluginPath = require.resolve(
'webpack/lib/web/FetchCompileWasmTemplatePlugin'
);
}
catch (_err) {
// webpack <= v3, skipping
}

if (wasmPluginPath) {
// eslint-disable-next-line global-require
const FetchCompileWasmTemplatePlugin = require(wasmPluginPath);
new FetchCompileWasmTemplatePlugin({
mangleImports: this._compiler.options.optimization.mangleWasmImports
}).apply(worker.compiler);
}

(new SingleEntryPlugin(this.context, `!!${path.resolve(__dirname, 'rpc-worker-loader.js')}!${request}`, 'main')).apply(worker.compiler);

const subCache = `subcache ${__dirname} ${request}`;
Expand All @@ -83,7 +102,8 @@ loader.pitch = function(request) {
// only process entry exports
if (current.resource!==entry) return;

let exports = compilation.__workerizeExports || (compilation.__workerizeExports = {});
let key = current.nameForCondition();
let exports = CACHE[key] || (CACHE[key] = {});

if (decl.id) {
exports[decl.id.name] = true;
Expand All @@ -106,8 +126,9 @@ loader.pitch = function(request) {
if (entries[0]) {
worker.file = entries[0].files[0];

let key = entries[0].entryModule.nameForCondition();
let contents = compilation.assets[worker.file].source();
let exports = Object.keys(CACHE[worker.file] = compilation.__workerizeExports || CACHE[worker.file] || {});
let exports = Object.keys(CACHE[key] || {});

// console.log('Workerized exports: ', exports.join(', '));

Expand All @@ -125,11 +146,16 @@ loader.pitch = function(request) {
delete this._compilation.assets[worker.file];
}

let workerUrl = worker.url;
if (options.import) {
workerUrl = `"data:,importScripts('"+location.origin+${workerUrl}+"')"`;
}

return cb(null, `
var addMethods = require(${loaderUtils.stringifyRequest(this, path.resolve(__dirname, 'rpc-wrapper.js'))})
var methods = ${JSON.stringify(exports)}
module.exports = function() {
var w = new Worker(${worker.url}, { name: ${JSON.stringify(filename)} })
var w = new Worker(${workerUrl}, { name: ${JSON.stringify(filename)} })
addMethods(w, methods)
${ options.ready ? 'w.ready = new Promise(function(r) { w.addEventListener("ready", function(){ r(w) }) })' : '' }
return w
Expand Down
11 changes: 6 additions & 5 deletions src/rpc-worker-loader.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,10 +11,10 @@ function workerSetup() {
p = Promise.reject('No such method');
}
p.then(result => {
postMessage({ type: 'RPC', id, result });
})
postMessage({ type: 'RPC', id, result });
})
.catch(e => {
let error = { message: e};
let error = { message: e };
if (e.stack) {
error.message = e.message;
error.stack = e.stack;
Expand All @@ -29,6 +29,7 @@ function workerSetup() {

const workerScript = '\n' + Function.prototype.toString.call(workerSetup).replace(/(^.*\{|\}.*$|\n\s*)/g, '');

export default function rpcWorkerLoader(content) {
return content + workerScript;
export default function rpcWorkerLoader(content, sourceMap) {
const callback = this.async();
callback(null, content + workerScript, sourceMap);
}
19 changes: 19 additions & 0 deletions test/src/index.test.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
import './other';
import Worker from 'workerize-loader?ready&name=test!./worker';
import InlineWorker from 'workerize-loader?ready&inline&name=test!./worker';
import ImportWorker from 'workerize-loader?import!./worker';

describe('worker', () => {
let worker;
Expand Down Expand Up @@ -95,3 +96,21 @@ describe('async/await demo', () => {
expect(elapsed).toBeLessThan(20);
});
});

describe('?import option', () => {
let worker;

it('should be an instance of Worker', () => {
worker = new ImportWorker();
expect(worker).toEqual(jasmine.any(window.Worker));
});

it('worker.foo()', async () => {
expect(await worker.foo()).toBe(1);
});

it('worker.bar()', async () => {
let out = await worker.bar('a', 'b');
expect(out).toEqual('a [bar:3] b');
});
});
5 changes: 5 additions & 0 deletions webpack.config.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
module.exports = function () {
return {
mode: process.env.NODE_ENV || 'development'
};
}

0 comments on commit 86cd7c0

Please sign in to comment.