React项目使用 Web Worker

缘起

Web Worker 老生常谈了 ------ 它允许你在主线程之外创建额外的线程来执行任务,例如处理文件,埋点轮询,如何在 React 中使用呢 ?

webpack5^

JSX

typescript 复制代码
  useEffect(() => {
    const worker = new Worker(new URL('./wk.ts', import.meta.url));

    // set Worker Handle
    worker.onmessage = function (e: MessageEvent) {
      const result: string = e.data;
      console.log('Received result from Worker:', result);
    };

    // post Worker message
    worker.postMessage('hello from main thread');
  }, []);

wk.ts

typescript 复制代码
self.onmessage = function(e: MessageEvent) {
  const data: string = e.data;  
  //  This's Worker in data 
  const result: string = data.toUpperCase();
  
  // Post result to JSX
  self.postMessage(result);
};
  • import.meta 是一个内置在 ES 模块内部的对象,import.meta.url 表示一个模块在浏览器和 Node.js 的绝对路径。该特性属于 es2020 的一部分
  • new URL传入 path & base 写入内存

worker-loader

不是 webpack5^ 可以使用插件 Loader worker-loader

js 复制代码
module.exports = {
  module: {
    rules: [
      {
        // 以 .worker.js 结尾的文件将被 worker-loader 加载
        test: /\.worker\.(c|m)?js$/i,
        use: {
          loader: "worker-loader",
        },
      },
    ],
  },
};

or

js 复制代码
  chainWebpack(config) {
    config.module
      .rule('worker')
      .test(/\.worker\.ts$/)
      .use('worker-loader')
      .loader('worker-loader')
      .end();
  },

为了保证 worker 中的代码被 babel 转译,可以让 babel-loaderworker-loader 之前执行。ts-loader 同理

why import worker file ?

js 复制代码
import workPath from "./worker.js";
const worker = new Worker(workPath);

为什么不能直接这样导入worker 文件呢?

同样也是需要借助特定的 loader,类似于 file-loader。至于 worker-loader 则是将new Worker(workPath)的步骤内置到 loader 处理流程了,并导出一个函数,外面直接使用该函数即可创建指定的 Worker

js 复制代码
module.exports = function () {
  return new Worker(__webpack_public_path_ + "123abc.worker.js");
};

worker-loader 把文件转成类似👆

blobUrl

还有一种方式就是 ------ worker.js 的主函数转化为 blobUrl 导出,供主线程引用。该方法的好处是可以动态创建 worker

js 复制代码
// worker.js
const contentCode = function () {} // worker 脚本主函数
const blob = new Blob([contentCode.toString()], {type: 'text/javascript'});
export {url: URL.createObjectURL(blob)}


// main.js
import { url } from './worker.js'
const worker = new Worker(url);

Reference: worker-loader源码

相关推荐
转转技术团队13 分钟前
多代理混战?用 PAC(Proxy Auto-Config) 优雅切换代理场景
前端·后端·面试
南囝coding14 分钟前
这几个 Vibe Coding 经验,真的建议学!
前端·后端
gnip28 分钟前
SSE技术介绍
前端·javascript
yinke小琪42 分钟前
JavaScript DOM节点操作(增删改)常用方法
前端·javascript
枣把儿1 小时前
Vercel 收购 NuxtLabs!Nuxt UI Pro 即将免费!
前端·vue.js·nuxt.js
望获linux1 小时前
【Linux基础知识系列】第四十三篇 - 基础正则表达式与 grep/sed
linux·运维·服务器·开发语言·前端·操作系统·嵌入式软件
爱编程的喵1 小时前
从XMLHttpRequest到Fetch:前端异步请求的演进之路
前端·javascript
喜欢吃豆1 小时前
深入企业内部的MCP知识(三):FastMCP工具转换(Tool Transformation)全解析:从适配到增强的工具进化指南
java·前端·人工智能·大模型·github·mcp
豆苗学前端1 小时前
手把手实现支持百万级数据量、高可用和可扩展性的穿梭框组件
前端·javascript·面试
不见_1 小时前
不想再写周报了?来看看这个吧!
前端·命令行