Expo项目中ts-jest无法导入react-native-dotenv环境变量
Expo + ts-jest 配置 react-native-dotenv 环境变量问题
我正在为Expo项目配置ts-jest,项目使用react-native-dotenv管理环境变量,已按照该库文档创建了env.d.ts文件。
代码中通过import {API} from '@env';导入环境变量,但运行测试时总会抛出Cannot find module '@env' from 'xx.test.tsx'的错误。
我的全部配置如下:
//jest.config.ts import type {JestConfigWithTsJest} from 'ts-jest'; import { defaults as tsjPreset } from 'ts-jest/presets' const config: JestConfigWithTsJest = { ...tsjPreset, testEnvironment: 'jsdom', preset: 'jest-expo', setupFiles: ['./jest_setup/asyncStorage.ts'], extensionsToTreatAsEsm: ['.ts', '.tsx'], moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', }, transform: { '^.+\\.tsx?$': [ 'ts-jest', { useESM: true, tsconfig: 'tsconfig.spec.json' }, ], }, testMatch: [ '**/__test__/?(*.)+(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(-community)?)|expo(nent)?|@expo(nent)?/.*|@expo-google-fonts/.*|react-navigation|@react-navigation/.*|@unimodules/.*|unimodules|sentry-expo|native-base|react-native-svg|@react-navigation/native-stack|@firebase|firebase/.*|@react-native|react-native)', ], coverageReporters: [ 'json-summary', 'text', 'lcov', ], 'cacheDirectory': '.jest/cache', }; export default config;
// env.d.ts declare module '@env' { export const API: string; };
// babel.config.js module.exports = function (api) { api.cache(true); return { presets: [['babel-preset-expo']], plugins: [ ["module:react-native-dotenv", { "envName": "APP_ENV", "moduleName": "@env", "path": ".env", }], ['module-resolver', { "root" : ["./"], "alias": { "~": "./", } }] ] }; };
解决方案
1. 添加@env模块映射
jest测试流程不会经过babel插件转换,因此需要通过moduleNameMapper模拟@env模块的导出。修改jest.config.ts中的moduleNameMapper:
moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', '@env': '<rootDir>/jest_setup/mockEnv.ts', // 新增这一行 },
2. 创建mock环境变量文件
在jest_setup目录下新建mockEnv.ts,导出测试用的环境变量:
export const API = 'https://test-api.example.com'; // 其他环境变量也可在此处导出
3. 可选:直接在配置中mock
如果不想单独创建文件,也可以直接在配置中返回mock对象:
moduleNameMapper: { '^(\\.{1,2}/.*)\\.js$': '$1', '@env': jest.fn(() => ({ API: 'https://test-api.example.com', })), },
推荐使用第一种方式,便于统一管理测试环境变量。
4. 验证配置
修改完成后重新运行测试,即可解决找不到@env模块的问题,测试代码也能正常使用环境变量。
内容的提问来源于stack exchange,提问作者Chongju Mai
相关产品推荐
相关产品推荐

