From c918693484adc7c4aa13b6920dadb3f164d032dd Mon Sep 17 00:00:00 2001 From: Alan Agius Date: Tue, 30 Jul 2019 15:32:17 +0200 Subject: [PATCH] fix: using multiple unnamed Web Workers mixes them up When no name is provide use the workerId as identifier as otherwise we end up with only a single worker emitted. Fixes https://github.com/angular/angular-cli/issues/15188 and fixes https://github.com/angular/angular-cli/issues/14582 and fixes #24 --- src/index.js | 4 ++-- test/fixtures/multiple/dep.js | 17 +++++++++++++++++ test/fixtures/multiple/entry.js | 28 ++++++++++++++++++++++++++++ test/fixtures/multiple/index.html | 19 +++++++++++++++++++ test/fixtures/multiple/worker-0.js | 26 ++++++++++++++++++++++++++ test/fixtures/multiple/worker-1.js | 26 ++++++++++++++++++++++++++ test/index.test.js | 17 +++++++++++++++++ 7 files changed, 135 insertions(+), 2 deletions(-) create mode 100644 test/fixtures/multiple/dep.js create mode 100644 test/fixtures/multiple/entry.js create mode 100644 test/fixtures/multiple/index.html create mode 100644 test/fixtures/multiple/worker-0.js create mode 100644 test/fixtures/multiple/worker-1.js diff --git a/src/index.js b/src/index.js index fdb3839..a734e82 100644 --- a/src/index.js +++ b/src/index.js @@ -68,8 +68,8 @@ export default class WorkerPlugin { return false; } - let loaderOptions = opts.name && { name: opts.name }; - const req = `require(${JSON.stringify(workerLoader + (loaderOptions ? ('?' + JSON.stringify(loaderOptions)) : '') + '!' + dep.string)})`; + const loaderOptions = { name: opts.name || workerId }; + const req = `require(${JSON.stringify(workerLoader + '?' + JSON.stringify(loaderOptions) + '!' + dep.string)})`; const id = `__webpack__worker__${++workerId}`; ParserHelpers.toConstantDependency(parser, id)(expr.arguments[0]); diff --git a/test/fixtures/multiple/dep.js b/test/fixtures/multiple/dep.js new file mode 100644 index 0000000..6bedb91 --- /dev/null +++ b/test/fixtures/multiple/dep.js @@ -0,0 +1,17 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +export const foo = 'bar'; diff --git a/test/fixtures/multiple/entry.js b/test/fixtures/multiple/entry.js new file mode 100644 index 0000000..b39e8f0 --- /dev/null +++ b/test/fixtures/multiple/entry.js @@ -0,0 +1,28 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +const worker0 = new Worker('./worker-0', { type: 'module' }); +const worker1 = new Worker('./worker-1', { type: 'module' }); + +worker0.onmessage = ({ data }) => { + console.log('page got data: ', data); +}; +worker0.postMessage('hello 0'); + +worker1.onmessage = ({ data }) => { + console.log('page got data: ', data); +}; +worker1.postMessage('hello 1'); diff --git a/test/fixtures/multiple/index.html b/test/fixtures/multiple/index.html new file mode 100644 index 0000000..25d6d97 --- /dev/null +++ b/test/fixtures/multiple/index.html @@ -0,0 +1,19 @@ + + + + + diff --git a/test/fixtures/multiple/worker-0.js b/test/fixtures/multiple/worker-0.js new file mode 100644 index 0000000..a2e9644 --- /dev/null +++ b/test/fixtures/multiple/worker-0.js @@ -0,0 +1,26 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +import { foo } from './dep'; + +console.log('hello from worker 0'); + +addEventListener('message', ({ data }) => { + console.log('worker 0 got message', data); + if (data === 'hello 0') { + postMessage(foo); + } +}); diff --git a/test/fixtures/multiple/worker-1.js b/test/fixtures/multiple/worker-1.js new file mode 100644 index 0000000..a8f5b7d --- /dev/null +++ b/test/fixtures/multiple/worker-1.js @@ -0,0 +1,26 @@ +/** + * Copyright 2018 Google LLC + * + * Licensed under the Apache License, Version 2.0 (the "License"); you may not + * use this file except in compliance with the License. You may obtain a copy of + * the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations under + * the License. + */ + +import { foo } from './dep'; + +console.log('hello from worker 1'); + +addEventListener('message', ({ data }) => { + console.log('worker 1 got message', data); + if (data === 'hello 1') { + postMessage(foo); + } +}); diff --git a/test/index.test.js b/test/index.test.js index 695cc73..c396a76 100644 --- a/test/index.test.js +++ b/test/index.test.js @@ -45,6 +45,23 @@ describe('worker-plugin', () => { expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"0\.worker\.js"/g); }); + test('it replaces multiple Worker exports with __webpack_require__', async () => { + const stats = await runWebpack('multiple', { + plugins: [ + new WorkerPlugin() + ] + }); + + const assetNames = Object.keys(stats.assets); + expect(assetNames).toHaveLength(3); + expect(assetNames).toContainEqual('0.worker.js'); + expect(assetNames).toContainEqual('1.worker.js'); + + const main = stats.assets['main.js']; + expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"0\.worker\.js"/g); + expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"1\.worker\.js"/g); + }); + test('retainModule:true leaves {type:module} in worker init', async () => { const { assets } = await runWebpack('basic', { plugins: [