Angular 9迁移至Jest时出现‘Zone is not defined’错误求助
我遇到过好几个Angular 9转Jest的项目都踩过这个Zone未定义的坑,大概率是你的测试环境初始化环节没把Zone的测试包正确加载进来,结合你的配置步骤,给你几个具体的排查和修复步骤:
1. 确保setupJest.ts正确导入Zone测试包
你的setupJest.ts必须优先导入zone.js/dist/zone-testing(不是普通的zone.js),并且正确初始化Angular测试环境。完整的setupJest.ts应该是这样的:
// 必须第一行导入这个Zone测试专用包 import 'zone.js/dist/zone-testing'; import { getTestBed } from '@angular/core/testing'; import { BrowserDynamicTestingModule, platformBrowserDynamicTesting } from '@angular/platform-browser-dynamic/testing'; declare const require: { context(path: string, deep?: boolean, filter?: RegExp): { keys(): string[]; <T>(id: string): T; }; }; // 初始化Angular测试环境 getTestBed().initTestEnvironment( BrowserDynamicTestingModule, platformBrowserDynamicTesting() ); // 加载所有.spec.ts测试文件 const context = require.context('./', true, /\.spec\.ts$/); context.keys().map(context);
注意:如果你的setupJest.ts里没导入zone.js/dist/zone-testing,或者导入顺序不对,就会触发Zone未定义的错误。
2. 检查jest.config.js的核心配置
确保你的jest.config.js里正确指定了预设和setup文件,并且适配Angular 9的版本:
module.exports = { // 必须使用jest-preset-angular预设 preset: 'jest-preset-angular', // 指向你的setupJest.ts文件,路径要正确 setupFilesAfterEnv: ['<rootDir>/src/setupJest.ts'], testPathIgnorePatterns: [ '<rootDir>/node_modules/', '<rootDir>/dist/' ], globals: { 'ts-jest': { // 关联你的tsconfig.spec.json tsconfig: '<rootDir>/tsconfig.spec.json', stringifyContentPathRegex: '\\.html$', astTransformers: { before: [ 'jest-preset-angular/build/InlineFilesTransformer', 'jest-preset-angular/build/StripStylesTransformer' ] } } }, moduleFileExtensions: ['ts', 'html', 'js', 'json'] };
关键:setupFilesAfterEnv必须正确指向setupJest.ts,这个配置是让Jest在运行测试前先执行初始化脚本,加载Zone测试包。
3. 修正tsconfig.spec.json配置
确保你的tsconfig.spec.json里的types只包含jest和node,并且启用必要的编译选项:
{ "extends": "./tsconfig.json", "compilerOptions": { "outDir": "./out-tsc/spec", "types": ["jest", "node"], "esModuleInterop": true, "emitDecoratorMetadata": true }, "files": [ "src/polyfills.ts" ], "include": [ "src/**/*.spec.ts", "src/**/*.d.ts" ] }
注意:要移除types里所有和karma、jasmine相关的配置,避免冲突。
4. 确保依赖版本兼容
Angular 9需要搭配对应版本的jest-preset-angular,建议安装8.x版本的jest-preset-angular(和Angular 9的大版本匹配):
npm install -D jest-preset-angular@8.3.2
同时检查zone.js是否存在(Angular本身依赖它,不要误删):
npm install zone.js --save
5. 清理缓存重新安装
有时候依赖缓存会导致问题,执行以下步骤重置依赖:
# 删除node_modules和lock文件 rm -rf node_modules package-lock.json # 重新安装依赖 npm install # 清除Jest缓存 npx jest --clearCache
完成以上步骤后,再运行npm test,应该就能解决Zone未定义的错误了。如果还是有问题,可以检查是否有第三方库手动导入了zone.js的错误版本,或者是否在测试文件里提前使用了Angular的异步API(比如async/await)而没等Zone初始化完成。
内容的提问来源于stack exchange,提问作者Kay van Bree

