前言java
在 React Native 項目中能夠看到 node_modules 文件夾,這是存放 node 模塊的地方,Node.js 的包管理器 npm 是全球最大的開源庫生態系統。提到 npm,通常指兩層含義:一是 Node.js 開放式模塊登記和管理系統,另外一種是 Node.js 默認的模塊管理器,是一個命令行軟件,用來安裝和管理 node 模塊。本文旨在探討如何在 React Native 中寫一個自定義的 npm 模塊(相似於插件),並上傳到 npm 上供他人使用。node
npm 使用介紹react
npm 是一個 Node.js 模塊,安裝 Node.js 會默認安裝 npm,能夠在終端中使用如下命令來查看 npm 的版本:android
npm -v
升級 npm:git
sudo npm install npm -g
安裝模塊(安裝完畢後會產生一個 node_modules 目錄,其目錄下就是安裝的各個 node 模塊):github
npm install <ModuleName>
查看 npm 配置:npm
npm config list
設置代理:json
//設置 http 代理 npm config set proxy http://server:port //設置 https 代理 npm config set https-proxy http://server:port
上面介紹了一些 npm 基本命令,接下來就能夠在本地建立一個模塊啦。 首先打開終端中新建一個你想在此建立自定義模塊的文件夾,而後在命令行中登陸 npm。輸入如下命令:react-native
npm adduser
接下來會提示你輸入用戶名和密碼還有郵箱,一一完成後就能夠輸入如下命令來查看當前 npm 用戶了:app
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(); } }