从去年11月开始到现在,使用ReactNative已经有近10个月了,从当初的RN小白,在实际开发的过程中踩了无数的坑,但还好大部分得到了完善的解决。目前负责公司的RN App跨端架构设计,同时沉淀了一些日常所需和自己优化过的组件,APP架构采用了拆分bundle包+热更新+android和ios兼容的模式。在公司2个APP上已稳定运行;
今天要讲的是在实际开发过程中在package.json配置命令,来进行工程的配置运行。比如android端在实际开发的过程中,常常需要在build.gradle中配置测试版和正式版,即productFlavors偏好配置,可以给不同渠道的APP生成不同的APP,android开发的小伙伴应该都比较熟悉,不熟的同学可以搜索“productFlavors”关键词;
下面正式开讲:
最初始开发ReactNative的时候,我们用的命令是react-native run-android或ios,当我们要配置偏好的时候,或者修改原始的启动页的时候应该怎么配置和修改呢?如果要修改app工程名或其他东西呢?
使用工具和平台:webstorm+android
1、用webstorm打开一个ReactNative工程,找到node_modules -> @react-native-community -> cli -> build -> commands -> runAndroid 文件夹,找到runAndroid.js文件,该文件主要负责运行android前的一些配置信息
var _default = {
name: 'run-android',
description: 'builds your app and starts it on a connected Android emulator or device',
func: runAndroid,
options: [{
command: '--install-debug'//安装debug版本
}, {
command: '--root [string]',//配置android工程的根目录
description: 'Override the root directory for the android build (which contains the android directory)',
default: ''
}, {
command: '--flavor [string]',//已过时,以前用来配置偏好的现在改用variant
description: '--flavor has been deprecated. Use --variant instead'
}, {
command: '--variant [string]',//配置app工程的偏好
default: 'debug'
}, {
command: '--appFolder [string]',//配置要运行的android app工程的文件夹
description: 'Specify a different application folder name for the android source. If not, we assume is "app"',
default: 'app'
}, {
command: '--appId [string]',//配置android的applicationId包名
description: 'Specify an applicationId to launch after build.',
default: ''
}, {
command: '--appIdSuffix [string]',//配置包名的后缀
description: 'Specify an applicationIdSuffix to launch after build.',
default: ''
}, {
command: '--main-activity [string]',//运行android的第一个启动页面,默认是MainActivity
description: 'Name of the activity to start',
default: 'MainActivity'
}, {
command: '--deviceId [string]',//配置开发的设备id
description: 'builds your app and starts it on a specific device/simulator with the ' + 'given device id (listed by running "adb devices" on the command line).'
}, {
command: '--no-packager',//配置构建项目的时候不要启动APP
description: 'Do not launch packager while building'
}, {
command: '--port [number]',//配置端口
default: process.env.RCT_METRO_PORT || 8081,
parse: val => Number(val)
}, {
command: '--terminal [string]',//在新的terminal窗口运行项目
description: 'Launches the Metro Bundler in a new window using the specified terminal path.',
default: ''
}]
};
举例:实际开发中,android应用区分了开发时的dem
o版和publish发布版,如下
// 在app目录下的build.gradle中,依据flavors变动的话设置如下
productFlavors {
//发布版
publish {
applicationId "com.asson.app"
}
//演示版
demo {
applicationId "com.asson.app.test"
}
}
这时报了错误,指的是配置喜好需要有一个默认的喜好配置
FAILURE: Build failed with an exception.
* What went wrong:
A problem occurred configuring project ':app'.
> All flavors must now belong to a named flavor dimension. Learn more at https://d.android.com/r/tools/flavorDimensions-missing-error-message.html
在build.gradle的android下的defaultConfig中配置
flavorDimensions "default"
再次运行,又报了错误,错误表示找不到installDebug的项目
FAILURE: Build failed with an exception.
* What went wrong:
Task 'installDebug' not found in project ':app'.
因此根据runAndorid的命令。如果想运行demo版本的debug可以用以下命令运行
react-native run-android --variant demoDebug
此时可以编译成功,但是没办法自动在设备中自动打开APP,报了错误
错误解析:构建APP成功了,安装也成功了,但是打开MainActivity就失败了,报了不存在com.asson.app.MainActivity,查看runOnAllDevices.js的源码
if (devices && devices.length > 0) {
devices.forEach(device => {
(0, _tryRunAdbReverse.default)(args.port, device);
(0, _tryLaunchAppOnDevice.default)(device, packageNameWithSuffix, packageName, adbPath, args.mainActivity);
});
} else {
try {
// If we cannot execute based on adb devices output, fall back to
// shell am start
const fallbackAdbArgs = ['shell', 'am', 'start', '-n', `${packageNameWithSuffix}/${packageName}.MainActivity`];
_logger.default.info(`Starting the app (${adbPath} ${fallbackAdbArgs.join(' ')}...`);
(0, _child_process().spawnSync)(adbPath, fallbackAdbArgs, {
stdio: 'inherit'
});
} catch (e) {
_logger.default.error('adb invocation failed. Do you have adb in your PATH?'); // stderr is automatically piped from the gradle process, so the user
// should see the error already, there is no need to do
// `logger.info(e.stderr)`
return Promise.reject(e);
}
}
const fallbackAdbArgs = ['shell', 'am', 'start', '-n', `${packageNameWithSuffix}/${packageName}.MainActivity`];
这个命令就是通过adb shell命令启动MainActivity,/号前的是packageNameWithSuffix,意思是带后缀的包名,而报错的截图上,我们的包名不带后缀,原因是我们的app的包名已由com.asson.app改为com.asson.app.test,因此要配置--appIdSuffix test让包名的后缀为test,因此命令改为
react-native run-android --variant demoDebug --appIdSuffix test
如果还需要配置其他启动页,则可以使用以下命令
react-native run-android --variant demoDebug --appIdSuffix test --main-activity SplashActivity
其他的命令都是类似的配置方式,可以结合源码查看或配置,相信大家可以很快就掌握了
另外,这是有一个ReactNative基本命令统计,可以学习一下
https://www.jianshu.com/p/64b1c4661b92
以后有时间也会逐步的分享一些ReactNative开发遇到的问题和一些架构的分享,希望大家喜欢的可以一起研究探讨;