React Native调试模式与生产模式之间的切换
本文完整阅读约需 13 分钟,如时间较长请考虑收藏后慢慢阅读~
不久前我接手了一个React Native项目,需要对应用的逻辑进行修改。然而在我自信满满地修改完js文件,放入模拟器执行时,却发现所有修改均未生效。折腾来折腾去才发现是这个工程已经开启了生产模式,然而应该如何返回到调试模式呢?
0x01
React Native为了提升应用执行性能,会在生产模式启动时对所有的资源文件以及相关代码打包后存储在app/src/main/assets
目录。
而当其处于调试模式的时候,需开启服务器进程,并可通过模拟器内双击R
键的方式实现实时刷新,而不需要重新构建。
我所接手的项目据说已经开启了生产模式(但对方并不知道如何关闭)。我尝试着通过清除缓存目录的方法来接触生产模式,然而在简单清除该目录后,却发现应用出现闪退情况。
0x02
我尝试阅读React Native官方文档,希望从中找到相关的资料,但无论是搜索debug mode
、cache
、assets
、bundle
,均未能得到任何结果。
0x03
于是我在React Native官方GitHub仓库中搜索包含index.android.bundle
的Issue,搜索到了这一篇:
facebook/react-native issues#22076:
0x04
按照Issue中的方法,我注释掉了MainApplication.java
中的import com.facebook.react.BuildConfig;
,删除app/src/main/assets
目录中所有文件,并尝试重新编译。
这一次项目终于回到了调试模式,应用行为与我在js文件中所描述的一致,也可以在服务器未开启时显示红屏警告。
0x05
根据Issue中的指引,我尝试利用AndroidStudio(IDEA)自带的反编译功能对com.facebook.react.BuildConfig
包进行反编译,拿到的结果如图所示:
可以看见,该包重载了BuildConfig类,并将DEBUG属性设置为False。
顺藤摸瓜Inspect下去,我们会发现该属性在MainApplication.java
的getUseDeveloperSupport()
重载方法中被调用,该部分代码为React Native自动生成。
而当我们注释掉com.facebook.react.BuildConfig
包后,再度往下Inspect,会发现当这个包被注释后,所引用的类为app/build/generated/source/buildConfig/debug/{your.package.name}/buildConfig.java
,而其中将DEBUG属性设置为了True。
0x06
一切迷惑就此真相大白。
我们也可以回归到这篇文章的主题:如何切换React Native的生产模式和调试模式呢?
从调试模式切换到生产模式
- 构建
assets/index.{platform}.bundle
文件
这里以Android为例。控制台切换到项目根目录,执行以下命令:
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/
注意,
app/src/main/res/assets
目录必须提前建立,否则会提示找不到目录。
- 构建结束后,在
MainApplication.java
中引入com.facebook.react.BuildConfig
包:
import com.facebook.react.BuildConfig;
最后,在Android Studio中编译执行,即可切换到生产模式
从生产模式切换回调试模式
- 删除
assets/index.{platform}.bundle
文件
该步骤为可选项,不删除也可以,单纯是为了避免文件冗余,以及造成维护上的迷惑。
- 注释掉
import com.facebook.react.BuildConfig;
这一行代码 -
在项目根目录下执行
react-native start
开启本地调试服务器
同上,在Android Studio中编译执行,即可切换到调试模式
附:
除了直接修改MainAppliction.java
以外,还有一种方法,即利用Gradle的BuildConfig,该方法可以轻松实现调试模式&生产模式配置化。
1. 修改app/build.gradle
文件,在最上面加入以下配置:
def debugMode = "true"
task generateBundle (type:Exec) {
if (debugMode.compareTo("debug")) {
commandLine './buildDebug.sh'
} else {
commandLine './buildProduction.sh'
}
}
如果是Windows,将
.sh
修改为.bat
,本文默认你已经是一位*NIXer,或已经掌握Windows的命令行操作,因此不扩展说明Windows下的配置方法。
- 同时在该文件
android -> buildTypes -> debug
下加入以下配置:
debug {
buildConfigField "boolean", "DEBUG_MODE", debugMode
}
- 在
app
目录下建立两个文件,命名为buildDebug.sh
与buildProduction.sh
并给与执行权限:
#!/bin/bash
# buildDebug.sh
cd ..
screen -dm react-native start
#!/bin/bash
# buildProduction.sh
cd ..
react-native bundle --platform android --dev false --entry-file index.android.js --bundle-output app/src/main/assets/index.android.bundle --assets-dest app/src/main/res/
建议在编辑完成后,执行测试一下,以避免出现预料之外的故障,提高排错难度。
- 在AndroidStudio中点击菜单栏的
Build -> Edit Configurations...
,打开你需要编译的包,在Before Launch
选项处点击加号,选择Run Gradle Task
,并选择app
作为Gradle Project,第一步加入的generateBundle
作为Tasks,其他默认。 -
重新同步Gradle项目,构建并运行。
这样子,我们只需要修改第一步中debugMode
的值(true or false),即可实现生产模式和调试模式的切换!