如何在React Native(Expo)项目JS端Mock NativeModules并解决ESM兼容问题
解决方案
问题根源
babel.config.js 属于 CommonJS 模块环境,直接使用 ESM 的 import 语法会触发模块格式冲突;同时 react-native-proxy 模块的加载顺序或格式设置,也可能与 ESM 格式的 expo-file-system 不兼容。
可行解决思路
1. 在 CommonJS 环境改用 require 引入 expo-file-system
babel.config.js 是 CommonJS 环境,直接用 require 替代 import 即可避开格式错误:
// babel.config.js const FileSystem = require('expo-file-system'); // 按需解构示例 const { writeAsStringAsync, readAsStringAsync } = require('expo-file-system');
expo-file-system 本身兼容 CommonJS 规范,这种方式无需额外配置即可生效。
2. 在 react-native-proxy 模块中处理 mock
不要在 babel 配置文件中引入第三方模块,直接在自定义的 react-native-proxy 里用 require 引入并扩展 NativeModules:
// react-native-proxy.js const originalRN = require('react-native'); const FileSystem = require('expo-file-system'); // 自定义 mock 逻辑 const mockedFileSystem = { ...FileSystem, writeAsStringAsync: jest.fn(() => Promise.resolve()), readAsStringAsync: jest.fn(() => Promise.resolve('mock content')), }; // 代理 NativeModules,替换目标模块 const proxyNativeModules = new Proxy(originalRN.NativeModules, { get(target, prop) { if (prop === 'FileSystem') { return mockedFileSystem; } return target[prop]; }, }); // 导出扩展后的 react-native 对象 module.exports = { ...originalRN, NativeModules: proxyNativeModules, };
如果你的 react-native-proxy 是 ESM 模块(用 export),也可以改用 import,但需确保 Metro 配置正确识别 ESM(Expo 默认支持,无需额外调整)。
3. 测试场景下直接用 jest.mock
如果只是测试环境需要 mock expo-file-system,完全可以跳过 babel 重定向,直接在测试文件或全局 setup 中使用 Jest 原生 mock:
// 在测试文件顶部或 jest.setup.js 中 jest.mock('expo-file-system', () => ({ writeAsStringAsync: jest.fn(() => Promise.resolve()), readAsStringAsync: jest.fn(() => Promise.resolve('mock data')), // 按需添加其他需要 mock 的 API }));
这种方式更直接,也不会触发模块格式冲突。
4. 调整 Metro 配置兼容 ESM
如果是 Metro 加载时的模块解析问题,可在 metro.config.js 中添加 ESM 支持配置:
// metro.config.js const { getDefaultConfig } = require('expo/metro-config'); const config = getDefaultConfig(__dirname); // 支持 ESM 扩展名 config.resolver.sourceExts.push('mjs'); // 允许 require 上下文(部分 ESM 模块依赖) config.transformer.unstable_allowRequireContext = true; module.exports = config;
内容的提问来源于stack exchange,提问作者ChocKing
相关产品推荐
相关产品推荐

