一文读懂ReactNative0.60的 Autolinking 新特性

4,305 阅读4分钟

React Native 0.60是一个重要的版本更新,带来一些非常有用的变化,其中Autolinking 就是一个非常实用的特性。 看看官方的描述:

Native Modules are now Autolinked

The team working on the React Native CLI has introduced major improvements to native module linking called autolinking! Most scenarios will not require the use of react-native link anymore. At the same time, the team overhauled the linking process in general. Be sure to react-native unlink any preexisting dependencies as mentioned in the docs above.

当我们使用第三方原生依赖时,不再需要执行额外react-native link的命令,就可以自动关联三方库。

更深一层,以前引入原生库时会侵入项目本身的代码(想想安卓上每次都要修改MainApplication.java文件吧),而有了Autolinking后,我们可以有一个更加干净的项目代码。

Autolinking特性官方说明

我们这次在项目中也尝试了这个新特性,总体感觉非常不错,安利一下。

如果你是已有项目升级RN到0.60,记得要使用react-native unlink 移除现有的关联,再体验Autolinking新特性

一、引入第三方库方法上带了的变化

Before

# install
yarn add react-native-webview
react-native link react-native-webview
# run
yarn react-native run-ios
yarn react-native run-android

After

# install
yarn add react-native-webview
cd ios && pod install && cd .. # CocoaPods on iOS needs this extra step
# run
yarn react-native run-ios
yarn react-native run-android

可以看到,有了autolink特性后,我们不需要再手动执行link命令来链接原生库。 但是在ios平台上,我们需要使用pod install命令来安装原生依赖。 也就是说,在安卓平台上,RN会自动帮我们处理原生依赖,ios则使用了pod来管理。

二、autolink对项目代码的影响

ios

当使用react-native link命令关联原生依赖时,会自动执行如下操作

1.将三方库的.xcodeproj文件加入到工程的Libraries分组中

2.将三方库的.a文件引入到项目的Link Binary With Libraries组内

而在使用了autolink后,ios平台统一使用CocoaPods来管理三方库,第三方依赖都在pods中管理,不在影响我们原来的工程代码。

安卓

当使用react-native link命令关联原生依赖时,会自动修改三个文件

  • settings.gradle
  • app/build.gradle
  • MainApplication.java

以React Native DateTimePicker为例

// setting.gradle
include ':react-native-datetimepicker'
project(':react-native-datetimepicker').projectDir = new File(rootProject.projectDir, '../node_modules/@react-native-community/datetimepicker/android')

// app/build.gradle
dependencies {
    ...
    implementation project(':react-native-datetimepicker')
}

// MainApplication.java
+ import com.reactcommunity.rndatetimepicker.RNDateTimePickerPackage;

public class MainApplication extends Application implements ReactApplication {

  @Override
  protected List<ReactPackage> getPackages() {
    @SuppressWarnings("UnnecessaryLocalVariable")
    List<ReactPackage> packages = new PackageList(this).getPackages();
+   packages.add(new RNDateTimePickerPackage());
    return packages;
  }
}

而在使用了autolink后,这三个文件都不要修改。是的,MainApplication.java中也不需要手动添加package了,因为框架会自动去发现原生依赖,并自动调用构造函数来引入包。

通过以上分析,可以看到,在使用了新的autolink特性后,减少了第三方库对项目代码的侵入,简化了项目管理,确实是一个非常好的改进。

三、autolink可以解决所有问题吗

autolink这么好,是不是可以完全抛弃手动link了呢?

当然不是,跟所有自动化工具一样,总有一些特殊情况是无法覆盖的,所以autolink也提供了相应的方法来处理这些问题。 以极光的分享组件jshare-react-native为例,如果使用autolink,那么在安卓上面就会报错

java:84: 错误: 无法将类 JSharePackage中的构造器 JSharePackage应用到给定类型;

这是因为autolink在引入第三包时,总是默认调用无参数的构造函数,而jshare的构造函数确是这样写的:

public class JSharePackage implements ReactPackage {

    public JSharePackage(boolean toastFlag, boolean logFlag) {
         Logger.SHUTDOWNTOAST = toastFlag;
         Logger.SHUTDOWNLOG = logFlag;
    }

....
}

所以,这种场景下是无法自动处理的。 当然,我们可以在

node_modules/jshare-react-native/android/src/main/java/cn/jiguang/share/reactnative/JSharePackage.java

中直接修改JSharePackage的构造函数,但是会带来维护不便的问题:不仅每次更新node_modules都需要手动改,而且这个改动需要作为项目约定,团队每个人时刻都需要注意并处理,维护成本太高。

所以更优雅的方法应该是使用官方提供的react-native.config.js 配置来解决这个问题:

config中有一个android.packageInstance参数,用来自定义三方库的实例化方法,如下 platforms.android.packageInstance

Custom syntax to instantiate a package. By default, it's a new AwesomePackage(). It can be useful when your package requires additional arguments while initializing.

因此我们在项目根目录下添加一个react-native.config.js文件,并填入如下配置

// react-native.config.js

module.exports = {
  dependencies: {
    'jshare-react-native' : {
      platforms: {
        android: {
          packageInstance: 'new JSharePackage(false, false)'
        }
      }
    }
  }
}

然后重新run-android即可

关于react-native.config.js的说明,react native CLI cofiguration

欢迎留言交流~


关于我们

深圳市浅海科技有限公司

我们是一个高效、热情、有责任的技术团队,承接各种软件系统定制需求。

长期招聘远程开发者,如果您喜欢尝试新技术,有一点代码洁癖,能够使用文档进行高效的沟通,React/nodejs/ES6任意一种玩的飞起,那么,欢迎来撩~(想赚快钱的请绕道,谢谢)

简历请发送到:service@qianhaikeji.cn

当然,也欢迎甲方爸爸把项目甩我们脸上。