React Native升级后,如何自定义Metro构建Android多环境包的命令?
前提条件
为实现多环境构建,我们配置了如下Android产品风味(productFlavors):
productFlavors { development { resValue "string", "app_name", "AppName Dev" applicationId "com.org.nativeapp.development" } staging { resValue "string", "app_name", "AppName Stag" applicationId "com.org.nativeapp.staging" } production { resValue "string", "app_name", "AppName" } }
在package.json中,我们通过以下脚本实现不同环境的构建:
"android": "react-native run-android --mode=developmentDebug --appIdSuffix=development", "android:prod": "react-native run-android --mode=productionDebug", "android:stag": "react-native run-android --mode=stagingDebug --appIdSuffix=staging",
问题背景
将React Native项目从0.67.5升级至最新版本(当前为0.71.3)后,通过npx react-native start启动Metro时,新增了按键直接构建Android和iOS的功能,界面如下:
问题描述
虽然通过Metro会话直接构建非常便捷,但由于默认执行的是react-native run-android和react-native run-ios命令,无法适配我们的多环境配置,导致构建失败,实际需要执行带参数的命令(如react-native run-android --mode=developmentDebug --appIdSuffix=development)。
咨询问题
- 是否可以修改Metro会话中构建时执行的脚本?如果不行,
- 是否可以为默认命令添加参数,以构建特定的Android风味?
额外疑问:
出于好奇,能否在Metro会话的默认命令(r - 重载应用、d - 打开开发者菜单、i - 在iOS运行、a - 在Android运行)之外添加自定义脚本?
解决方案
1. 为默认Metro构建命令添加参数
推荐两种可行方式:
方式一:通过react-native.config.js配置默认参数
在项目根目录创建或修改react-native.config.js,指定Android的默认构建命令:
module.exports = { android: { runCommand: "react-native run-android --mode=developmentDebug --appIdSuffix=development" } };
Metro会话中按下a键时,会自动执行该带参数命令。若需切换环境,可结合环境变量动态调整:
const env = process.env.BUILD_ENV || 'development'; const getAndroidRunCommand = () => { switch(env) { case 'production': return 'react-native run-android --mode=productionDebug'; case 'staging': return 'react-native run-android --mode=stagingDebug --appIdSuffix=staging'; default: return 'react-native run-android --mode=developmentDebug --appIdSuffix=development'; } }; module.exports = { android: { runCommand: getAndroidRunCommand() } };
启动时设置环境变量即可切换:BUILD_ENV=staging npx react-native start。
方式二:自定义Metro启动脚本
复制node_modules/react-native/scripts/start.js到项目根目录,修改其中执行run-android的代码块,替换为你的带参数命令,然后在package.json中更新启动脚本:
"scripts": { "start": "node ./custom-start.js" }
此方式自由度高,但RN版本升级后需同步脚本内容。
2. 修改Metro默认执行脚本
本质与自定义启动脚本一致,通过重写Metro启动逻辑替换默认命令。也可尝试社区插件metro-custom-commands扩展,但需注意版本兼容性。
3. 添加自定义Metro命令
可通过扩展Metro终端交互逻辑实现,步骤如下:
- 确保项目依赖
metro-terminal - 在
metro.config.js中添加自定义命令:
const { Terminal } = require('metro-terminal'); const { execSync } = require('child_process'); module.exports = { // 保留原有配置 server: { enhanceMiddleware: (middleware) => { const terminal = new Terminal(process.stdout); terminal.addCommand('s', '构建Staging环境Android', () => { execSync('react-native run-android --mode=stagingDebug --appIdSuffix=staging', { stdio: 'inherit' }); }); terminal.addCommand('p', '构建Production环境Android', () => { execSync('react-native run-android --mode=productionDebug', { stdio: 'inherit' }); }); return middleware; } } };
启动Metro后,即可使用新增的s、p按键执行自定义构建脚本。
内容的提问来源于stack exchange,提问作者ale917k

