From c8a1156d4c2dd5902ba500aa9c25547bfab53eac Mon Sep 17 00:00:00 2001 From: Jeremy Danyow Date: Sat, 30 Dec 2017 13:30:11 -0500 Subject: [PATCH] web worker support (#441) * web worker support * fix lint error --- src/assets/JSAsset.js | 4 ++- src/visitors/dependencies.js | 31 +++++++++++++++++----- test/integration/workers/index.js | 3 +++ test/integration/workers/service-worker.js | 1 + test/integration/workers/worker.js | 1 + test/javascript.js | 8 ++++-- 6 files changed, 39 insertions(+), 9 deletions(-) create mode 100644 test/integration/workers/index.js create mode 100644 test/integration/workers/service-worker.js create mode 100644 test/integration/workers/worker.js diff --git a/src/assets/JSAsset.js b/src/assets/JSAsset.js index 0bdb64a9260..203968d4b21 100644 --- a/src/assets/JSAsset.js +++ b/src/assets/JSAsset.js @@ -16,6 +16,7 @@ const IMPORT_RE = /\b(?:import\b|export\b|require\s*\()/; const GLOBAL_RE = /\b(?:process|__dirname|__filename|global|Buffer)\b/; const FS_RE = /\breadFileSync\b/; const SW_RE = /\bnavigator\s*\.\s*serviceWorker\s*\.\s*register\s*\(/; +const WORKER_RE = /\bnew\s*Worker\s*\(/; class JSAsset extends Asset { constructor(name, pkg, options) { @@ -32,7 +33,8 @@ class JSAsset extends Asset { !/.js$/.test(this.name) || IMPORT_RE.test(this.contents) || GLOBAL_RE.test(this.contents) || - SW_RE.test(this.contents) + SW_RE.test(this.contents) || + WORKER_RE.test(this.contents) ); } diff --git a/src/visitors/dependencies.js b/src/visitors/dependencies.js index 711e4b7c0c1..954f8b46061 100644 --- a/src/visitors/dependencies.js +++ b/src/visitors/dependencies.js @@ -64,12 +64,22 @@ module.exports = { matchesPattern(callee, serviceWorkerPattern); if (isRegisterServiceWorker) { - let assetPath = asset.addURLDependency(args[0].value); - if (!isURL(assetPath)) { - assetPath = urlJoin(asset.options.publicURL, assetPath); - } - args[0].value = assetPath; - asset.isAstDirty = true; + addURLDependency(asset, args[0]); + return; + } + }, + + NewExpression(node, asset) { + const {callee, arguments: args} = node; + + const isWebWorker = + callee.type === 'Identifier' && + callee.name === 'Worker' && + args.length === 1 && + types.isStringLiteral(args[0]); + + if (isWebWorker) { + addURLDependency(asset, args[0]); return; } } @@ -79,3 +89,12 @@ function addDependency(asset, node, opts = {}) { opts.loc = node.loc && node.loc.start; asset.addDependency(node.value, opts); } + +function addURLDependency(asset, node) { + let assetPath = asset.addURLDependency(node.value); + if (!isURL(assetPath)) { + assetPath = urlJoin(asset.options.publicURL, assetPath); + } + node.value = assetPath; + asset.isAstDirty = true; +} diff --git a/test/integration/workers/index.js b/test/integration/workers/index.js new file mode 100644 index 00000000000..c168c379918 --- /dev/null +++ b/test/integration/workers/index.js @@ -0,0 +1,3 @@ +navigator.serviceWorker.register('service-worker.js', { scope: './' }); + +new Worker('worker.js'); diff --git a/test/integration/workers/service-worker.js b/test/integration/workers/service-worker.js new file mode 100644 index 00000000000..d0965140fe7 --- /dev/null +++ b/test/integration/workers/service-worker.js @@ -0,0 +1 @@ +self.addEventListener('message', () => {}); diff --git a/test/integration/workers/worker.js b/test/integration/workers/worker.js new file mode 100644 index 00000000000..d0965140fe7 --- /dev/null +++ b/test/integration/workers/worker.js @@ -0,0 +1 @@ +self.addEventListener('message', () => {}); diff --git a/test/javascript.js b/test/javascript.js index 8dbf91faa96..5f7d0f3b4a1 100644 --- a/test/javascript.js +++ b/test/javascript.js @@ -58,13 +58,17 @@ describe('javascript', function() { assert.equal(await output(), 3); }); - it('should support bundling service workers', async function() { - let b = await bundle(__dirname + '/integration/service-worker/index.js'); + it('should support bundling workers', async function() { + let b = await bundle(__dirname + '/integration/workers/index.js'); assertBundleTree(b, { name: 'index.js', assets: ['index.js'], childBundles: [ + { + assets: ['service-worker.js'], + childBundles: [] + }, { assets: ['worker.js'], childBundles: []