在React中创建一个Web worker

时间:2017-11-24 14:32:19

标签: reactjs webpack web-worker create-react-app

我有一个使用create-react-app创建的React应用程序,而不是已弹出。我试图使用网络工作者。我已经尝试过worker-loader包(https://github.com/webpack-contrib/worker-loader)。

如果我尝试使用开箱即用的工作加载程序(import Worker from 'worker-loader!../workers/myworker.js';),我会收到错误消息,告诉我创建反应应用程序不支持Webpack加载器,我已经知道了。

解决方案是弹出应用程序(我不想这样做)并编辑webpack.config.js还是在React应用程序中使用Web worker还有其他方法吗?

编辑:我在这里找到了解决方案:https://github.com/facebookincubator/create-react-app/issues/1277(由yonatanmn发布)

3 个答案:

答案 0 :(得分:7)

正如我在上述问题的编辑中写的那样,我在这里找到了解决方案:https://github.com/facebookincubator/create-react-app/issues/1277

这是一个有效的例子:

// worker.js
const workercode = () => {

    self.onmessage = function(e) {
        console.log('Message received from main script');
        var workerResult = 'Received from main: ' + (e.data);
        console.log('Posting message back to main script');
        self.postMessage(workerResult);
    }
};

let code = workercode.toString();
code = code.substring(code.indexOf("{")+1, code.lastIndexOf("}"));

const blob = new Blob([code], {type: "application/javascript"});
const worker_script = URL.createObjectURL(blob);

module.exports = worker_script;

然后,在需要使用Web worker的文件中:

import worker_script from './worker';
var myWorker = new Worker(worker_script);

myWorker.onmessage = (m) => {
    console.log("msg from worker: ", m.data);
};
myWorker.postMessage('im from main');

答案 1 :(得分:2)

是的,可以使用custom-react-scripts

来使用自定义webpack配置

要在现有custom-react-scripts项目中使用create-react-app,如本issue中所述,您需要做的是:

  • 从package.json中删除 react-scripts:

    "devDependencies": {
        "react-scripts": "0.6.1"
    },
    
  • 运行npm install --save-dev *your-custom-react-scripts*

有关更详细的说明,请查看@kitze's article 和他自己的custom-react-scripts,包括对以下功能的内置支持:

  • 装饰员
  • babel-preset-stage-0
  • 萨斯
  • CSS模块
  • Sass模块
  • 较少的模块
  • 手写笔模块

答案 2 :(得分:0)

如果您遇到有关“ this”,“ self”,“ window”主题的问题,那么this comment in the github issue可以很好地补充dnmh的答案。

就我而言,以下解决了我所有的麻烦:

您无需触摸此文件,只需保留它即可。

//WebWorkerEnabler.js
export default class WebWorkerEnabler {
    constructor(worker) {
         let code = worker.toString();
         code = code.substring(code.indexOf("{") + 1, code.lastIndexOf("}"));

         const blob = new Blob([code], { type: "application/javascript" });
         return new Worker(URL.createObjectURL(blob));
    }
}

这是您运行后台任务的地方

// WebWorker.js
export default function WebWorker(args) {
    let onmessage = e => { // eslint-disable-line no-unused-vars
         // THIS IS THE PLACE YOU EMBED YOUR CODE THAT WILL RUN IN BACKGROUND        
         postMessage("Response");
    };
}

这是WebWorker与其余代码的连接。您可以从componentDidMount函数下方向WebWorker发送和接收数据。

//BackgroundTaskRunner.js
import * as React from 'react';
import WebWorkerEnabler from './WebWorkerEnabler.js';
import WebWorker from './WebWorker.js';
const workerInstance = new WebWorkerEnabler(WebWorker);
export default class BackgroundTaskRunner extends React.Component {
    componentDidMount(){
        workerInstance.addEventListener("message", e => {
            console.log("Received response:");
            console.log(e.data);
        }, false);
        workerInstance.postMessage("bar");
    }
    render() {
        return (
                <React.Fragment>
                    {"DEFAULT TEXT"}
                </React.Fragment>
        );
    }
}