Expo React TypeScript应用Jest测试报错:无法找到@env模块
Expo + TypeScript Jest 测试找不到 @env 模块的解决方案
问题背景
使用TypeScript开发Expo React应用,应用运行正常,但Jest测试时始终报错无法从store.ts找到@env模块,错误栈指向环境变量导入行。
错误信息
Cannot find module '@env' from 'src/store.ts' Require stack: src/store.ts src/screens/HomeScreen.tsx src/tests/HomeScreen.test.tsx > 1 | import { REACT_APP_API_URL } from '@env'; | ^ 2 | import axios from 'axios'; 3 | import { Alert } from 'react-native'; 4 | import create from 'zustand'; at Resolver._throwModNotFoundError (node_modules/jest-resolve/build/resolver.js:425:11) at Object.<anonymous> (src/store.ts:1:1) at Object.<anonymous> (src/screens/HomeScreen.tsx:5:1) at Object.<anonymous> (src/tests/HomeScreen.test.tsx:3:1)
现有关键配置(供参考)
HomeScreen.test.tsx
import React from 'react'; import renderer from 'react-test-renderer'; import Home from '../screens/HomeScreen'; describe('<App />', () => { it('has 1 child', () => { const tree = renderer.create(<Home />).toJSON(); console.log('test', tree); }); });
src/types/env.d.ts
declare module '@env' { export const REACT_APP_API_URL: string; }
jest.config.js(原配置)
module.exports = { preset: 'jest-expo', transform: { '^.+\\.tsx?$': [ 'ts-jest', { tsconfig: { jsx: 'react', }, }, ], }, testMatch: ['**/?(*.)+(spec|test).ts?(x)'], collectCoverageFrom: [ '**/*.{ts,tsx}', '!**/coverage/**', '!**/node_modules/**', '!**/babel.config.js', '!**/jest.setup.js', ], moduleFileExtensions: ['js', 'ts', 'tsx'], transformIgnorePatterns: [ 'node_modules/(?!(jest-)?react-native|@react-native|react=native|react-clone-referenced-element|@react-native-community|expo(nent)?|@expo(nent)?/.*|react-navigation|@react-navigation/.*|@unimodules/.*|sentry-expo)', ], coverageReporters: ['json-summary', 'text', 'lcov'], rootDir: './', modulePaths: ['<rootDir>'], collectCoverage: false, moduleNameMapper: { '#(.*)': '<rootDir>/node_modules/$1', }, };
tsconfig.json(原配置)
{ "extends": "expo/tsconfig.base", "compilerOptions": { "jsx": "react-jsx", "strict": true, "typeRoots": ["./src/types"], "types": ["jest", "node","@types/jest"], "baseUrl": ".", "paths": { "@env": ["node_modules/@env"] } } }
babel.config.js(原配置)
module.exports = function (api) { api.cache(true); return { presets: ['babel-preset-expo'], plugins: [ 'react-native-reanimated/plugin', [ 'module:react-native-dotenv', { moduleName: '@env', path: '.env', blacklist: null, whitelist: null, safe: false, allowUndefined: true, }, ], ], }; };
解决方案
方案1:Mock @env 模块(推荐,测试更稳定)
Jest 无法识别 babel 插件虚拟的@env模块,直接创建 mock 文件让 Jest 读取:
- 在
src目录下创建__mocks__/env.ts文件:
export const REACT_APP_API_URL = 'https://mock-api.example.com'; // 若有其他环境变量,一并在此导出
- 修改
jest.config.js的moduleNameMapper,添加@env的映射:
moduleNameMapper: { '#(.*)': '<rootDir>/node_modules/$1', '@env': '<rootDir>/src/__mocks__/env.ts' // 新增这一行 },
方案2:调整 TS 配置并让 Jest 使用 Babel 转换
- 修改
tsconfig.json的paths配置,指向类型定义文件(原配置指向node_modules/@env错误,因为@env不是真实包):
"paths": { "@env": ["./src/types/env.d.ts"] }
- 修改
jest.config.js的transform配置,让 ts-jest 启用项目的 Babel 配置,从而处理react-native-dotenv插件:
transform: { '^.+\\.tsx?$': [ 'ts-jest', { tsconfig: './tsconfig.json', // 改用项目根目录的tsconfig babelConfig: true // 启用项目的babel配置 }, ], },
方案3:清理 Jest 缓存(辅助步骤)
执行以下命令清理 Jest 缓存,确保配置修改生效:
npx jest --clearCache
内容的提问来源于stack exchange,提问作者Hugoi
相关产品推荐
相关产品推荐

