如何在 React Native 中写一个自定义模块
前言
在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统。提到npm,一般指两层含义:一是 Node.js 开放式模块登记和管理系统,另一种是 Node.js 默认的模块管理器,是一个命令行软件,用来安装和管理 node 模块。本文旨在探讨如何在 React Native 中写一个自定义的 npm 模块(类似于插件),并上传到 npm 上供他人使用。
npm 使用介绍
npm 是一个 Node.js 模块,安装 Node.js 会默认安装 npm,可以在终端中使用以下命令来查看 npm 的版本:
npm -v
升级 npm:
sudo npm install npm -g
安装模块(安装完毕后会产生一个node_modules目录,其目录下就是安装的各个node模块):
npm install <ModuleName>
查看 npm 配置:
npm config list
设置代理:
//设置 http 代理
npm config set proxy http://server:port
//设置 https 代理
npm config set https-proxy http://server:port
上面介绍了一些 npm 基本命令,接下来就可以在本地创建一个模块啦。
首先打开终端中新建一个你想在此创建自定义模块的文件夹,然后在命令行中登录 npm。输入以下命令:
npm adduser
接下来会提示你输入用户名和密码还有邮箱,一一完成后就可以输入以下命令来查看当前 npm 用户了:
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();}
}
作者:KenChoi - 极光推送
原文:如何在 React Native 中写一个自定义模块
知乎专栏:极光日报
如何在 React Native 中写一个自定义模块相关推荐
- 如何在React Native中写一个自定义模块
前言 在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统.提到npm,一般指 ...
- 如何在React Native中使用Redux Saga监视网络更改
by Pritish Vaidya 通过Pritish Vaidya 如何在React Native中使用Redux Saga监视网络更改 (How to monitor network change ...
- 如何在React Native中创建精美的动画加载器
by Vikrant Negi 通过Vikrant Negi 如何在React Native中创建精美的动画加载器 (How to create a beautifully animated load ...
- 如何在React Native中构建项目并管理静态资源
by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...
- 如何在React Native中使用react-navigation 5处理导航
React-navigation is the navigation library that comes to my mind when we talk about navigation in Re ...
- 如何在React Native中记录日志?
本文翻译自:How to do logging in React Native? 如何为Web开发时在React Native中记录变量,例如使用console.log ? #1楼 参考:https: ...
- React Native 中的 Android 原生模块
当使用 React Native 开发 Android 应用时,你可能需要使用没有被 React Native 封装的模块.但你可以使用 Java 编写原生模块,然后选择性的暴露公共接口到 React ...
- 如何在React Native中使用文本输入组件?
You know, an app becomes more authentic and professional when there is the interaction between the a ...
- 如何在React Native中使用React JS Hooks?
In my articles, I'm going to be using either expo or snack online IDE and android emulator. 在我的文章中,我 ...
最新文章
- python损失函数实现_pytorch 实现cross entropy损失函数计算方式
- C++中void和void*指针的含义 (指针类型的含义)
- mysql+误操作怎么恢复_MySQL 误操作后如何快速恢复数据
- java学完jdk后学什么_学完了javase之后要学什么?
- 查询mysql 中的空文本_MySQL查询以显示空列的自定义文本
- 程序员如何用六年时间打造价值10亿的帝国?
- 引用数据类型的一些知识
- POJ 3061 Subsequence 尺取法 挑战146页
- java 软考_关于软考
- PLC、传感器 源型漏型、NPN与PNP之间的关系
- 处理器阉割版和满血版有什么区别?
- npp++常用的匹配正则表达式
- 记一次编写刷浏览量,刷查看次数脚本(内附代码)
- java中的字符串池
- 迈拓恢复出厂设置图解_恢复出厂设置在哪里 如何恢复出厂设置【图解】
- flipboard的翻页效果的实现
- 老码农眼中的大模型(LLM)
- 精华阅读第 13 期 |常见的八种导致 APP 内存泄漏的问题 1
- 谷歌三大核心技术(一)The Google File System中文版
- grafana+graphit安装笔记
热门文章
- javabean 连接mysql_连接mysql的javabean实例+简单分页
- android-x86 镜像iso下载_Windows 10(1909)最新12月更新版MSDN官方简体中文原版ISO镜像下载+激huo工ju...
- Android external storage
- Robbers' watch CodeForces - 685A (暴力)
- 约瑟夫问题(java实现)
- 动画原理——绘制正弦函数环绕运动椭圆运动
- 软件工程中交流的思考
- [翻译-ASP.NET MVC]Contact Manager开发之旅
- 蓝桥杯 2011年第二届C语言初赛试题(1)
- 华为鸿蒙话题作文800字,关于鸿蒙OS 华为最高层发布最新通知:统一口径-华为,智能手机,鸿蒙...