如何在 WebWorker 上使用 React 组件

How to use React components on WebWorker

我正在 https://react-pdf.org/ 使用 react-pdf 包创建一个 PDF 生成器。将 react-pdf 组件转换成 pdf 的过程阻塞了主线程,所以我想在一个单独的工作线程上将它们转换。

我正在使用带有 worker-loader 的 create-react-app 来识别 WebWorker 文件。我很难想出一种方法将 React 组件导入 Webworker 并使用 react-pdf 提供的 pdf(Component).toBlob() 方法转换它们。 pdf(Component).toBlob() 将 React 组件作为输入并输出 blob 文件,这意味着工作人员必须以某种方式能够加载 React 组件。当没有包含 React 组件时,WebWorker 可以正常工作。

我天真地尝试将 React 组件导入 WebWorker 并尝试了 运行 转换方法:

pdf(<Component />).toBlob().then(blob=>{
   ...
  }) 

导致模块解析错误:

Uncaught Error: Module parse failed: Unexpected token (14:8)
File was processed with these loaders:
 * ./node_modules/eslint-loader/index.js
You may need an additional loader to handle the result of these loaders.

任何帮助将不胜感激。

编辑: 我正在使用 create-react-app 默认 webpack 配置,并添加了 worker-loader,它检测 .worker.js 文件并将它们注册为 Webworker。我使用 react-app-rewired 包添加了工作加载器:

module.exports = function override(config, env) {
    config.module.rules.push({
        test: /\.worker\.js$/,
        use: { loader: 'worker-loader' }
      })
      config.output['globalObject'] = 'this';
    return config;
  }

这个回答是我们在聊天中讨论的延伸。

这里手头的问题是覆盖函数的 .push()。如前所述 in the MSDN documentation:

The push() method adds one or more elements to the end of an array and returns the new length of the array.

实际上 config.module.rules.push() 是在规则数组的末尾添加加载程序,因此首先处理 React 代码,然后是 worker.js

Ali Zeaiter 发现解决方案是使用 .unshift() (cf. doc) 而不是 .push() 以便将加载程序添加到规则数组中,从而首先处理 worker.js 文件.