从源代码编译React Native

如果你想使用新的功能,获得官方的修复补丁,尝试还没发布的最新特性,或者维护你自己的不能合并到核心版本的补丁,你可能需要自己从源代码编译React Native。

预备条件#

如果你已经安装了安卓SDK,那么运行android命令打开安卓SDK管理器。

确保你已经安装了以下模块:

  • Android SDK version 23 (编译SDK版本号在build.gradle中可以找到)
  • SDK build tools version 23.0.1(编译工具版本号在build.gradle中可以找到)
  • Android Support Repository >= 17
  • Android NDK(下载及解压指南看这里)

将Gradle指向你的安卓SDK: 设置$ANDROID_SDK$ANDORID_NDK为对应的目录,或者按照以下内容在react-native根目录下创建local.properties文件(注意:windows下需要使用反双斜杠)。

sdk.dir=指向android sdk目录的绝对路径
ndk.dir=指向android ndk目录的绝对路径

例如:

sdk.dir=/Users/your_unix_name/android-sdk-macosx
ndk.dir=/Users/your_unix_name/android-ndk/android-ndk-r10e

从下载链接安装Android NDK#

  1. Mac OS (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-darwin-x86_64.zip
  2. Linux (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-linux-x86_64.zip
  3. Windows (64-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86_64.zip
  4. Windows (32-bit) - http://dl.google.com/android/repository/android-ndk-r10e-windows-x86.zip

更多参考您可以访问官网NDK界面 official page.

译注:建议安装r10e版本,否则在编译过程可能会出错。

编译源代码:#

1.在你的分支代码中进行安装#

首先,在你的分支代码中安装react-native。例如从官方地址安装主干版本:

npm install --save github:facebook/react-native#master

或者,你也可以把仓库克隆到你的node_modules目录,然后运行npm install进行安装

2.添加gradle依赖#

android/build.gradle中添加gradle-download-task依赖

...
    dependencies {
        classpath 'com.android.tools.build:gradle:1.3.1'
        classpath 'de.undercouch:gradle-download-task:3.1.2'

        // 注意:不要把你的应用的依赖放在这里;
        // 它们应该放在各自模块的build.gradle文件中
    }
...

添加:ReactAndroid项目#

android/settings.gradle中添加:ReactAndroid项目

...
include ':ReactAndroid'

project(':ReactAndroid').projectDir = new File(rootProject.projectDir, '../node_modules/react-native/ReactAndroid')
...

修改你的android/app/build.gradle文件,使用:ReactAndroid替换预编译库。例如用compile project(':ReactAndroid')替换compile 'com.facebook.react:react-native:0.16.+'

...
dependencies {
    compile fileTree(dir: 'libs', include: ['*.jar'])
    compile 'com.android.support:appcompat-v7:23.0.1'

    compile project(':ReactAndroid')

    ...
}
...

让第三方模块使用你的分支#

如果你使用第三方的React Native模块,你需要重写它们的依赖以避免它们仍然打包官方的预编译库。否则当你编译时会报错-Error: more than one library with package name 'com.facebook.react'.(错误:有几个重名的'com.facebook.react'的包)

修改你的android/app/build.gradle文件,添加如下内容:

configurations.all {
    exclude group: 'com.facebook.react', module: 'react-native'
}

在Android Studio中构建您的项目#

在Android Studio欢迎页中选择Import project,随后选择您应用所在的文件夹。

您还需要使用Run按钮(译注:Android Studio中绿色的运行按钮)来在设备上运行您的app,此外Android Studio不会自动开启服务,你还需要通过npm start来启动。

其他注意事项#

从源码进行编译将会花费很长时间,尤其是第一次编译,需要下载接近200M的文件然后编译原生代码。每次你在自己的仓库更新react-native版本时,构建的目录可能会被删除,所有的文件都需要重新下载。为了避免构建目录被删,你需要编辑~/.gradle/init.gradle文件来修改构建目录路径。

gradle.projectsLoaded {
    rootProject.allprojects {
        buildDir = "/path/to/build/directory/${rootProject.name}/${project.name}"
    }
}

Additional notes#

Building from source can take a long time, especially for the first build, as it needs to download ~200 MB of artifacts and compile the native code. Every time you update the react-native version from your repo, the build directory may get deleted, and all the files are re-downloaded. To avoid this, you might want to change your build directory path by editing the ~/.gradle/init.gradle file:

gradle.projectsLoaded {
    rootProject.allprojects {
        buildDir = "/path/to/build/directory/${rootProject.name}/${project.name}"
    }
}

Building for Maven/Nexus deployment#

If you find that you need to push up a locally compiled React Native .aar and related files to a remote Nexus repository, you can.

Start by following the Point Gradle to your Android SDK section of this page. Once you do this, assuming you have Gradle configured properly, you can then run the following command from the root of your React Native checkout to build and package all required files:

./gradlew ReactAndroid:installArchives

This will package everything that would typically be included in the android directory of your node_modules/react-native/ installation in the root directory of your React Native checkout.