-
Notifications
You must be signed in to change notification settings - Fork 84
Expand file tree
/
Copy pathindex.js
More file actions
113 lines (88 loc) · 3.51 KB
/
index.js
File metadata and controls
113 lines (88 loc) · 3.51 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
import path from 'path';
import loaderUtils from 'loader-utils';
import NodeTargetPlugin from 'webpack/lib/node/NodeTargetPlugin';
import SingleEntryPlugin from 'webpack/lib/SingleEntryPlugin';
import WebWorkerTemplatePlugin from 'webpack/lib/webworker/WebWorkerTemplatePlugin';
export default function loader() {}
loader.pitch = function(request) {
this.cacheable(false);
const options = loaderUtils.getOptions(this) || {};
const cb = this.async();
const filename = loaderUtils.interpolateName(this, `${options.name || '[hash]'}.worker.js`, {
context: options.context || this.rootContext || this.options.context,
regExp: options.regExp
});
const worker = {};
worker.options = {
filename,
chunkFilename: `[id].${filename}`,
namedChunkFilename: null
};
const compilerOptions = this._compiler.options || {};
if (compilerOptions.output && compilerOptions.output.globalObject==='window') {
console.warn('Warning (workerize-loader): output.globalObject is set to "window". It should be set to "self" or "this" to support HMR in Workers.');
}
worker.compiler = this._compilation.createChildCompiler('worker', worker.options);
(new WebWorkerTemplatePlugin(worker.options)).apply(worker.compiler);
if (this.target!=='webworker' && this.target!=='web') {
(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);
worker.compiler.runAsChild((err, entries, compilation) => {
if (err) return cb(err);
if (entries[0]) {
worker.file = Array.from(entries[0].files)[0];
let contents = compilation.assets[worker.file].source();
if (entries[0].entryModule.buildMeta.providedExports === true) {
// Can also occur if doing `export * from 'common js module'`
throw new Error('Attempted to load a worker implemented in CommonJS');
}
let exports = entries[0].entryModule.buildMeta.providedExports;
// console.log('Workerized exports: ', exports.join(', '));
if (options.inline) {
worker.url = `URL.createObjectURL(new Blob([${JSON.stringify(contents)}]))`;
}
else if (options.publicPath) {
worker.url = `${JSON.stringify(options.publicPath + worker.file)}`;
}
else {
worker.url = `__webpack_public_path__ + ${JSON.stringify(worker.file)}`;
}
if (options.fallback === false) {
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(${workerUrl}, { name: ${JSON.stringify(filename)} })
addMethods(w, methods)
${ options.ready ? 'w.ready = new Promise(function(r) { w.addEventListener("ready", function(){ r(w) }) })' : '' }
return w
}
`);
}
return cb(null, null);
});
};