前言java
在 React Native 项目中能够看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统。提到 npm,通常指两层含义:一是 Node.js 开放式模块登记和管理系统,另外一种是 Node.js 默认的模块管理器,是一个命令行软件,用来安装和管理 node 模块。本文旨在探讨如何在 React Native 中写一个自定义的 npm 模块(相似于插件),并上传到 npm 上供他人使用。node
npm 使用介绍react
npm 是一个 Node.js 模块,安装 Node.js 会默认安装 npm,能够在终端中使用如下命令来查看 npm 的版本:android
npm -v
升级 npm:git
sudo npm install npm -g
安装模块(安装完毕后会产生一个 node_modules 目录,其目录下就是安装的各个 node 模块):github
npm install <ModuleName>
查看 npm 配置:npm
npm config list
设置代理:json
//设置 http 代理 npm config set proxy http://server:port //设置 https 代理 npm config set https-proxy http://server:port
上面介绍了一些 npm 基本命令,接下来就能够在本地建立一个模块啦。 首先打开终端中新建一个你想在此建立自定义模块的文件夹,而后在命令行中登陆 npm。输入如下命令:react-native
npm adduser
接下来会提示你输入用户名和密码还有邮箱,一一完成后就能够输入如下命令来查看当前 npm 用户了:app
npm whoami
若是正确显示了刚才注册的用户名,说明登陆成功了。而后就使用如下命令来建立 npm 模块:
npm init
执行上述命令后,会引导你建立一个 package.json 文件,包括名称、版本、做者这些信息等。
建立模块
这里要提一下,为何要写一个自定义模块。由于 React Native 虽然实现了不少 Native 组件,而且提供了丰富的 API,可是有些原生库仍是不支持的,并且有不少开源的组件和库是面向原生的,所以要想在 React Native 中使用这些组件和库就须要本身定义一个模块,这样也方便别人集成。接下来咱们直接进入正题。写一个 React Native 中可使用的自定义模块。在命令行中执行
react-native init AwesomeProject
初始化一个 React Native 项目。这里以 Android 为例,用 Android Studio 选择菜单 File->open 打开 AwesomeProject 文件夹下的 android 文件夹,而后选择 File -> New -> New Module,选择建立一个 Android Library,如图:
如图所示,这里新建了一个 Library module,接下来点击 finish 就能够看到以下的目录结构:
而后将所须要依赖的 jar 放到 libs 目录下,这里以使用 jpush-sdk 为例,将官网上下载的 libs 复制到 libs 下,把相关的资源文件放到 res 文件夹下,再把 AndroidManifest 文件内容复制过来,更改一下包名,最后在 build.gradle 中配置一把,以下(这里要注意把 targetSdkVersion 改为 22,在 23 上运行可能会闪退):
apply plugin: 'com.android.library' android { compileSdkVersion 23 buildToolsVersion "23.0.2" defaultConfig { minSdkVersion 16 targetSdkVersion 22 versionCode 1 versionName "1.0" manifestPlaceholders = [ JPUSH_APPKEY: "yourAppKey", //在此修改 JPush 的 AppKey APP_CHANNEL: "developer-default" //应用渠道号 ] } lintOptions { abortOnError false warning 'InvalidPackage' } sourceSets { main { jniLibs.srcDirs = ['libs'] } } } repositories { mavenCentral() } dependencies { compile fileTree(dir: 'libs', include: ['*.jar']) compile "com.facebook.react:react-native:+" }
到此为止,咱们已经完成了第一步操做,接下来须要写 Native 和 JS 交互的代码,能够参考个人这篇文章中 JS 调用 Native 以及 Native 调用 JS 部分,这里再也不赘述。假设咱们已经完成了 Native 部分代码,咱们如何才能在 JS 中让他人可以经过 import 的方式调用咱们的 JS 代码,从而调用 Native 呢?首先进入 my-react-library 文件夹,而后在终端执行
npm init
生成 package.json 文件(注意这里的 name 字段,这里是别人引用你的模块的名字),而后再建立一个 index.js 文件,这是 node 模块的 JS 入口,这里推荐使用 Sublime Text 进行 JS 的编写。这里以 jpush-react-native 为例:
jpush-react-native/index.js 部分代码
import {NativeModules, Platform, DeviceEventEmitter} from 'react-native'; // 经过 NativeModules 找到咱们在 Native 定义的 JPushModule 类 const JPushModule = NativeModules.JPushModule; export default class JPush { /** * Android only * 初始化 JPush 必须先初始化才能执行其余操做 */ static initPush() { JPushModule.initPush(); } }
上面定义了一个 initPush 方法,initPush 实际上调用了 JPushModule 中定义的 initPush 方法,其余方法与此相似,本质上都是经过 NativeModules 调用了 Native 提供的方法。
发布
到此为止,咱们已经完成了 React Native 自定义模块。如今能够发布咱们的自定义模块了。在 package.json 所在的目录下执行
npm publish
就能够把咱们的自定义模块上传到 npm 库了。每次更新版本时,须要改动 package.json 中的 version 值,而后再执行 npm publish 便可。
使用
在 React Native 目录下,执行:
npm install my-react-library --save
安装完成后就会把这个模块保存到 node_modules 文件夹下,因为咱们的模块是一个 Android Library 项目,因此在 Native 中还须要配置一下。主要是添加项目依赖:
someone's react-native project/some module/build.gradle
dependencies { compile fileTree(dir: "libs", include: ["*.jar"]) compile "com.android.support:appcompat-v7:23.0.1" compile "com.facebook.react:react-native:+" // From node_modules // 在 dependecies 中加入自定义模块 compile project(':my-react-library') }
而后在 settings.gradle 中也要配置一下:
someone's react-native project/settings.gradle
include ':app', ':my-react-library' project(':my-react-library').projectDir = new File(rootProject.projectDir, '../node_modules/my-react-library/android')
在 MainActivity 中将自定义的 Package 添加进去:
MainActivity.java
... mReactInstanceManager = ReactInstanceManager.builder() .setApplication(getApplication()) .setBundleAssetName("index.android.bundle") .setJSMainModuleName("react-native-android/index.android") .addPackage(new MainReactPackage()) //添加自定义的 package .addPackage(new MyReactPackage()) ...
若是是 RN 0.29.0 以上版本,则应在 MainApplication 中添加:
MainApplication.java
@Overrideprotected List<ReactPackage> getPackages() { return Arrays.<ReactPackage>asList( new MainReactPackage(), new MyReactPackage() ); }
到此为止咱们完成了 Native 部分的配置(完成后 sync 一下),接下来就可使用了。 别人要使用咱们的模块时,就能够这样写:
someone.js
//这里的 'my-react-library'是在 package.json 定义的 name // 这样就能够 import MyModule from 'my-react-library' export default class SomeClass extends React.Component { componentDidMount() { // 调用 index.js 中定义的 doSomething() MyModule.doSomething(); } }