TypeScript改造后GitHub CI中Jest在Node.js12+/14+下报module未定义
拆解你的GitHub CI测试异常问题
嘿,我之前也碰到过类似的Node.js版本差异导致的CI报错,咱们来一步步捋清楚问题出在哪:
首先,这个报错的核心是Node.js 12.x及以上版本对ES模块(ESM)的处理逻辑和10.x完全不一样。结合你的场景来看:
- 你把项目改成TypeScript兼容版本后,应该是在
package.json里加了"type": "module"字段(或者其他ESM相关配置)。这个配置会让Node.js 12+把所有.js文件默认当成ES模块加载,而不是传统的CommonJS模块。 - 但你的
jest.config.js用的是CommonJS的module.exports语法,ESM环境里根本没有module这个全局变量,所以直接抛出了ReferenceError: module is not defined。 - 至于Node.js 10.x能正常跑,是因为它对ESM的支持还处于实验性阶段,默认不会启用这个逻辑,还是会把
.js文件当作CommonJS处理,所以没触发报错。
几种快速修复方案
根据你的项目需求,选下面其中一种就行:
方案1:给jest配置文件改个后缀
最简单的办法是把jest.config.js重命名为jest.config.cjs。Node.js会自动识别.cjs后缀的文件是CommonJS模块,不管package.json里的"type"配置是什么。然后记得在package.json的测试命令里指定配置文件:
{ "scripts": { "test": "jest --config jest.config.cjs" } }
方案2:把jest配置改成ESM格式
如果你的项目整体想用ESM,那就把jest.config.js改成ESM的导出语法,把module.exports换成export default:
export default { preset: 'ts-jest', testEnvironment: 'node', testMatch: ['<rootDir>/**/__tests__/**/*.spec.ts'], testPathIgnorePatterns: ['/node_modules/'], coverageDirectory: './test-reports', coveragePathIgnorePatterns: ['node_modules', 'src/database', 'src/test', 'src/types'], reporters: ['default', 'jest-junit'], globals: { 'ts-jest': { diagnostics: false } } };
不过要注意,这种方式需要你的jest和ts-jest版本足够新,支持ESM配置文件,建议先升级一下这两个依赖。
方案3:移除ESM全局配置(如果不需要的话)
如果你的项目其实不需要全局启用ESM,直接删掉package.json里的"type": "module"字段就行。这样Node.js会默认把.js文件当作CommonJS处理,你的jest.config.js就能正常加载了。不过这个操作可能会影响其他TS相关配置,得先确认没问题再改。
为啥本地测试正常?
本地能跑通大概率是这几个原因之一:
- 你本地的Node.js版本低于12.x,和CI里的Node10.x行为一致;
- 或者本地Node版本高于12.x,但你的jest版本在本地环境里自动兼容了混合模块的情况;
- 也有可能你本地的
package.json里没加"type": "module",但CI环境里部署时带上了这个配置(比如你本地测试时没提交这个修改?不过这个可能性比较低)。
内容的提问来源于stack exchange,提问作者Mout Pessemier
相关产品推荐
相关产品推荐

