1.配置 Umi.js
在 Umi.js 中,需要通过配置来扩展 Webpack 的功能。在项目根目录下修改 config/config.ts 文件:
export default defineConfig({
chainWebpack(config) {
config.module
.rule('worker')
.test(/\.worker\.ts$/)
.use('worker-loader')
.loader('worker-loader')
.end();
}
});
配置之后 worker.ts 文件将被 worker-loader 加载。
将 Worker 需要的依赖添加到 MFSU 的 exclude 配置中是因为 Module Federation 是通过 window 对象来共享模块的,所以在 worker 中不能使用 Module Federation 中的模块。
2.创建一个 Web Worker 文件
创建worker.ts 文件,编写 Web Worker 逻辑:
// src/utils/worker.ts
self.onmessage = function(e: MessageEvent) {
console.log('Worker: Message received from main script');
const result: number = e.data[0] * e.data[1];
if (isNaN(result)) {
self.postMessage('Please write two numbers');
} else {
console.log('Worker: Posting message back to main script');
self.postMessage(result);
}
};
3.在 React 组件中使用 Web Worker
在 React 组件中引入并使用 Web Worker:
import React, { useEffect, useState } from 'react';
const WorkerDemo: React.FC = () => {
const [workerResult, setWorkerResult] = useState(0);
useEffect(() => {
const worker = new Worker(new URL('@/utils/worker.ts', import.meta.url));
// Message posted to worker
worker.postMessage([2, 3]);
// Message received from worker
worker.onmessage = function (e: MessageEvent) {
setWorkerResult(e.data);
}
return () => {
worker.terminate(); // 组件卸载时终止 Web Worker
}
}, []);
return (
<div>
<h1>Web Worker Example</h1>
<p>Result from Worker: {workerResult}</p>
</div>
)
};
export default WorkerDemo;
import.meta 是一个内置在 ES 模块内部的对象,import.meta.url 表示一个模块在浏览器和 Node.js 的绝对路径。
new URL传入 path & base 写入内存。
使用 Web Worker,可以在后台线程中执行耗时的操作,而不会阻塞主线程,从而提升应用的响应速度。