React Native - 环境搭建(踩坑指南)

官方文档:
https://reactnative.cn/docs/getting-started/


使用环境:
Windows & Android


缩略词:
RN(React Native)、AS(Android Studio)

1. 初始化项目

1.1 需要的环境

  • Node
    Node 是 JS 的运行环境,这里注意需要下载的 Node 版本需要8.3以上。
  • Python 2
    Python 2的运行环境,这里注意需要下载的python版本为 python 2.x ,不能是 python 3.x。
  • JDK
    Java的运行环境,这里注意需要下载的JDK版本为1.8,只能是1.8。

1.2 需要的配置

由于国内把很多东西都墙掉了,国内的良心公司提供了不少代理,为我们的开发带来方便。下面的一些配置信息,由官网提供。

  • npm 配置

npm 是 Node.js 的包管理工具,负责下载 js 代码的依赖包,由于被墙,我们需要配置下面的代理。

npm config set registry https://registry.npm.taobao.org --global

npm config set disturl https://npm.taobao.org/dist --global
  • yarn 配置(可选)

yarn 是用来替代 npm 功能的工具,可以加速 npm 的下载。

npm install -g yarn react-native-cli

安装完成后,依然需要未 yarn 设置代理。

yarn config set registry https://registry.npm.taobao.org --global

yarn config set disturl https://npm.taobao.org/dist --global

2. 开始第一个项目

注意:在开始之前,请确定 1.1 和 1.2 的配置已经完成。

第一步

找到一个你认为合适的位置,执行如下命令,创建一个名为 Self 的 RN 项目:

react-native init Self

执行完成后,打开文件夹,可以看到如下内容:


React Native - 环境搭建(踩坑指南)_第1张图片
正确的目录样式

第二步

连接我们的手机,打开开发者模式-允许usb调试,然后在项目文件夹下执行下面命令:

react-native run-android

执行完成后,会开始下载一些 Android 项目需要的依赖包,然后在手机上运行 App,效果如下:

React Native - 环境搭建(踩坑指南)_第2张图片
App正确运行

注意:这里手机和电脑需要处于同一网段下,如果不在同一网段,可以左右剧烈摇晃手机,在弹窗中选择 Dev Settings - Debug server host & port for device 选项中输入 IP 和端口。

第三步

修改 App.js 文件,然后重启 App ,看是否能正常显示修改后的内容。

3. 集成 RN 项目到Android(Gradle项目)

3.1 准备工作

所谓准备工作,就是我们的 RN 项目。在集成进入 Android 中之前,我们需要确保我们的 RN 项目中存在 node_modules 这个文件夹。这个文件夹中存在 JavaScript 依赖的所有模块,一般情况下,从 GitHub 上 clone 的项目不会有这个文件夹的。

如果没有这个文件夹,我们需要在项目目录下,执行下面的命令:

npm install

如果使用的 yarn ,还可以直接执行:

yarn

生成的 node_modules 中有很多的文件夹,如果只有一个.开头的文件夹,说明是错误的。

然后,需要将 RN 服务器打开,在项目路径下执行下面命令:

react-native start

成功后会弹出一个新的窗口,用来打印 RN 服务器日志。

3.2 添加依赖

** 第一步 **

App项目build.gradle 文件中添加如下代码:

allprojects {
    repositories {
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
        ...
    }
    ...
}

url "$rootDir/../node_modules/react-native/android" 这段代码实际上对应的是 node_modules/react-native/android 这个文件夹的真正地址,而 $rootDir 指的是项目根目录,如果你的 RN 项目和 App 不在同一目录下,那么这里应该是实际地址。Windows 下面的 '\' 符号需要换成 '\\' 符号。

第二步

App项目build.gradle 文件中添加如下代码:

dependencies {
    compile 'com.android.support:appcompat-v7:23.0.1'
    ...
    compile "com.facebook.react:react-native:+" // From node_modules
}

