在Vitest中测试React Native应用时的模块导入问题
React Native + Vitest 测试问题排查与解决
问题原因解析
1. 模块格式混淆
React Native的npm包以CommonJS(CJS)格式为主发布,但部分内部文件混用了ES模块(ESM)的import/export语法,却未在根package.json中声明"type": "module"。Vite/Vitest的模块解析器会因此误判其为ESM模块,抛出格式不兼容错误。
2. inline配置后崩溃的本质
deps.inline会让Vitest把指定依赖当作项目源码处理,跳过预编译。但React Native代码依赖大量移动端专属全局变量(如NativeModules、Platform)和原生桥接逻辑,这些在Node.js/Vitest的测试环境中完全不存在,直接inline必然导致内部代码因找不到依赖崩溃。
可行解决办法
方案一:全局Mock React Native核心模块
通过模拟React Native的核心导出,让测试环境识别这些模块:
- 在项目根目录创建
__mocks__/react-native.js,写入基础模拟代码:
export const Platform = { OS: 'ios', // 可根据测试需求改为'android' select: (obj) => obj[Platform.OS] }; export const NativeModules = {}; // 按需添加测试用到的其他导出,比如StyleSheet、View等 export const StyleSheet = { create: (styles) => styles }; export const View = 'View'; export const Text = 'Text';
- 修改
vitest.config.js配置自动mock:
export default { test: { globals: true, mockReset: true, deps: { external: ['react-native'] } }, resolve: { alias: { 'react-native': '__mocks__/react-native.js' } } };
- 若需要更全面的模拟,可使用
react-native-mock-render等第三方库简化编写。
方案二:用Babel转换适配React Native代码
通过Babel将React Native的混合格式代码转换为Vitest可处理的格式:
- 安装依赖:
npm install --save-dev @babel/preset-react-native @babel/core
- 创建
babel.config.js:
module.exports = { presets: ['@babel/preset-react-native'] };
- 更新
vitest.config.js:
export default { test: { transform: { '^.+\\.(js|jsx)$': 'babel-jest' }, deps: { optimizer: { web: { exclude: ['react-native'] } } } } };
方案三:使用官方成熟测试工具
如果Vitest适配成本过高,React Native官方推荐的jest配合@testing-library/react-native是更成熟的选择,无需额外处理模块兼容性,可直接运行组件测试。
内容的提问来源于stack exchange,提问作者Markus A Noren
相关产品推荐
相关产品推荐

