Web Worker с импортированными модулями в React - PullRequest
0 голосов
/ 08 апреля 2020

Я пытаюсь заставить веб-работника предотвратить срыв основного потока React. Работник должен читать изображения и делать разные вещи.

Приложение было создано с использованием create-react-app.

В настоящее время у меня есть

WebWorker.js

export default class WebWorker {
    constructor(worker) {
        const code = worker.toString();
        const blob = new Blob(['('+code+')()'], {type: "text/javascript"});
        return new Worker(URL.createObjectURL(blob),  {type: 'module'});
    }
}

readimage.worker.js

import Jimp from "jimp";

export default () => {
    self.addEventListener('message', e => { // eslint-disable-line no-restricted-globals
        if (!e) return;
        console.log('Worker reading pixels for url', e.data);
        let data = {};

        Jimp.read(e.data).then(image => {
            // jimp does stuff
            console.log('Worker Finished processing image');
        })

        postMessage(data);
    })
};

А затем в моем компоненте React AppContent.js у меня есть импорт WebWorker из "./workers/WebWorker"; импортировать readImageWorker из. не определено

Как правильно импортировать модуль в веб-рабочий?

РЕДАКТИРОВАТЬ:

В соответствии с предложениями от Kaiido, я попытался установить worker-loader и отредактировал мой webpack.config. js на следующее:

module.exports = {
    module: {
        rules: [
            {
                test: /\.worker\.js$/,
                use: { loader: 'worker-loader' }
            }
        ]
    }
};

Но когда я его запускаю, я все равно получаю ошибку

Uncaught ReferenceError: jimp__WEBPACK_IMPORTED_MODULE_0__ не определено

1 Ответ

0 голосов
/ 08 апреля 2020

Я не слишком увлечен React, поэтому не могу сказать, является ли модуль-Worker лучшим способом для go (возможно, worker-loader будет лучшим решением), но Что касается последней полученной ошибки, то это потому, что вы не установили type вашего BLOB-объекта при его создании.

В этом случае это имеет значение, поскольку оно определяет тип содержимого обозревателя. устанавливается при обслуживании API-интерфейсов, которые его выбирают.
Здесь Firefox немного более мягок и как-то позволяет это, но Chrome требователен и требует, чтобы вы установили эту опцию type на один из множества javascript MIME-типы.

const script_content = `postMessage('running');`;

// this one will fail in Chrome
const blob1 = new Blob([script_content]); // no type option
const worker1 = new Worker(URL.createObjectURL(blob1), { type: 'module'});
worker1.onerror = (evt) => console.log( 'worker-1 failed' );
worker1.onmessage = (evt) => console.log( 'worker-1', evt.data );
// this one works in Chrome
const blob2 = new Blob([script_content], { type: "text/javascript" });
const worker2 = new Worker(URL.createObjectURL(blob2), { type: 'module'});
worker2.onerror = (evt) => console.log( 'worker-2 failed' );
worker2.onmessage = (evt) => console.log( 'worker-2', evt.data );

Но теперь, когда эта ошибка исправлена, вы столкнетесь с другой ошибкой, потому что формат import lib from "libraryname" все еще не поддерживается в браузерах, поэтому вам придется замените "libraryname" на путь к вашему фактическому файлу сценария, учитывая, что он будет относительно базового URI вашего работника, то есть, вероятно, источника вашей главной страницы.

...