简体   繁体   中英

How to use a web-worker from an npm library into main webpack project

My project structure is like this:

moduleA -> Library that i publish to npm using Rollup

projectA -> My gatsby project that installs moduleA and uses it.

I'm using this library to bundle my workers with my other library code into the dist folder: https://github.com/darionco/rollup-plugin-web-worker-loader

Module A code:

workers/index.js

let webWorker = null;

if (typeof window !== "undefined") {
  webWorker = new Worker(new URL("./my.worker.js", import.meta.url), {
    type: "module",
  });
}

export default webWorker;

workers/my.worker.js

self.onmessage = (message) => {
  console.log("hii");
  self.postMessage("yes");
};

When I build the above library the result is this:

在此处输入图像描述

So you can see that the workers are correctly in the library's dist now. This all works great.

If we take a look into index.modern.module.js you can see this is the output for the worker code:

if (typeof window !== "undefined") {
  webWorker = new Worker(new URL("my.worker-f73c7cd4.js", import.meta.url), {
    type: "module"
  });
}

Now in my main project I have this webpack rule to convert the import.meta.url to a path otherwise webpack crashes as it does not recognize import.meta.url :

 config.module.rules.push({
  test: /\.jsx?$/,
  loader: require.resolve("@open-wc/webpack-import-meta-loader"),
});

I now run my main react project (which is built in gatsby & webpack) and this is the output in index.modern.module.js :

if (typeof window !== "undefined") {
  webWorker = new Worker(new URL("my.worker-8e6a623b.js", ({ url: getAbsoluteUrl('node_modules/@tracktak/dcf-react/dist/index.modern.module.js') }).url), {
    type: "module"
  });
}

Here's the network request, you can see it loans in but I'm pretty sure the path is wrong. It's just saying a 200 ok because it's going to 404 page I think:

在此处输入图像描述

And it gives me a console error:

Failed to load module script: The server responded with a non-JavaScript MIME type of "text/html". Strict MIME type checking is enforced for module scripts per HTML spec.

So, my question is. How do I load the web worker to the public folder for my Gatsby project (projectA). Do I need to use something like worker-loader here? I'm just not sure how it can work here because it's in my npm module and NOT in my project.

Any help would be great and I'd award a bounty!

Thanks

EDIT: It seems like worker-plugin is getting my closer to the solution. If I use this in my main project and modify the web workers in the dist output from this: new URL("my.worker-8e6a623b.js", ({ url: getAbsoluteUrl('node_modules/@tracktak/dcf-react/dist/index.modern.module.js') }).url) to this: new URL("my.worker-8e6a623b.js") it works fine as worker-plugin only accepts string arguments.

However this isn't a sustainable solution because obviously I don't want to modify dist files.

Updated:

Verify the dist folder contents are correct. I'm surprised to see files from old builds (multiple hash ids). Clean folder, then generate all scripts (for performance reasons, you might want to only do this on production builds.)

Then when you npm publish the files, verify npm picked up what you expect.

There's an alternate way to make sure it's not related to npm's selective file bundling. Use the GitHub repo URL to npm install <github repo URL> .

Original response:

I believe you need worker-loader .

I've used comlink & worker-loader to help smooth over Webpack worker bundling.


The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM