如何在 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 中写一个自定义模块
知乎专栏:极光日报

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/368733.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

gulp webpack整合

为什么需要前端工程化&#xff1f; 前端工程化的意义在于让前端这个行业由野蛮时代进化为正规军时代&#xff0c;近年来很多相关的工具和概念诞生。好奇心日报在进行前端工程化的过程中&#xff0c;主要的挑战在于解决如下问题&#xff1a;✦ 如何管理多个项目的前端代码&…

SpringBoot 入门第一章

一、前言 Spring Boot 是由 Pivotal 团队提供的全新框架&#xff0c;其设计目的是用来简化新 Spring 应用的初始搭建以及开发过程。该框架使用了特定的方式来进行配置&#xff0c;从而使开发人员不再需要定义样板化的配置。 本系列以快速入门为主&#xff0c;可当作工具小手册阅…

【转】 VC++6.0 在Win7 64位下调试,Shift+F5无法退出

Win7 64位VC6.0调试代码无法关闭窗口解决方法  VC6.0 在64位Windows7下调试的时候&#xff0c;再结束调试&#xff0c;程序无法退出&#xff0c;只能关闭VC6.0 IDE环境。  问题描述&#xff1a;当我击F5开始一个项目的调试时&#xff0c;程序在我设置的断点处停止&#xff…

使用Infinispan创建自己的Drools和jBPM持久性

我 在这里发表的原始文章&#xff1a; 您好&#xff0c;欢迎来到我打算向您展示如何创建自己的Drools和jBPM持久性实现的帖子。 我已经为流口水对象开发了基于infinispan的持久性方案&#xff0c;并且在此过程中学到了很多东西。 如果您想做某种事情&#xff0c;我打算给您一些…

Html5 填表 表单(二) input type 各种输入, 各种用户选择,上传等等泛输入用户交互

<input> 无限制输入 type 限制输入 type 如下类型 type 后还可以跟一些属性: 如<input typetext maxlength 10> 限制文本的长度为10字节 list 可以用的时候再来查, list就是当一个建议值不够的时候添加到几个. <form> <input typ…

c语言 输出音频 单片机,单片机播放WAV格式音频的理解

CSDN账号注册了3年&#xff0c;一直没有上来过&#xff0c;更不用说写博客了。我不知道博客的具体用途&#xff0c;我只想把它当做一种心得来发表&#xff0c;可能是一些技术上的理解或者生活上的小故事。好了&#xff0c;下面我将记录我对WAV播放器的理解。很久以前就看到过某…

UVALive3989 Ladies' Choice —— 稳定婚姻问题 Gale - Shapely算法

题目链接&#xff1a;https://vjudge.net/problem/UVALive-3989 题解&#xff1a; 题意&#xff1a;有n个男生和n个女生。每个女生对男神都有个好感度排行&#xff0c;同时每个男生对每个女生也有一个好感度排行。问&#xff1a;怎样配对&#xff0c;才能使的每个女生尽可能幸福…

通过命令行界面使用AWS ElasticMapReduce

在本文中&#xff0c;我将通过针对EMR的CLI使用AWS MapReduce服务&#xff08;称为ElasticMapReduce &#xff09;。 使用EMR的过程可以大致分为三个步骤&#xff1a; 设置并填充S3存储桶 创建并运行EMR作业 从S3存储桶中获取结果 在开始这三个高级步骤之前&#xff0c;还…

[UE4]关卡蓝图

转载于:https://www.cnblogs.com/timy/p/9053876.html

iframe的缺点

一、iframe会阻塞主页面的onload事件&#xff1b; 二、搜索引擎检索程序无法解读这种页面&#xff0c;不利于SEO&#xff1b; 三、会影响页面的并行加载。 并行加载&#xff1a;同一时间对同一域名下的加载数量是有限制的&#xff1a; 解决方法&#xff1a; 使用js动态给ifr…

使用可视化工具redisclient连接redis

