admin管理员组文章数量:1415139
I'm trying to make a web worker to prevent stalling the React main thread. The worker is supposed to read an image and do various things.
The app was created using create-react-app
.
Currently I have
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.worker\.js$/,
use: { loader: 'worker-loader' }
}
]
}
};
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);
})
};
And then in my React ponent AppContent.js
I have
import WebWorker from "./workers/WebWorker";
import readImageWorker from './workers/readimage.worker.js';
export default function AppContent() {
const readWorker = new ReadImageWorker(readImageWorker);
readWorker.addEventListener('message', event => {
console.log('returned data', event.data);
setState(data);
});
// callback that is executed onClick from a button ponent
const readImageContents = (url) => {
readWorker.postMessage(url);
console.log('finished reading pixels');
};
}
But when I run it, I get the error
Uncaught ReferenceError: jimp__WEBPACK_IMPORTED_MODULE_0__ is not defined
How can I properly import a module into a web worker?
I'm trying to make a web worker to prevent stalling the React main thread. The worker is supposed to read an image and do various things.
The app was created using create-react-app
.
Currently I have
webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.worker\.js$/,
use: { loader: 'worker-loader' }
}
]
}
};
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);
})
};
And then in my React ponent AppContent.js
I have
import WebWorker from "./workers/WebWorker";
import readImageWorker from './workers/readimage.worker.js';
export default function AppContent() {
const readWorker = new ReadImageWorker(readImageWorker);
readWorker.addEventListener('message', event => {
console.log('returned data', event.data);
setState(data);
});
// callback that is executed onClick from a button ponent
const readImageContents = (url) => {
readWorker.postMessage(url);
console.log('finished reading pixels');
};
}
But when I run it, I get the error
Uncaught ReferenceError: jimp__WEBPACK_IMPORTED_MODULE_0__ is not defined
How can I properly import a module into a web worker?
Share Improve this question asked Apr 9, 2020 at 4:49 cclloydcclloyd 9,25518 gold badges68 silver badges122 bronze badges 3- import in workers is not widely supported yet - looks like Chrome, Edge, and node right now, developer.mozilla/en-US/docs/Web/JavaScript/Reference/…. have you tried importScripts? developer.mozilla/en-US/docs/Web/API/Web_Workers_API/… – James South Commented Apr 9, 2020 at 5:43
-
@JamesSouth I looked at using importScripts, but besides it gives a linting error (which I can set to ignore), where am I supposed to import the module from? I can't use the relative path in the node_modules folder, nor just
jimp
. The only way to use importScripts with it is to copy the module to thepublic
folder and then use an absolute url (such ashttp://localhost:3000/jimp.js
). Is there a better way to do that? – cclloyd Commented Apr 9, 2020 at 9:52 - 2 Maybe worker-plugin github./GoogleChromeLabs/worker-plugin instead of worker-loader would help?? – James South Commented Apr 9, 2020 at 21:15
2 Answers
Reset to default 1You might have a problem with webpack importing your worker in the WebWorker class. Try returning new Worker(URL.createObjectURL(blob), import.meta.url));
like how it's documented in the webpack docs.
In my next.js typescript project, I use this code and answer in my use case:
function in onClick prop on the element at next.js
async () => {
const testWorker = new Worker(
new URL("./test.worker.ts", import.meta.url), {
name: "test",
type: "module",
});
testWorker.onmessage = function (event) {
console.log("data:", event.data, "\n", "event:", event);
};
testWorker.postMessage([0, 1, 2, 3, 4, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15]);
}
test.worker.ts
self.onmessage = function ({ data }) {
self.postMessage((data as number[]).map((d) => d * 10));
};
export {};
本文标签:
版权声明:本文标题:javascript - Web Worker not working when importing module, even while using worker-loader - Stack Overflow 内容由网友自发贡献,该文观点仅代表作者本人, 转载请联系作者并注明出处:http://www.betaflare.com/web/1745229749a2648769.html, 本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌抄袭侵权/违法违规的内容,一经查实,本站将立刻删除。
发表评论