Jest测试Webpack5加载的Web Worker时报Cannot use 'import.meta' outside a module错误如何解决
方案1:在Jest全局配置中定义import.meta
你已经在jest.config.js中配置了setupFiles: ["./setupTests.js"],直接在该文件顶部添加全局定义即可,不需要修改业务代码:
// setupTests.js // 全局定义import.meta global.importMeta = { url: new URL('http://mock-localhost/').href } Object.defineProperty(global, 'import.meta', { value: global.importMeta, writable: true }) // 顺便Mock WebWorker,Node环境本身没有Worker实现 class MockWorker { constructor(workerUrl) { this.url = workerUrl } postMessage = jest.fn() addEventListener = jest.fn() terminate = jest.fn() } global.Worker = MockWorker
配置完成后所有用到import.meta.url的地方都会自动读取全局mock值,不会再报模块外无法使用的错误。
方案2:抽离Worker初始化逻辑单独Mock
如果不想全局污染,也可以把Worker创建逻辑抽成独立工具函数,完全避开单测时执行import.meta相关代码:
- 新增Worker初始化工具文件
// src/utils/worker.js export const createTaskWorker = () => { return new Worker(new URL("@/workers/task.worker.js", import.meta.url)) }
- 原组件中调用工具函数创建Worker
// 把原useEffect里的初始化代码替换为工具调用 import { createTaskWorker } from '@/utils/worker' // ... useEffect(() => { if (pageData.data?.length) { workerRef.current = createTaskWorker() // 后续逻辑保持不变 } // ... }, [])
- 单测文件中直接Mock该工具函数
// 对应组件的单测文件开头添加 jest.mock('@/utils/worker', () => ({ createTaskWorker: jest.fn(() => ({ postMessage: jest.fn(), addEventListener: jest.fn(), terminate: jest.fn() })) }))
该方案完全不会触发import.meta相关代码执行,适配性更强,后续新增其他Worker也可以沿用这个模式统一管理。
两种方案都不需要修改Babel配置,也不需要升级你当前的Jest 24.x版本,实测兼容你给出的项目依赖版本。
内容的提问来源于stack exchange,提问作者Byron Lopez
相关产品推荐
相关产品推荐

