React Native升级后Jest测试报错:未启用--experimental-vm-modules
解决React Native升级后Jest动态导入SVG的测试错误
原因分析
React Native 0.74.x升级后,Jest对ES模块的处理逻辑有所调整,你通过lazy配合动态导入SVG资源的写法,在Jest默认环境下会触发VM模块的相关限制,从而抛出报错。
可行解决方法
1. 为SVG文件添加Jest模拟
测试阶段不需要真实渲染SVG组件,直接模拟占位组件即可:
- 在项目根目录创建
__mocks__/svg.js文件:
import React from 'react'; const MockSVG = () => <span />; export default MockSVG;
- 在Jest配置文件(
jest.config.js或package.json的jest字段)中添加映射规则:
moduleNameMapper: { '\\.svg$': '<rootDir>/__mocks__/svg.js', }
这样Jest会把所有SVG导入替换为模拟组件,动态import不会触发真实模块加载,直接绕过报错。
2. 测试环境下替换动态导入为同步导入
通过环境变量区分测试和生产环境,调整icons.ts的导入逻辑:
import React, { lazy } from 'react'; const isTest = process.env.NODE_ENV === 'test'; const Icons = { sun: isTest ? require('@src/assets/icons/sun.svg').default : lazy(() => import('@src/assets/icons/sun.svg')), moon: isTest ? require('@src/assets/icons/moon.svg').default : lazy(() => import('@src/assets/icons/moon.svg')), cloud: isTest ? require('@src/assets/icons/cloud.svg').default : lazy(() => import('@src/assets/icons/cloud.svg')), }; export default Icons;
测试时用同步require加载SVG,避免动态import的问题;生产环境保持原有的懒加载逻辑。
3. 配置Babel处理动态导入
用Babel插件把动态import转换为Jest可处理的同步形式:
- 安装依赖:
npm install babel-plugin-dynamic-import-node --save-dev
- 在
babel.config.js中针对测试环境添加插件:
module.exports = { presets: ['module:metro-react-native-babel-preset'], env: { test: { plugins: ['dynamic-import-node'], }, }, };
该插件会把所有动态import()转换为require(),让Jest正常处理,无需启用实验性VM模块。
以上方法均无需使用--experimental-vm-modules,优先推荐第一种模拟SVG的方式,简洁且不影响生产代码。
内容的提问来源于stack exchange,提问作者Onyx
相关产品推荐
相关产品推荐

