You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在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

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.26 05:03:22