webpack: Webpack 5: Library build with WebWrokers does not work with applications that are dependent on it

Bug report

What is the current behavior?

We have a core library based on React, that used among several applications that built on top of react-scripts. Our library contain various heavy computations that used among our applications. Adding new Worker construction in library, produces additional chunk in build result (what is quite expected). But when using component from a library that uses this WebWorker does not load worker script (a chunk from library). The WebWorker chunk does not exist in project build.

If the current behavior is a bug, please provide the steps to reproduce.

  1. Download project: https://github.com/tsarapke/proj.git. It use a library with WebWorker: https://github.com/tsarapke/lib
  2. yarn install
  3. yarn start

image

What is the expected behavior?

Project build should contain WebWorker chunk from a library. In accordance with provided example - it should print ‘Hello World’ in console when WebWorker post message.

Other relevant information: webpack version: webpack version: 5.22.0 Node.js version: v14.15.5 Operating System: Win10 Additional tools: Yarn

About this issue

  • Original URL
  • State: closed
  • Created 3 years ago
  • Reactions: 5
  • Comments: 52 (27 by maintainers)

Most upvoted comments

Our project has a similar issue. We are building a programming scratchpad that uses WebWorkers to evaluate arbitrary code. We then want to be able to include this scratchpad into other applications that want to run code locally.

The workers are correctly bundled into separate files to allow loading. However, upon spawning the workers, the application looks in the current directory for the bundle (for example /806.index.js) but the actual location is within the node_modules of your current project, i.e. /node_modules/@dodona/papyros/lib/806.index.js.

By copying the worker bundles into that location, they can be loaded, but this is of course far from ideal as you want your package to be plug-and-play.

EDIT: By using worker-loader, I managed to get it working. A big thanks to @lawrence-witt for this example repository. The idea is using worker-loader even while using webpack 5 with the following rule in your config:

{
	test: /\.worker\.ts?$/,
	loader: 'worker-loader',
	options: {
		inline: 'no-fallback'
	}
},

Import workers via

import Worker from './WorkerTimer.worker.ts';

and adding a default export to these workers

export default null as any;

This makes webpack generate a single bundle so no resolving errors take place, allowing me to publish my package as a library without any hindrances for the consumer.

@alexander-akait My goal with this issue is to provide better bundling support for workers . The current approach requires inlining workers using worker-loader, which causes the bundling output to be very large which causes latency. This gets worse if your library contains multiple workers that are not always all needed, it depends on the user’s action which worker needs to run. With the current approach, both are fetched upon loading the page instead of chunked. The issue lies in new Worker(…) that is by default outputted to some url that cannot be resolved anymore when including the library in a different package. Example in question is Papyros which is a library with workers to run the user’s code in different programming languages, that is then included in Dodona. I believe the other users in this thread have similar needs but they can elaborate where required.

thank you, I removed worker-loader from my project, looks like I need it back in again. Out of curiosity don’t you need to disable worker in

test: /\.ts?$/,
					loader: "ts-loader",
					exclude: /node_modules/,
					```

Likely not necessarry, but maybe it provides a 0.0001 ms speedup by not having to check that entire folder, just in case 😉