可视化工具推荐&#xff1a;http://database.51cto.com/art/201505/477692.htm 1.连接redis服务端 1.1 设置连接密码&#xff1a;在redis根目录下&#xff0c;双击redis-cli.exe&#xff0c; 输入命令&#xff1a;redis-cli.exe -h 127.0.0.1 -p 6379 -n 1 1就是密码 1.2 使…

android 蓝牙项目代码,Android蓝牙聊天开源项目

前言基于Android Classic Bluetooth的蓝牙聊天软件&#xff0c;目前仅支持一对一实时通信、文件传输、好友添加、好友分组、好友在线状态更新等功能&#xff0c;其中消息发送支持文本、表情等方式。前景蓝牙技术作为一种小范围无线连接技术&#xff0c;能够在设备间实现方便快捷…

你必须知道的.NET之特性和属性(转)

你必须知道的.NET之特性和属性2008-10-13 来源&#xff1a;网络 1. 引言 attribute是.NET框架引入的有一技术亮点&#xff0c;因此我们有必要花点时间走进一个发现attribute登堂入室的入口。因为.NET Framework中使用了大量的定制特性来完成代码约定&#xff0c;[Serializable]…

宽带阻抗匹配的工程实现-第一步,端口驻波仿真

概要 ADS仿真&#xff0c;Matlab仿真&#xff0c;宽带阻抗匹配&#xff0c;smith圆图。 其实阻抗匹配我工作以来经常说&#xff0c;也经常做&#xff0c;但是基本上都是直接在印制板上进行调试。现在想先用仿真软件直接设计出来&#xff0c;才发现很多东西嘴上说容易&#xf…

学web前端一定要这样学,不然学完找不到工作哭都来不及!

因为工作原因&#xff0c;经常关注有关互联网行业的最新动态。这不&#xff0c;刚送走了高考&#xff0c;又迎来了每年的毕业季&#xff0c;看到好多人都说今年的前端工作不好找&#xff0c;很多童鞋简历投了一大堆&#xff0c;也没有回应&#xff0c;发现连实习的机会都没有&a…

android视频通信和web端,探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境...

探讨用webrtc在手机和浏览器之间实现音视频实时通信的实施环境Walker.Xuproduct/develop flow&#xff1a;技术需求&#xff1a;任务拆解:1.android客户端2.前端js网页客户端技术产品&#xff1a;落地&#xff0c;实施在实际应用环境中1.技术因素2.非技术因素选择浏览器的标准&…

XStream – XStreamely使用Java中的XML数据的简便方法

有时候&#xff0c;我们不得不处理XML数据。 而且大多数时候&#xff0c;这不是我们一生中最快乐的一天。 甚至有一个术语“ XML地狱”描述了程序员必须处理许多难以理解的XML配置文件时的情况。 但是&#xff0c;不管喜欢与否&#xff0c;有时我们别无选择&#xff0c;这主要是…

前端微信小程序实战篇

电商底部导航栏的制作 我想大家对电商一定不陌生&#xff0c;一般电商的底部导航栏有以下几个首页、分类、购物车、个人中心。 app.json是用来配置page路径以及导航栏属性的&#xff0c;那我们要做首页、分类、购物车、个人中心界面就要在page也添加这几个界面&#xff0c;所…

Spring MVC –使用@ResponseBody轻松实现基于REST的JSON服务

Spring 3使JSON REST服务非常容易。 本教程将通过几个步骤向您展示如何进行。 您可以在GitHub上获取代码。 先决条件 您应该有一个运行中的Spring MVC应用程序。 如果尚未设置正常的Spring MVC应用程序&#xff0c;请按照本教程进行操作 。 我们将定义三个REST服务&#xff1a…

(转)zabbix3.4使用percona-monitoring-plugins监控mysql

原文&#xff1a;https://blog.csdn.net/yanggd1987/article/details/79656771 简介 之前主要使用nagios监控mysql&#xff0c;本文主要介绍使用percona-monitoring-plugins监控mysql&#xff0c;percona监控插件是php开发&#xff0c;因此要在agent安装php环境。 配置安装 一.…