要指定特定的 React Native 版本,可以用具体的版本号替换 “+”,当然前提是你从 npm 里下载的是这个版本。

第三步

在==AndroidManifest.xml==下加上两个权限:


3.3 编码及测试

由于主要测试集成结果,所以采用的简单的Demo,提供免费的下载链接:

CSDN(系统强制要的1分):RN项目集成测试

百度云盘(密码 mh4x):RN项目集成测试

在运行 Demo 前,请知晓如下几点:

  1. Demo 项目需要执行 npm install
  2. Demo 项目下开启 RN 服务器(具体方法参考3.1)
  3. 使用 AS 编译Demo_app
  4. 需要修改 Demo_app 项目下的 build.gradle (具体修改方法参考3.2)
  5. 运行 App 。如果是在真机上测试,手机和电脑需要在同一网段。

运行 App 时,分别输入 DemoDemo2,会分别显示 App.jsAPP.js 下面的内容,且修改两个文件后,刷新界面,可以正常显示。此时验证集成完毕。

4. 错误记录

4.1 Failed to resolve : com.facebook.react:react-native:xxx

这个问题发生在为 Android 项目添加了关于 React Native 的依赖时,出现问题的原因是因为无法下载相应的依赖,需要在 Android 项目的 build.gradle (不是 app 中的 build.gradle)文件中添加如下代码:

allprojects {
    repositories {
        ...
        maven {
            // All of React Native (JS, Android binaries) is installed from npm
            url "$rootDir/../node_modules/react-native/android"
        }
    }
    ...
}

特别注意:url "$rootDir/../node_modules/react-native/android" 这段代码实际上对应的是node_modules/react-native/android 这个文件夹的真正地址,而 $rootDir 指的是项目根目录,如果你的 RN 项目和 App 不在同一目录下,那么这里应该是实际地址。比如 Windows 下的路径:

maven{
            url "F:\\Self\\node_modules\\react-native\\android"
        }

4.2 Received malformed response from registry for undefined. The registry may be down.

这个问题发生在初始化项目时(react-native init xxx),原因是没有配置代理,依次执行下面的代码可正常初始化

npm config set registry https://registry.npm.taobao.org 

npm config set disturl https://npm.taobao.org/dist

react-native init xxx

4.3 Manifest merger failed : uses-sdk:minSdkVersion 14 cannot be smaller than version 16 declared in library [com.facebook.react:react-native:0.55.4]

这个问题发生在将 RN 项目集成到其他项目中时(修改完 build.gradle 之后),出现这个问题的原因,是因为我们的 RN 要求的最低 SDK 版本是 16 ,而我们项目中实际的最低版本小于16。解决办法,就是修改 app 的最低 SDK 版本。

4.4 Unexpected end of JSON input while parsing near '..."_hasShrinkwrap":fals'

这个问题发生在使用 github 上面其它人的项目后,在生成 node_modules 文件夹时(执行 npm install 或者 npm update 命令时报错)。百度候找到的解决方案大部分都是下面这个方法:

npm cache clean --force

上面的这个方法清除了 npm 的缓存,但是实际验证还是会有问题。后面找到了网上其它的说法,指出可能是 npm 和 node 的版本不合适导致的,参考:Unexpected end of JSON input while parsing near错误解决方式(网上的方法)

后面依次执行了下面的命令,最终成功生成了该文件夹:

npm -g i npm@4

npm cache clean --force

npm install

React Native - 环境搭建(踩坑指南)_第3张图片
image

重点来了

上面的这个过程很麻烦,并且降低了 npm 的版本后会不会导致其它环节出问题,谁也不知道。这属于不确定因素。所以这里还提供一个简单的办法:

安装 yarn:
npm install -g yarn react-native-cli


配置代理:
npm config set registry https://registry.npm.taobao.org --global
npm config set disturl https://npm.taobao.org/dist --global

yarn 是 Facebook 提供的用来替换 npm 的工具,执行如下命令后就可以替代 npm install :

