Monorepo中使用Yarn PNP与ts-jest时找不到describe等Jest类型问题
jz test失败,@types/jest配置异常 在Monorepo环境下使用Jazelle和Yarn PNP,执行jz test运行测试时失败,报错显示@types/jest配置存在问题。
报错信息
FAIL __tests__/autocomplete/presto/suggest.test.ts ● Test suite failed to run __tests__/autocomplete/presto/suggest.test.ts:4:8 - error TS6137: Cannot import type declaration files. Consider importing 'jest' instead of '@types/jest'. 4 import '@types/jest'; ~~~~~~~~~~~~~ __tests__/autocomplete/presto/suggest.test.ts:6:1 - error TS2593: Cannot find name 'describe'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig. 6 describe('Presto SQL Suggest Tests', () => { ~~~~~~~~ __tests__/autocomplete/presto/suggest.test.ts:7:5 - error TS2593: Cannot find name 'test'. Do you need to install type definitions for a test runner? Try `npm i --save-dev @types/jest` or `npm i --save-dev @types/mocha` and then add 'jest' or 'mocha' to the types field in your tsconfig. 7 test('Empty suggest', () => { ~~~~ __tests__/autocomplete/presto/suggest.test.ts:10:9 - error TS2304: Cannot find name 'expect'. 10 expect(result.length).toBe(0); ~~~~~~
现有配置文件
tsconfig.json
{ "typeAcquisition": { "include": [ "jest" ] }, "compilerOptions": { "types": [ "node", "@types/jest" ], "typeRoots": [ "./types", "./node_modules/@types" ], "outDir": "target", "sourceMap": true, "inlineSources": true, "noImplicitAny": true, "strict": true, "noEmit": true, "target": "es2015", "module": "commonjs", "allowJs": true, "checkJs": true, "jsx": "react", "moduleResolution": "node", "esModuleInterop": true, "skipLibCheck": true, "baseUrl": ".", "resolveJsonModule": true, "experimentalDecorators": true }, "include": [ "src/**/*.*", "__tests__" ], "exclude": [ "node_modules", "**/*.spec.ts", "**/*.test.ts" ], }
jest.config.js
module.exports = { rootDir: './', testEnvironment: 'node', preset: 'ts-jest', transform: { "^.+\\.(ts|js)$": require.resolve('ts-jest') }, moduleFileExtensions: [ "ts", "tsx", "js" ], roots: [ "<rootDir>/__tests__" ], }
devDependencies
"@types/jest": "28.1.3", "@types/mocha": "^2.2.42", "@jest/globals": "25.5.2", "antlr4ts-cli": "^0.5.0-alpha.4", "babel-eslint": "10.1.0", "babel-jest": "28.1.3", "babel-plugin-parameter-decorator": "1.0.16", "create-universal-package": "^4.3.0", "eslint": "7.32.0", "eslint-config-fusion": "^6.3.0", "eslint-config-prettier": "2.10.0", "eslint-plugin-baseui": "10.12.1", "eslint-plugin-cup": "2.0.3", "eslint-plugin-flowtype": "4.7.0", "eslint-plugin-import": "2.22.1", "eslint-plugin-jest": "23.20.0", "eslint-plugin-jsx-a11y": "^6.2.1", "eslint-plugin-prettier": "4.2.1", "eslint-plugin-react": "^7.27.0", "eslint-plugin-react-hooks": "^4.6.0", "flow-bin": "0.131.0", "flow-coverage-report": "0.7.0", "jest": "28.1.3", "jest-environment-jsdom": "28.1.3", "jest-environment-jsdom-global": "3.1.2",
解决思路
移除测试文件中的
import '@types/jest'
TypeScript不允许直接导入类型声明文件,这类文件会通过tsconfig自动加载,手动导入会触发TS6137错误,删掉所有测试文件里的该导入语句。修正tsconfig.json的exclude配置
当前配置中include包含了__tests__,但exclude又排除了**/*.test.ts,这会导致TypeScript忽略测试文件的类型检查,把exclude里的**/*.spec.ts和**/*.test.ts移除。统一Jest相关依赖版本
注意到@jest/globals版本为25.5.2,而jest、@types/jest、babel-jest均为28.1.3,版本不兼容会导致类型加载异常,将@jest/globals升级至28.1.3,与其他Jest依赖版本保持一致。调整tsconfig的types配置
将compilerOptions.types里的@types/jest改为jest,因为@types/jest包的类型标识是jest,而非@types/jest。验证Yarn PNP依赖解析
在Monorepo+Yarn PNP环境下,执行yarn install重新安装依赖,确保@types/jest被正确链接到当前workspace包。简化jest.config.js配置
使用preset: 'ts-jest'时,无需自定义transform配置,preset已包含ts-jest的转换规则,避免冲突。修改后的配置:module.exports = { rootDir: './', testEnvironment: 'node', preset: 'ts-jest', moduleFileExtensions: ["ts", "tsx", "js"], roots: ["<rootDir>/__tests__"], }
内容的提问来源于stack exchange,提问作者hehe123456

