【问题标题】:Web workers inside a JS library with Rollup带有 Rollup 的 JS 库中的 Web Worker
【发布时间】:2020-06-06 19:58:10
【问题描述】:

我正在 Typescript 中构建一个使用 Thread.js 网络工作者的 negamax 引擎。它是一个 npm 库,将由使用 webpack 构建的应用程序导入。

我正在使用 Rollup 构建引擎 - 如何导出 web-worker 文件,以便将它们作为单独的块复制到客户端的构建目录中?

【问题讨论】:

    标签: javascript webpack rollup


    【解决方案1】:

    有插件:Alorel/rollup-plugin-web-workerdarionco/rollup-plugin-web-worker-loader

    ..但我最终还是从头开始,为工作人员使用单独的构建配置。这只是让我更好地控制局势。

    附上我使用的rollup.config.worker.js

    rollup.config.mjs 导入此文件,并将其配置作为第一个构建配置。真正的构建配置使用 @rollup/plugin-replace 将 worker 的哈希值注入到加载它的代码中。

    /*
    * Rollup config for building web worker(s)
    *
    * Imported by the main rollup config.
    */
    import sizes from '@atomico/rollup-plugin-sizes'
    import resolve from '@rollup/plugin-node-resolve'
    import replace from '@rollup/plugin-replace'
    import { terser } from 'rollup-plugin-terser'
    
    import {dirname} from 'path'
    import {fileURLToPath} from 'url'
    
    const myPath = dirname(fileURLToPath(import.meta.url));
    
    const watch = process.env.ROLLUP_WATCH;
    
    const REGION = process.env.REGION;
    if (!REGION) throw new Error("'REGION' env.var. not provided");
    
    let loggingAdapterProxyHash;
    
    const catchHashPlugin = {
      name: 'my-plugin',
    
      // Below, one can define hooks for various stages of the build.
      //
      generateBundle(_ /*options*/, bundle) {
        Object.keys(bundle).forEach( fileName => {
          // filename: "proxy.worker-520aaa52.js"
          //
          const [_,c1] = fileName.match(/^proxy.worker-([a-f0-9]+)\.js$/) || [];
          if (c1) {
            loggingAdapterProxyHash = c1;
            return;
          }
          console.warn("Unexpected bundle generated:", fileName);
        });
      }
    };
    
    const pluginsWorker = [
      resolve({
        mainFields: ["esm2017", "module"],
        modulesOnly: true       // "inspect resolved files to assert that they are ES2015 modules"
      }),
      replace({
        'env.REGION': JSON.stringify(REGION),
        //
        preventAssignment: true   // to mitigate a console warning (Rollup 2.44.0); remove with 2.45?
      }),
      //!watch && terser(),
      catchHashPlugin,
    
      !watch && sizes(),
    ];
    
    const configWorker = {
      input: './adapters/logging/proxy.worker.js',
      output: {
        dir: myPath + '/out/worker',   // under which 'proxy.worker-{hash}.js' (including imports, tree-shaken-not-stirred)
        format: 'es',   // "required"
        entryFileNames: '[name]-[hash].js',   // .."chunks created from entry points"; default is: '[name].js'
    
        sourcemap: true,   // have source map even for production
      },
    
      plugins: pluginsWorker
    }
    
    export default configWorker;
    export { loggingAdapterProxyHash }
    

    在主配置中使用:

      replace({
        'env.PROXY_WORKER_HASH': () => {
          const hash= loggingAdapterProxyHash;
          assert(hash, "Worker hash not available, yet!");
          return JSON.stringify(hash);
        },
        //
        preventAssignment: true   // to mitigate a console warning (Rollup 2.44.0); remove with 2.45?
      }),
    

    ..在 Worker 加载代码中:

    const PROXY_WORKER_HASH = env.PROXY_WORKER_HASH;    // injected by Rollup build
    
    ...
    new Worker(`/workers/proxy.worker-${PROXY_WORKER_HASH}.js?...`);
    

    如果有人想获得整个 repo 的链接,请留言,我会在那里发布。它仍在不断变化中。


    编辑:

    写完答案后,我发现了这个:Building module web workers for cross browser compatibility with rollup(博客,2020 年 7 月)

    TL;DR 如果您希望为工作人员使用 EcmaScript 模块,请注意!截至今天,Firefox 和 Safari 不支持。 source 并且Worker 构造函数需要被告知worker 源是ESM。

    【讨论】:

      猜你喜欢
      • 2019-11-26
      • 1970-01-01
      • 2020-07-20
      • 1970-01-01
      • 2019-07-16
      • 1970-01-01
      • 1970-01-01
      • 2021-09-27
      • 1970-01-01
      相关资源
      最近更新 更多