Skip to content

Commit 236faae

Browse files
committed
Merge master branch of GoogleChromeLabs/worker-plugin
Fixes #6.
1 parent 1b3f3d1 commit 236faae

6 files changed

Lines changed: 173 additions & 48 deletions

File tree

package.json

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@
3131
"jest": {
3232
"watchPathIgnorePatterns": [
3333
"<rootDir>/node_modules/",
34-
"<rootDir>/test/fixtures/.*?/dist/"
34+
"<rootDir>/test/fixtures/"
3535
]
3636
},
3737
"babel": {
@@ -63,6 +63,9 @@
6363
],
6464
"license": "Apache-2.0",
6565
"devDependencies": {
66+
"@file-services/memory": "^1.0.3",
67+
"@file-services/node": "^1.0.3",
68+
"@file-services/overlay": "^1.0.3",
6669
"babel-plugin-transform-es2015-modules-commonjs": "^6.26.2",
6770
"clean-webpack-plugin": "^1.0.0",
6871
"eslint": "^5.9.0",

src/index.js

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,9 +69,9 @@ export default class WorkerPlugin {
6969
}
7070
}
7171

72-
let loaderOptions = opts.name && { name: opts.name };
73-
const req = `require(${JSON.stringify(workerLoader + (loaderOptions ? ('?' + JSON.stringify(loaderOptions)) : '') + '!' + dep.string)})`;
74-
const id = `__webpack__worker__${++workerId}`;
72+
const loaderOptions = { name: opts.name || workerId + '' };
73+
const req = `require(${JSON.stringify(workerLoader + '?' + JSON.stringify(loaderOptions) + '!' + dep.string)})`;
74+
const id = `__webpack__worker__${workerId++}`;
7575
ParserHelpers.toConstantDependency(parser, id)(expr.arguments[0]);
7676

7777
ParserHelpers.addParsedVariableToModule(parser, id, req);

src/loader.js

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,7 @@ export function pitch (request) {
5656
});
5757

