2

我正在编写一个 npm 包,它是流行库leafletjs 的插件。我正在使用 webpack 来捆绑包。我希望这个包能够根据命令生成和销毁一些网络工作者。网络工作者代码是我的源文件的一部分。但我希望能够将我的包作为 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'underoutput解决了这个问题,但给了我很多文件 - 一个用于主包,另一个文件用于我的源代码中的每个工作文件。

阅读 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 个包含工作代码的单个文件。使用这个答案的修改版本,我至少可以将我的代码放在一个function( ...code... ){}.toString()格式中,所以我至少可以获得智能感知、语法突出显示等。但我不能使用导入。

我如何使用 webpack 捆绑我的工作人员,以便整个捆绑包最终包含在 1 个文件、工作人员代码和所有内容中?

4

0 回答 0