從去年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開發遇到的問題和一些架構的分享,希望大家喜歡的可以一起研究探討;