create-react-app 在使用Typescript和Webpack 5时,不支持Web worker?

6za6bjd0  于 2个月前  发布在  React
关注(0)|答案(8)|浏览(47)

Describe the bug

Webpack 5 has deprecated 'worker-loader'
When using the suggested webpack 5 compat loader API such as

const worker = new Worker(new URL('./test.worker.ts', import.meta.url));  
worker.postMessage("test");

The CRA loaders @pmmmwh/react-refresh-webpack-plugin and babel-loader fails, and instead it returns with error

'You may need an additional loader to handle the result of these loaders.'

snvhrwxg

snvhrwxg1#

这个问题已经被自动标记为过时,因为它没有任何最近的活动。如果没有发生任何进一步的活动,它将在5天后被关闭。

2skhul33

2skhul332#

我发现我可以在webpack 5和create-react-app v5中使用Web Worker,并在这里提供一个深思熟虑的示例https://webpack.js.org/guides/web-workers/
基本仓库示例https://github.com/cmdcolin/cra-webpack5-web-worker-example
@toeryn 你提到使用react-scripts 4,但这个线程是关于webpack 5的

jfewjypa

jfewjypa3#

上面的仓库也支持TypeScript。

qcuzuvrc

qcuzuvrc4#

当你测试时,来自cmdcolin的示例会抛出一个错误:
npm test
Jest遇到了一个意外的标记

C:\Dev\Tests\cra-webpack5-web-worker-example-master\src\App.tsx:19
const worker = new Worker(new URL('./deep-thought.ts', import.meta.url));
juzqafwq

juzqafwq5#

感谢指出这个问题@ninichki,我没有尝试使用测试套件,但我也遇到了同样的错误。这可能与jest和esm模块支持有关,不确定修复方法是什么。

7fhtutme

7fhtutme6#

这真的很无聊。我处于一种情况:

  • 我坚持使用cra4来运行webworkers。
  • 使用craco在这些webworkers中加载wasm。
  • 使用替代的serve web服务器,因为与提供的serve版本相比,wasm mime类型是错误的。

我正在寻找cra 5.0,以便了解它是否可以简化我的pb,但它没有!

yjghlzjz

yjghlzjz7#

@cmdcolin ,我尝试了你的webworker,它可以工作。

zte4gxcn

zte4gxcn8#

感谢指出这个问题 @ninichki,我没有尝试使用测试套件,但我也遇到了相同的错误。这可能与jest和esm模块支持有关,不确定修复方法是什么。

仅供参考,我在运行 jest 时通过在整个测试套件中模拟 new URL 函数来修复了这个错误:

// getWebWorker.ts

// In it's own file so that it can be individually mocked in tests
// in a way that does not force jest to read the file first (eg, jest's requireActual)
// because import.meta.url is not supported in jest
export const getWebWorkerURL = (workerURL: string) =>
    new URL(workerURL, import.meta.url);
// setupTests.js

// mocked because import.meta.url is not supported in jest
jest.mock("./getWebWorkerURL", () => ({
    getWebWorkerURL: () => "test",
}));

我们没有任何测试会测试web worker、其输出或我们的应用程序在web worker完成工作之前的情况,所以这主要是为了阻止错误,而不是一个完整的、有用的模拟。
尽管如此,我希望这对将来的某个人有所帮助。

编辑:上述方法似乎在生产环境中引起了一些奇怪的问题,代码会在本地文件系统中查找web worker,而不是从它应该来自的 blob 中获取。解决方法似乎是模拟整个 new Worker 调用,而不是动态地将URL传递给worker。:

// getPointBoundaryRelationshipWorker.ts

// In it's own file so that it can be individually mocked in tests
// in a way that does not force jest to read the file first (eg, jest's requireActual)
// because import.meta.url is not supported in jest
// Hardcoding the path to the worker file is not ideal, but it's the only way to get it to work,
// something something webpack
export const getPointBoundaryRelationshipWorker = () =>
    new Worker(
        new URL("./pointBoundaryRelationshipWorker.ts", import.meta.url)
    );
// setupTests.js

// mocked because import.meta.url is not supported in jest
// See https://github.com/facebook/create-react-app/issues/11651#issuecomment-1292461098
jest.mock("./workers/getPointBoundaryRelationshipWorker", () => ({
    getPointBoundaryRelationshipWorker: () => "test",
}));

相关问题