Yarn 工具安装

4.5 java.lang.UnsatisfiedLinkError: could find DSO to load:libreactnativejni.so

同类问题包括:

java.lang.UnsatisfiedLinkError: dlopen failed: "xxx/libgnustl_shared.so" is 32-bit instead of 64-bit

产生这个问题的原因,是因为 RN 中同时存在 arm64-v8aarmeabi-v7a 的 so 文件,在打包时,只会将 arm64-v8a 的 so 打入 app ,导致找不到 armeabi-v7a 对应的 so 文件。具体的原因和分析可以看:【ReactNative】关于32位和64位SO库混合引入Crash解决方案

解决方法,在 app 的 build.gradle 中加入下面配置:

defaultConfig {
        ...
        ndk{
            abiFilters "armeabi-v7a","x86"
        }
        packagingOptions {
            exclude "lib/arm64-v8a/libimagepipeline.so"
        }
    }

4.6 Program type already present: android.support.v4.app.ActionBarDrawerToggle$DelegateProvider

同类问题包括:

Program type already present: xxx

这个问题出现在编译 App 包时,是由于RN 中依赖的包和其它依赖包有重复,需要 exclude 其中的一个包:

implementation("com.facebook.react:react-native:0.55.4"){ // From node_modules
    exclude module: 'android.support.v4'
}

4.7 Failed to resolve: com.facebook.react:react-native:0.55.5

同类问题包括:

Failed to resolve: com.facebook.react:react-native:xxx

这个问题出现在 Build 阶段,是由于无法下载 RN 的依赖导致,具体的原因是由于手动将 com.facebook.react:react-native:+ 修改成了其它版本。

我们查看官方文档可以发现,添加 RN 的依赖时,我们可以看到一段注释: // From node_modules 。这段注释告诉我们,我们依赖进入项目的 RN 版本是有 node_modules 决定的。也就是 RN 项目下的 package.json 内部定义的。

所以,我们解决这个问题的办法有三个:

  1. 直接使用 com.facebook.react:react-native:+
  2. 根据 package.json 内部定义,修改依赖的版本
  3. 修改 package.json 内部定义

上面的三个方案,有两点需要注意:

  1. 直接使用 com.facebook.react:react-native:+ 时,依然可能出现导入的 react-native 包的版本与 package.json 中的定义不一样,这时候,我们先在 App 中去掉这个依赖,然后 clear 工程,在 RN 目录下,删除 node_modules 文件夹,再通过命令重新生成,之后再在 App 中加入依赖。
  2. 修改 package.json 内部定义后,也需要重新生成 node_modules 文件夹

4.8 com.facebook.react.bridge.JSExecutionException: TypeError: undefined is not a function (evaluating '(bridgeConfig.remoteModuleConfig||[]).forEach')

这个问题可能会出现在 App 访问 RN 的 Activity 时出现,目前具体原因还不清楚,只能基本确定和我们的依赖有关。

解决方案(仅供参考):

这个问题会伴随着一个 url 链接,我们首先通过浏览器访问这个 url ,首先确定我们的 RN 服务器是正常的,其正常界面入下图所示:

React Native - 环境搭建(踩坑指南)_第4张图片
正确访问时的样子

如果没出现上图界面

说明我们的 RN 代码有问题,先检查 RN 服务器是否打开,如果不行就删除 node_models 重建。

如果出现上图界面

说明 App 的依赖存在问题,参考 4.7 的三个办法中的第一个办法以及对应的注意点进行操作。

5. Demo 地址

CSDN(强制要的1分):RN项目集成测试

百度云盘(免费密码 mh4x):RN项目集成测试

6. 鸣谢

RN 中文社区

Unexpected end of JSON input while parsing near错误解决方式(网上的方法)

【React Native】在原生项目中集成之坑点总结

【ReactNative】关于32位和64位SO库混合引入Crash解决方案

你可能感兴趣的:(React Native - 环境搭建(踩坑指南))