前言

在 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 中写一个自定义模块相关推荐

  1. 如何在React Native中写一个自定义模块

    前言 在 React Native 项目中可以看到 node_modules 文件夹,这是存放 node 模块的地方,Node.js 的包管理器 npm 是全球最大的开源库生态系统.提到npm,一般指 ...

  2. 如何在React Native中使用Redux Saga监视网络更改

    by Pritish Vaidya 通过Pritish Vaidya 如何在React Native中使用Redux Saga监视网络更改 (How to monitor network change ...

  3. 如何在React Native中创建精美的动画加载器

    by Vikrant Negi 通过Vikrant Negi 如何在React Native中创建精美的动画加载器 (How to create a beautifully animated load ...

  4. 如何在React Native中构建项目并管理静态资源

    by Khoa Pham 通过Khoa Pham 如何在React Native中构建项目并管理静态资源 (How to structure your project and manage stati ...

  5. 如何在React Native中使用react-navigation 5处理导航

    React-navigation is the navigation library that comes to my mind when we talk about navigation in Re ...

  6. 如何在React Native中记录日志?

    本文翻译自:How to do logging in React Native? 如何为Web开发时在React Native中记录变量,例如使用console.log ? #1楼 参考:https: ...

  7. React Native 中的 Android 原生模块

    当使用 React Native 开发 Android 应用时,你可能需要使用没有被 React Native 封装的模块.但你可以使用 Java 编写原生模块,然后选择性的暴露公共接口到 React ...

  8. 如何在React Native中使用文本输入组件?

    You know, an app becomes more authentic and professional when there is the interaction between the a ...

  9. 如何在React Native中使用React JS Hooks?

    In my articles, I'm going to be using either expo or snack online IDE and android emulator. 在我的文章中,我 ...

最新文章

  1. python损失函数实现_pytorch 实现cross entropy损失函数计算方式
  2. C++中void和void*指针的含义 (指针类型的含义)
  3. mysql+误操作怎么恢复_MySQL 误操作后如何快速恢复数据
  4. java学完jdk后学什么_学完了javase之后要学什么?
  5. 查询mysql 中的空文本_MySQL查询以显示空列的自定义文本
  6. 程序员如何用六年时间打造价值10亿的帝国?
  7. 引用数据类型的一些知识
  8. POJ 3061  Subsequence   尺取法   挑战146页
  9. java 软考_关于软考
  10. PLC、传感器 源型漏型、NPN与PNP之间的关系
  11. 处理器阉割版和满血版有什么区别?
  12. npp++常用的匹配正则表达式
  13. 记一次编写刷浏览量,刷查看次数脚本(内附代码)
  14. java中的字符串池
  15. 迈拓恢复出厂设置图解_恢复出厂设置在哪里 如何恢复出厂设置【图解】
  16. flipboard的翻页效果的实现
  17. 老码农眼中的大模型(LLM)
  18. 精华阅读第 13 期 |常见的八种导致 APP 内存泄漏的问题 1
  19. 谷歌三大核心技术(一)The Google File System中文版
  20. grafana+graphit安装笔记

热门文章

  1. javabean 连接mysql_连接mysql的javabean实例+简单分页
  2. android-x86 镜像iso下载_Windows 10(1909)最新12月更新版MSDN官方简体中文原版ISO镜像下载+激huo工ju...
  3. Android external storage
  4. Robbers' watch CodeForces - 685A (暴力)
  5. 约瑟夫问题(java实现)
  6. 动画原理——绘制正弦函数环绕运动椭圆运动
  7. 软件工程中交流的思考
  8. [翻译-ASP.NET MVC]Contact Manager开发之旅
  9. 蓝桥杯 2011年第二届C语言初赛试题(1)
  10. 华为鸿蒙话题作文800字,关于鸿蒙OS 华为最高层发布最新通知:统一口径-华为,智能手机,鸿蒙...