前言
在使用 ReactNative 开发过程中,由于 ReactNative API 有限,难免会遇到无法实现的效果,这时就需要借助原生模块了。
今天我们尝试一下开发一个 ReactNative 原生模块并发布到 npm 仓库。
准备工作
安装 ReactNative 开发环境
创建一个 ReactNative 项目
$ react-native init AwesomeProject
开发原生模块
创建原生模块
创建好项目后,用 AndroidStudio 打开 AwesomeProject/android/
目录下的 Android 项目。
新建一个 Android Library
,我们以原生对话框为例
为原生模块添加 ReactNative 依赖,在 dialogmodule 下的 build.gradle 的 dependencies 下添加
compile "com.facebook.react:react-native:+"
为 app 添加原生模块依赖,在 app 下的 build.gradle 的 dependencies 下添加
compile project(':dialogmodule')
编写原生模块代码
在原生模块中添加继承自 ReactContextBaseJavaModule
的类,重写 getName()
方法,js 代码通过这个 name 来访问原生模块,在该类中添加提供给 js 访问的原生方法
public class DialogModule extends ReactContextBaseJavaModule {
public DialogModule(ReactApplicationContext reactContext) {
super(reactContext);
}
@Override
public String getName() {
return "DialogModule";
}
@ReactMethod
public void showDialog(String message) {
// 原生方法内容
}
原生模块的编写规范不是本文的重点,大家可以参考官方指南原生模块
注册原生模块
- 在原生模块中添加继承自
ReactPackage
的类,注册原生模块
public class DialogPackage implements ReactPackage {
@Override
public List<NativeModule> createNativeModules(ReactApplicationContext reactContext) {
List<NativeModule> modules = new ArrayList<>();
modules.add(new DialogModule(reactContext));
return modules;
}
@Override
public List<Class<? extends JavaScriptModule>> createJSModules() {
return Collections.emptyList();
}
@Override
public List<ViewManager> createViewManagers(ReactApplicationContext reactContext) {
return Collections.emptyList();
}
}
- 在 app 的 MainActivity 中添加该 Package
@Override
protected List<ReactPackage> getPackages() {
return Arrays.<ReactPackage>asList(
new MainReactPackage(),
new DialogPackage() // 添加原生模块的 Package
);
}
到这里,我们的原生模块已经可以供 js 代码访问了
// 导入
import {
NativeModules,
} from 'react-native';
// 调用
NativeModules.DialogModule.showDialog('message')
发布原生模块到 npm
准备发布文件
如果我们发现我们的原生模块特别好用,想让其他人也用到怎么办,类似于 java 的 jcenter 仓库,我们需要把模块发布到 npm 仓库。
复制文件
新建一个文件夹react-native-dialog
,在该目录下创建一个android
文件夹,表示我们要发布的是一个 android 模块,如果你同时开发了这个模块的 iOS 版本,那么放在 ios 目录下即可。
把原生模块 dialogmodule 目录下的文件(除了 build 等临时文件)复制到 android 目录下添加原生模块入口文件
在react-native-dialog
下新建一个index.js
文件
//index.js
import React, { NativeModules } from 'react-native';
module.exports = NativeModules.DialogModule;
- 添加模块信息
在react-native-dialog
目录下使用npm init
命令来创建package.json
文件,该文件包含了我们的模块信息,我们根据提示输入
输入完成并确认后,package.json
文件就创建好了
{
"name": "react-native-dialog",
"version": "1.0.0",
"description": "a native dialog module",
"main": "index.js",
"keywords": [
"dialog"
],
"author": "xxx",
"license": "xxx",
"homepage": "http://xxx.com/",
"repository": {
"type": "git",
"url": "git+https://github.com/xxx/react-native-dialog.git"
},
"bugs": {
"url": "https://github.com/xxx/react-native-dialog/issues"
}
}
添加 README.md
添加模块的详细使用文档,供使用者阅读添加 .npmignore
类似于.gitignore
,配置上传到 npm 需要忽略的文件,可以参考下面的
# Android/IJ
#
*.iml
.idea
.gradle
build
local.properties
发布模块
- 创建 npm 账号
如果没有 npm 账号,需要创建一个账号,这个账号会被添加到npm本地的配置中,用来发布module用
$ npm adduser
Username: your name
Password: your password
Email: yourmail@gmail.com
已有 npm 账号,登录
npm login
根据提示输入信息
成功之后,npm会把认证信息存储在~/.npmrc中,并且可以通过以下命令查看npm当前使用的用户
$ npm whoami
- 发布
在react-native-dialog
目录下执行
$npm publish
+ react-native-nativemodule-example@1.0.0
如果看到下面的提示,说明已经发布成功了。
建议把代码托管到 GitHub ,方便跟踪问题。
测试是否可用
新建一个 ReactNative 项目,按照添加其他原生模块的方法添加我们发布的原生模块,并测试是否可用发布新版本
更新了代码后,只需要修改package.json
文件中的version
字段,并使用npm publish
进行发布
总结
本文主要介绍了如何创建 ReactNative Android 原生模块,并发布到 npm ,重点在于如何发布。
如果你在阅读中遇到问题,欢迎在评论中给我留言。