5858
const workerCompiler = this._compilation.createChildCompiler(NAME, workerOptions, plugins);
59+
workerCompiler.context = this._compiler.context;
5960
(new WebWorkerTemplatePlugin(workerOptions)).apply(workerCompiler);
6061
(new FetchCompileWasmTemplatePlugin({
6162
mangleImports: compilerOptions.optimization.mangleWasmImports

test/_util.js

Lines changed: 88 additions & 43 deletions
Original file line numberDiff line numberDiff line change
@@ -19,44 +19,98 @@ import webpack from 'webpack';
1919
import CleanPlugin from 'clean-webpack-plugin';
2020
import TerserPlugin from 'terser-webpack-plugin';
2121

22+
export function sleep (ms) {
23+
return new Promise(resolve => setTimeout(resolve, ms));
24+
}
25+
2226
export function runWebpack (fixture, { output, plugins, ...config } = {}) {
27+
return run(callback => webpack({
28+
mode: 'production',
29+
devtool: false,
30+
context: path.resolve(__dirname, 'fixtures', fixture),
31+
entry: './entry.js',
32+
output: {
33+
publicPath: 'dist/',
34+
path: path.resolve(__dirname, 'fixtures', fixture, 'dist'),
35+
...(output || {})
36+
},
37+
optimization: {
38+
minimizer: [
39+
new TerserPlugin({
40+
terserOptions: {
41+
mangle: false,
42+
output: {
43+
beautify: true
44+
}
45+
},
46+
sourceMap: false
47+
})
48+
]
49+
},
50+
plugins: [
51+
new CleanPlugin([
52+
path.resolve(__dirname, 'fixtures', fixture, 'dist', '**')
53+
])
54+
].concat(plugins || []),
55+
...config
56+
}, callback));
57+
}
58+
59+
export function watchWebpack (fixture, { output, plugins, context, ...config } = {}) {
60+
context = context || path.resolve(__dirname, 'fixtures', fixture);
61+
const compiler = webpack({
62+
mode: 'production',
63+
context,
64+
entry: './entry.js',
65+
output: {
66+
publicPath: 'dist/',
67+
path: path.resolve(context, 'dist'),
68+
...(output || {})
69+
},
70+
optimization: {
71+
minimize: true,
72+
minimizer: [
73+
new TerserPlugin({
74+
terserOptions: {
75+
mangle: false,
76+
output: {
77+
beautify: true
78+
}
79+
},
80+
sourceMap: false
81+
})
82+
]
83+
},
84+
plugins: plugins || []
85+
});
86+
// compiler.watch({});
87+
compiler.doRun = () => run(compiler.run.bind(compiler));
88+
return compiler;
89+
}
90+
91+
export class CountApplyWebpackPlugin {
92+
constructor () {
93+
this.count = 0;
94+
}
95+
apply () {
96+
this.count++;
97+
}
98+
}
99+
100+
export function statsWithAssets (stats) {
101+
stats.assets = Object.keys(stats.compilation.assets).reduce((acc, name) => {
102+
acc[name] = stats.compilation.assets[name].source();
103+
return acc;
104+
}, {});
105+
return stats;
106+
}
107+
108+
function run (runner) {
23109
return new Promise((resolve, reject) => {
24-
webpack({
25-
mode: 'production',
26-
devtool: false,
27-
context: path.resolve(__dirname, 'fixtures', fixture),
28-
entry: './entry.js',
29-
output: {
30-
publicPath: 'dist/',
31-
path: path.resolve(__dirname, 'fixtures', fixture, 'dist'),
32-
...(output || {})
33-
},
34-
optimization: {
35-
minimizer: [
36-
new TerserPlugin({
37-
terserOptions: {
38-
mangle: false,
39-
output: {
40-
beautify: true
41-
}
42-
},
43-
sourceMap: false
44-
})
45-
]
46-
},
47-
plugins: [
48-
new CleanPlugin([
49-
path.resolve(__dirname, 'fixtures', fixture, 'dist', '**')
50-
])
51-
].concat(plugins || []),
52-
...config
53-
}, (err, stats) => {
110+
runner((err, stats) => {
54111
if (err) return reject(err);
55112

56-
stats.assets = Object.keys(stats.compilation.assets).reduce((acc, name) => {
57-
acc[name] = stats.compilation.assets[name].source();
58-
return acc;
59-
}, {});
113+
statsWithAssets(stats);
60114

61115
stats.info = stats.toJson({ assets: true, chunks: true });
62116

@@ -73,12 +127,3 @@ export function runWebpack (fixture, { output, plugins, ...config } = {}) {
73127
});
74128
});
75129
}
76-
77-
export class CountApplyWebpackPlugin {
78-
constructor () {
79-
this.count = 0;
80-
}
81-
apply () {
82-
this.count++;
83-
}
84-
}

test/index.test.js

Lines changed: 75 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@
1414
* the License.
1515
*/
1616

17+
import { resolve } from 'path';
18+
import { readFileSync, writeFileSync } from 'fs';
1719
import WorkerPlugin from '../src';
18-
import { runWebpack, CountApplyWebpackPlugin } from './_util';
20+
import { runWebpack, CountApplyWebpackPlugin, watchWebpack, statsWithAssets, sleep } from './_util';
21+
22+
jest.setTimeout(30000);
1923

2024
describe('worker-plugin', () => {
2125
test('exports a class', () => {
@@ -45,6 +49,23 @@ describe('worker-plugin', () => {
4549
expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"0\.worker\.js"/g);
4650
});
4751

52+
test('it replaces multiple Worker exports with __webpack_require__', async () => {
53+
const stats = await runWebpack('multiple', {
54+
plugins: [
55+
new WorkerPlugin()
56+
]
57+
});
58+
59+
const assetNames = Object.keys(stats.assets);
60+
expect(assetNames).toHaveLength(3);
61+
expect(assetNames).toContainEqual('0.worker.js');
62+
expect(assetNames).toContainEqual('1.worker.js');
63+
64+
const main = stats.assets['main.js'];
65+
expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"0\.worker\.js"/g);
66+
expect(main).toMatch(/module.exports = __webpack_require__\.p\s*\+\s*"1\.worker\.js"/g);
67+
});
68+
4869
test('retainModule:true leaves {type:module} in worker init', async () => {
4970
const { assets } = await runWebpack('basic', {
5071
plugins: [
@@ -150,4 +171,57 @@ describe('worker-plugin', () => {
150171

151172
expect(stats.assets['main.js']).toMatch(/new\s+Worker\s*\(\s*new\s+Blob\s*\(\s*\[\s*'onmessage=\(\)=>\{postMessage\("right back at ya"\)\}'\s*\]\s*\)\s*\)/g);
152173
});
174+
175+
describe('watch mode', () => {
176+
const workerFile = resolve(__dirname, 'fixtures', 'watch', 'worker.js');
177+
const workerCode = readFileSync(workerFile, 'utf-8');
178+
afterAll(() => {
179+
writeFileSync(workerFile, workerCode);
180+
});
181+
182+
test('it produces consistent modules in watch mode', async () => {
183+
const compiler = watchWebpack('watch', {
184+
plugins: [
185+
new WorkerPlugin()
186+
]
187+
});
188+
189+
function Deferred () {
190+
let controller;
191+
const p = new Promise((resolve, reject) => {
192+
controller = { resolve, reject };
193+
});
194+
Object.assign(p, controller);
195+
return p;
196+
}
197+
198+
let stats;
199+
let ready = new Deferred();
200+
201+
const watcher = compiler.watch({
202+
aggregateTimeout: 1,
203+
poll: 50,
204+
ignored: /node_modules|dist/
205+
}, (err, stats) => {
206+
if (err) ready.reject(err);
207+
else ready.resolve(statsWithAssets(stats));
208+
});
209+
210+
try {
211+
for (let i = 1; i < 5; i++) {
212+
ready = new Deferred();
213+
writeFileSync(workerFile, workerCode.replace(/console\.log\('hello from worker( \d+)?'\)/, `console.log('hello from worker ${i}')`));
214+
await sleep(1000);
215+
stats = await ready;
216+
await sleep(1000);
217+
expect(Object.keys(stats.assets).sort()).toEqual(['0.worker.js', 'main.js']);
218+
expect(stats.assets['0.worker.js']).toContain(`hello from worker ${i}`);
219+
}
220+
} finally {
221+
watcher.close();
222+
}
223+
224+
await sleep(1000);
225+
});
226+
});
153227
});

test/integration.test.js

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,8 @@ import { createStaticServer } from './_server';
2020
import { runWebpack } from './_util';
2121
import { evaluatePage } from './_page';
2222

23+
jest.setTimeout(30000);
24+
2325
describe('Integration', () => {
2426
test('The resulting Worker is instantiated correctly', async () => {
2527
const fixture = 'basic';

0 commit comments

Comments
 (0)