我正在编写一个 npm 包,它是流行库 leafletjs 的插件。我正在使用 webpack 来捆绑包。我希望这个包能够根据命令生成和销毁一些网络工作者。 Web Worker 代码是我的源文件的一部分。但我希望能够将我的包作为 npm 模块或通过 cdn 分发,这意味着它必须编译为可以通过 HTML 标头包含的单个文件。我正在使用 webpack 来做到这一点。假设我有一个工作人员文件:
// sample.worker.js
import { doSomeStuff } from './algorithm.js';
onmessage = function (e) {
const results = doSomeStuff(e.data)
postMessage({
id: e.data.id,
message: results',
});
};
相当简单,但这里重要的一点是,我的工作人员实际上是从算法文件导入一些代码,而算法文件又导入一些节点模块。我的工作人员在主模块中的某处使用,如下所示:
// plugin.js
import SampleWorker from 'worker-loader!./workers/dem.worker.js';
export function plugin(){
// do some stuff
const worker = new SampleWorker()
worker.postMessage(someData);
worker.onmessage = (event) => {};
}
我的 webpack 配置如下所示:
module.exports = {
entry: './src/index',
output: {
path: path.resolve(__dirname, 'build'),
filename: 'my-plugin.js',
},
resolve: {
extensions: ['.ts', '.tsx', '.js', '.json'],
},
module: {
rules: [
{
test: /\.worker\.js$/,
loader: 'worker-loader',
options: {
inline: 'fallback',
},
},
{
test: /\.(ts|js)x?$/,
exclude: /node_modules/,
loader: 'babel-loader',
},
],
},
externals: { ... },
plugins: { ... }
};
这不能按原样工作 - webpack 尝试将主包和每个工作脚本文件捆绑在同一名称下。更改为filename: '[name].js'
under output
修复了这个问题,但给了我很多文件 - 一个用于主包,另一个文件用于源代码中的每个工作文件。
阅读 webpack 选项后,我认为使用inline: 'fallback'
选项实际上会为每个工作人员创建一个 Blob 并将其捆绑到主输出文件中。但这并没有发生。
到目前为止,我的解决方案是将我的工作人员写成 blob,如下所示:
// workers.js
const workerblob = new Blob([`
// cannot import in a blob!
// have to put algorithm.js code here, copy in any external module code here
onmessage = function (e) {
const results = doSomeStuff(e.data)
postMessage({
id: e.data.id,
message: results,
});
};
`])
export const sampleWorker = URL.createObjectURL(workerblob);
// my-plugin.js
import { sampleWorker } from 'workers.js'
const worker = new Worker(sampleWorker)
这实际上是有效的 - webpack 现在输出 1 个包含工作代码的单个文件。使用此的修改版本这个答案 https://stackoverflow.com/a/19201292/12010984,我至少可以将我的代码放在function( ...code... ){}.toString()
格式,所以我至少可以得到智能感知、语法突出显示等。但我不能使用导入。
如何使用 webpack 捆绑我的工作人员,以便整个捆绑包最终包含在 1 个文件、工作人员代码等中?