Duplicate path segment error in dynamic imports in Web Worker (react-scripts 5, webpack 5)
Created by: kenlyon
Describe the bug
When my app attempts to dynamically import something via a Web Worker, the request has the static/js
part of the path repeated, resulting in a 404 error.
I can reproduce this with a clean install of the typescript template of create-react-app.
The two main factors required are:
- A web worker (I'm using webpack 5's syntax with
import.meta.url
.) - A
homepage
attribute set inpackage.json
. If the app is served directly vialocalhost
it seems the faulty part of the resolution doesn't happen. Our production environment uses a subdomain, though, so I need thehomepage
attribute,
Did you try recovering your dependencies?
I've reproduced this with a clean install. The dependencies are not an issue.
I'm using yarn 1.22.18. I believe the same problem would happen with npm.
$ yarn --version
1.22.18
Which terms did you search for in User Guide?
- webpack 5
- web worker
Environment
Environment Info:
current version of create-react-app: 5.0.1
running from C:\Users\<my-user-name>\AppData\Local\Yarn\Data\global\node_modules\create-react-app
System:
OS: Windows 10 10.0.19041
CPU: (8) x64 Intel(R) Core(TM) i7-9700 CPU @ 3.00GHz
Binaries:
Node: 14.19.0 - C:\Program Files\nodejs\node.EXE
Yarn: 1.22.18 - C:\Program Files\nodejs\yarn.CMD
npm: 6.14.16 - C:\Program Files\nodejs\npm.CMD
Browsers:
Chrome: Not Found
Edge: Spartan (44.19041.1266.0), Chromium (99.0.1150.52)
Internet Explorer: 11.0.19041.1202
npmPackages:
react: ^18.1.0 => 18.1.0
react-dom: ^18.1.0 => 18.1.0
react-scripts: 5.0.1 => 5.0.1
npmGlobalPackages:
create-react-app: Not Found
Steps to reproduce
- Add a Web Worker to your project, as described in the webpack 5 docs.
- Within the Web Worker, use a dynamic
import()
statement to load something from elsewhere. It can be a local module or something fromnode_modules
. - Consume the web worker somewhere.
- You also need the
homepage
property set inpackage.json
to reproduce this.
(I have fuller details below in the Reproducible demo section.)
Expected behavior
The dynamic import should work.
Actual behavior
The dynamic import fails with a 404 error. A network error is shown. The path includes static/js/static/js
, where it should just be static/js
.
Reproducible demo
- Make a new app using "create react app" with the TypeScript template:
yarn create react-app example-app --template typescript
- Edit the
package.json
file, adding these two lines:
"type": "module",
"homepage": ".",
- Add a new file called
src/OtherModule.ts
with the following content:
export const message = "Message from another module.";
- Add a new file called
src/TestWorker.worker.ts
with the following content:
/* eslint no-restricted-globals: 0 */
const worker: Worker = self as any;
worker.addEventListener("message", async (event) => {
const data = event.data;
console.log("[Worker] Received:", data);
// This dynamic import is put into a separate chunk by webpack.
// In a production build, the loading of this module fails with a duplicate "static/js" in the path.
const { message } = await import("./OtherModule");
worker.postMessage(message);
});
export {};
- Add the following code to
src/App.tsx
, just before thereturn
statement:
useEffect(() => {
const worker = new Worker(new URL("./TestWorker.worker.ts", import.meta.url));
worker.onmessage = (event: MessageEvent<any>) => {
console.log(`[App] Received:`, event.data);
};
// The expected behaviour is for the worker to send a message in response to this one.
// In reality, there's an error loading one of the chunks.
worker.postMessage("abc");
});
- Add
useEffect
to the import from'react'
insrc/App.tsx
:
import React, { useEffect } from 'react';
- Build the app:
yarn build
- Serve the
build
folder via a web server. - Visit the site and open the console.
Expected behavior:
The console should show log output of the App and the Worker receiving messages from each other.
[Worker] Received: abc
[App] Received: Message from another module.
Actual behavior:
A network error is shown. The path includes static/js/static/js
, where it should just be static/js
.
[Worker] Received: abc
GET http://localhost/example-app/static/js/static/js/975.6b1d0bce.chunk.js
[HTTP/1.1 404 Not Found 0ms]
NetworkError: A network error occurred.