如何在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,如圖:
然后將所需要依賴的 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();
- }
- }