NX Workspace升级Angular 14后Jest单元测试无法运行问题
不需要等Nx官方发布新版本,所有问题都是迁移流程不规范、配置位置错误导致的,按以下步骤修复即可:
1. 修正迁移流程,对齐兼容依赖
手动修改package.json版本号、直接跨大版本执行nx migrate latest的操作是问题根源:Nx迁移脚本是逐版本执行依赖对齐、配置修改的,跨大版本跳级+手动改版本会跳过所有必要的配置更新,直接导致依赖冲突。
先清理错误修改:
- 删除根目录下
node_modules文件夹、包管理器锁文件(package-lock.json/yarn.lock/pnpm-lock.yaml) - 将package.json中所有手动修改过的Angular、Jest相关版本回退到工作区刚创建时的初始状态
- 执行以下命令,指定迁移到Angular14对应的Nx14最终稳定版,不要直接迁移到latest(会跨多个大版本):
nx migrate 14.8.8 npm install nx migrate --run-migrations
这一步执行完成后,Nx会自动将所有Angular、Jest相关依赖对齐到互相兼容的版本,不需要手动调整任何版本号。
2. 修正Jest测试环境配置
在根目录jest.config.js中添加testEnvironment的操作无效:Nx采用多项目配置结构,根目录的Jest配置不会被子项目继承,testEnvironment配置必须加在每个子项目自己的Jest配置文件中。
- 确认
jest-environment-jsdom已安装,版本与本地Jest大版本保持一致即可 - 打开对应项目的Jest配置文件(示例demo项目路径为
apps/demo/jest.config.ts),在配置项中添加testEnvironment: 'jsdom',示例配置如下:
module.exports = { displayName: 'demo', preset: '../../jest.preset.js', setupFilesAfterEnv: ['<rootDir>/src/test-setup.ts'], // 新增以下配置,所有需要跑单测的项目都要在自己的jest配置中加这行 testEnvironment: 'jsdom', // 以下原有配置保持不变 globals: { 'ts-jest': { tsconfig: '<rootDir>/tsconfig.spec.json', stringifyContentPathRegex: '\\.(html|svg)$', } }, coverageDirectory: '../../coverage/apps/demo', transform: { '^.+\\.(ts|mjs|js|html)$': 'jest-preset-angular' }, transformIgnorePatterns: ['node_modules/(?!.*\\.mjs$)'], snapshotSerializers: [ 'jest-preset-angular/build/serializers/no-ng-attributes', 'jest-preset-angular/build/serializers/ng-snapshot', 'jest-preset-angular/build/serializers/html-comment', ] };
3. 修正测试启动文件引入顺序
打开项目下的src/test-setup.ts文件,确保jest-preset-angular的引入放在文件最顶部,任何其他代码都不能放在该引入之前,顺序错误会导致模块解析失败、DOM环境未定义等问题:
// 第一行必须是该引入 import 'jest-preset-angular/setup-jest'; // 其他全局测试配置放在该行之后
4. 清理缓存后重跑测试
执行以下命令清理Nx和Jest的缓存,再运行测试即可:
nx reset npx jest --clearCache npm run nx run-many -- --target=test --projects=demo --watch=false
注意:测试命令中附带的--browsers=ChromeHeadless是Karma runner的参数,Jest测试不需要启动Chrome浏览器,该参数加了也不会生效,可以删掉。
如果执行后仍有依赖冲突,运行npm ls jest-preset-angular检查是否存在多版本共存问题,Nx14.8.8对应的兼容Jest相关版本为jest-preset-angular@12.2.3、jest@28.1.3、ts-jest@28.0.8,不要手动升级到更高的大版本,跨大版本无兼容保证。
内容的提问来源于stack exchange,提问作者Pieterjan

