React Vite中使用Web Worker时'import.meta'非模块环境报错求助
React + TypeScript + Vite 中 Web Worker 问题的可行解决方案
方案一:使用 Vite 原生支持的独立 Worker 文件(推荐)
Vite 对 Web Worker 有原生支持,这种方式能解决类型提示、打包兼容、调试困难等问题,是最稳妥的实现方式。
- 创建独立 Worker 文件
在src/workers/目录下新建import.worker.ts,写入以下代码:
/// <reference lib="webworker" /> declare const self: DedicatedWorkerGlobalScope; self.onmessage = async (e) => { const { chanel, importMode, image, token } = e.data; const formData = new FormData(); formData.append("chanel", chanel); formData.append("import_mode", importMode); formData.append( "files", new Blob(image, { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }) ); console.log("Message received from main script"); // 使用配置的 API 地址,避免 Worker 上下文无法访问主环境变量的问题 const response = await fetch(import.meta.env.VITE_API_BASE_URL, { method: "post", body: formData, headers: { Authorization: `Bearer ${token}` } }); const data = await response.json(); console.log("Posting message back to main script"); self.postMessage(data); };
- 在主组件中导入并使用 Worker
import { useEffect } from "react"; import ImportWorker from "./workers/import.worker?worker"; // 创建 Worker 实例 const worker = new ImportWorker(); // 发送消息给 Worker worker.postMessage({ chanel: "your-chanel-value", importMode: "your-mode-value", image: yourImageBlobData, token: "your-auth-token" }); // 监听 Worker 返回的结果 worker.onmessage = (e) => { console.log("Received from worker:", e.data); // 处理业务逻辑 }; // 组件卸载时销毁 Worker,避免内存泄漏 useEffect(() => { return () => { worker.terminate(); }; }, []);
- 环境变量配置
在项目根目录的.env文件中添加 API 地址配置:
VITE_API_BASE_URL=https://your-api-domain.com
方案二:修复原有 Blob 动态生成方式
如果坚持使用动态生成 Blob 的方式,需要解决环境变量无法访问、语法兼容等问题:
修改后的代码:
const workercode = (apiBaseUrl: string) => { self.onmessage = async function (e) { const { chanel, importMode, image, token } = e.data; const formData = new FormData(); formData.append("chanel", chanel); formData.append("import_mode", importMode); formData.append( "files", new Blob(image, { type: "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet" }) ); console.log("Message received from main script"); const response = await fetch(apiBaseUrl, { method: "post", body: formData, headers: { Authorization: `Bearer ${token}` } }); const data = await response.json(); console.log("Posting message back to main script"); self.postMessage(data); }; }; // 将 API 地址作为参数注入到 Worker 代码中 let code = `(${workercode.toString()})('${import.meta.env.VITE_API_BASE_URL}');`; const blob = new Blob([code], { type: "application/javascript" }); const WorkerScript = URL.createObjectURL(blob); export default WorkerScript;
使用方式:
import WorkerScript from "./worker-script"; const worker = new Worker(WorkerScript); // 后续消息发送、监听逻辑同方案一
内容的提问来源于stack exchange,提问作者Minh Quang Lê
相关产品推荐
相关产品推荐

