Jest与Selenium 4的ES6兼容性问题:ReferenceError: require is not defined
我太懂你这种左右为难的感觉了——一边Selenium 4硬要ES6模块语法,另一边Jest在ES模块模式下又出require is not defined的报错,2023年还搞这种兼容问题确实头疼!不过别慌,这不是Jest和Selenium天生不兼容,是咱们没摸透Jest对ES模块的适配规则,下面给你一步步解决:
问题根源
当你用--experimental-vm-modules启动Jest时,整个环境切换到了ES模块模式,但Jest的传统jest.mock()API内部还是依赖CommonJS的require,直接用就会触发这个报错。咱们得换用Jest为ES模块专门提供的mock方式,同时调整配置适配ES模块规则。
具体解决步骤
1. 修正Jest配置文件
你的jest.config.js现在的配置有点冗余,改成下面这样,专门适配ES模块:
export default { testEnvironment: 'node', transform: {}, // 禁用Jest默认的CommonJS转换 extensionsToTreatAsEsm: ['.js'], // 告诉Jest把.js文件当作ES模块处理 moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1' // 处理ES模块导入时的.js后缀问题 } }
把没用的ts-jest预设删掉,毕竟你没用到TypeScript;新增的两个配置项是让Jest完全适配ES模块的导入逻辑。
2. 改造测试文件的Mock写法
ES模块是静态加载的,不能用传统的jest.mock(),得换成Jest 29+支持的jest.unstable_mockModule(别担心,虽然带unstable,但实际项目里用着很稳),同时调整导入逻辑:
import * as beCalls from '../utils/backendCalls.js' import { expect, jest, test } from '@jest/globals' // 用ES模块专属的mock方法替代jest.mock await jest.unstable_mockModule('axios', () => ({ default: { get: jest.fn() } })) // Mock完成后必须重新导入axios,才能拿到mock后的实例 const mockedAxios = (await import('axios')).default test('should fetch users', async () => { const coaches = [ { firstName: 'Bob', lastName: 'Kelso' }, { firstName: 'John', lastName: 'Doe' }, ] const resp = { data: coaches } mockedAxios.get.mockResolvedValue(resp) // 注意调用的是beCalls里导出的getCoachesList,还要传area参数哦 const data = await beCalls.getCoachesList('test-area') expect(data).toEqual(coaches) })
另外你之前测试里直接调用getCoachesList()是错的,这个函数是在beCalls对象里导出的,得加上前缀;还有getCoachesList需要area参数,别忘了传。
3. 给package.json加关键配置
在package.json里加上"type": "module",告诉Node.js整个项目都用ES模块,这是Selenium和Jest兼容的基础:
{ "type": "module", "scripts": { "jestTests": "node --experimental-vm-modules node_modules/jest/bin/jest.js" }, // ...其他依赖项 }
做完这三步,再跑npm run jestTests应该就能正常执行测试,同时也不影响Selenium的ES6语法使用了。
备注:内容来源于stack exchange,提问作者Don Diego

