React Native低版本下如何排除指定包构建Android?
问题背景
我有一个支持Web、iOS、Android、Windows、macOS平台的React Native项目,当前RN版本低于0.70.0且无法升级。react-native-worklets-core和react-native-vision-camera这两个包会导致Android构建失败,目前我通过复制伪造模块到node_modules临时解决,但这不是可行方案。我的package.json中有如下脚本:
"replace-vision-camera": "rm -rf ./node_modules/react-native-vision-camera && cp -R ./fake_modules/react-native-vision-camera ./node_modules/react-native-vision-camera", "replace-worklets-core": "rm -rf ./node_modules/react-native-worklets-core && cp -R ./fake_modules/react-native-worklets-core ./node_modules/react-native-worklets-core"
请问如何在不使用这两个包的情况下构建Android?是否可以通过Metro配置实现?
可行方案:通过Metro配置实现模块替换(无需伪造模块拷贝)
1. 配置Metro拦截模块导入
无需修改node_modules,直接通过Metro的自定义解析规则,针对Android平台将这两个包替换为项目内的空实现模块:
第一步:创建本地Mock模块
在项目根目录新建mock-modules文件夹,分别为两个包创建空实现文件:
mock-modules/react-native-vision-camera/index.js:
// 按需导出项目中用到的API,保证与原包导出结构一致 export const Camera = () => null; export const useCameraDevices = () => ({ back: null, front: null }); export const CameraPermissionStatus = { AUTHORIZED: 'authorized' }; // 补充项目中使用到的其他导出项
mock-modules/react-native-worklets-core/index.js:
// 按需导出项目中用到的API export const runOnUI = (cb) => cb(); export const runOnJS = (cb) => cb(); export const Worklet = () => {}; // 补充项目中使用到的其他导出项
第二步:修改Metro配置
在项目根目录的metro.config.js中添加解析钩子,仅针对Android平台替换模块:
const { getDefaultConfig, mergeConfig } = require('@react-native/metro-config'); const customConfig = { resolver: { resolveRequest: (context, moduleName, platform) => { // 仅对Android平台生效 if (platform === 'android') { // 替换react-native-vision-camera if (moduleName === 'react-native-vision-camera') { return { filePath: `${__dirname}/mock-modules/react-native-vision-camera/index.js`, type: 'sourceFile', }; } // 替换react-native-worklets-core if (moduleName === 'react-native-worklets-core') { return { filePath: `${__dirname}/mock-modules/react-native-worklets-core/index.js`, type: 'sourceFile', }; } } // 其他场景沿用默认解析逻辑 return context.resolveRequest(context, moduleName, platform); }, }, }; module.exports = mergeConfig(getDefaultConfig(__dirname), customConfig);
2. 清理原有临时方案
直接删除package.json中的replace-vision-camera和replace-worklets-core脚本,同时删除项目内的fake_modules文件夹,避免冗余操作。
3. 优化Android构建配置(可选)
如果Android构建系统仍扫描到这两个包的原生代码,可在android/app/build.gradle中排除相关依赖:
dependencies { // 排除两个包的原生依赖 implementation(project(':react-native-vision-camera')) { exclude group: 'com.mrousavy', module: 'react-native-vision-camera' } implementation(project(':react-native-worklets-core')) { exclude group: 'com.mrousavy', module: 'react-native-worklets-core' } }
同时在android/settings.gradle中移除对应的模块引入:
// 删除以下两行(如果存在) include ':react-native-vision-camera' project(':react-native-vision-camera').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-vision-camera/android') include ':react-native-worklets-core' project(':react-native-worklets-core').projectDir = new File(rootProject.projectDir, '../node_modules/react-native-worklets-core/android')
核心优势
- 无需修改
node_modules,所有Mock代码都在项目目录内,便于版本控制和维护 - 仅针对Android平台替换模块,不影响Web、iOS、Windows、macOS的正常功能
- 避免了文件拷贝带来的同步问题,构建流程更稳定
内容的提问来源于stack exchange,提问作者Josh Thompson

