React Native組件開發指南

React Native的組件開發一直處在一個比較尷尬的處境。在官方未給予相關示例與腳手架的狀況下,社區中依然誕生了許許多多的React Native組件。由於缺乏示例與規範,不少組件庫僅含有一個index.js文件。這種基礎的目錄結構也致使了一些顯而易見的問題,例如「如何測試」,「如何預覽」,「如何開發」......本文將爲各位提供一種React Native組件開發的示例目錄結構相關配置指南node

示例目錄結構

.
├── src
│   └── index.js
├── test
│   └── index.test.js 
├── demo
│   ├── .gitignore
│   ├── .watchmanconfig
│   ├── App.js
│   ├── app.json
│   ├── babel.config.js
│   ├── metro.config.js
│   └── package.json
├── .eslintrc.js
├── babel.config.js
├── README.md
├── .gitignore
└── package.json
複製代碼

目錄結構主要區分爲4塊內容根目錄src目錄test目錄demo目錄react

根目錄包含了eslint配置babel配置README, gitignore, package.json。其中babel配置package.json中依賴定義是爲了運行測試用例而存在的。git

src目錄包含了當前React Native組件的源碼,是組件開發最主要的目錄。github

test目錄包含了當前React Native組件的測試相關代碼。npm

demo目錄包含了一個獨立的Expo項目,其中App.js文件是開發組件示例最主要文件,其中會引用src目錄中提供的組件來進行開發與展現。該目錄的配置詳情會在下文中繼續展開。json

爲何用Expo來進行開發與展現?

Expo是一個基於React Native包裹的React Native應用開發框架。許多React Native的開發者對於Expo依然持懷疑態度。不能否認的是用Expo來開發React Native應用確實存在一些問題,例如:react-native

  • 引入Expo SDK後,應用體積過大的問題
  • 缺少應用在後臺運行的能力
  • ...

可是絕大多數Expo的弊端是咱們在組件開發中不會遇到或者能夠避開的,那麼隨之而來的即是Expo的優勢:bash

  • 快速安裝與上手
  • 快速在網頁、模擬器、實機上預覽或測試
  • 與React Native的無縫兼容性

相信開發過React Native的同窗必定會抱怨它沉重的依賴安裝,與繁瑣的調試過程,而Expo正好輕量化了這兩個過程,不只加速了咱們的組件開發預覽,也在咱們的組件目錄中去除了Native端相關的代碼,輕量化了咱們的目錄結構babel

相關配置指南

引入Expo

爲組件項目引入Expo可能沒有聽上去這麼容易,由於咱們在上文的目錄結構中將src目錄定義成與demo目錄平行的目錄結構,這就致使了metro(React Native打包工具)的默認配置將沒法正常打包demo目錄中的React Native代碼。爲了解決這個問題,咱們就須要手動去調整metro的配置文件,而metro配置文檔又以「精簡」著稱,因而配置metro便成了一個極大的困難點。app

準備工做

首先咱們須要安裝Expo CLI工具

$ npm install -g expo-cli
複製代碼

在組件庫的根目錄中運行

$ expo init demo
複製代碼

而後選擇

  • blank template
  • managed workflow

你便在demo目錄中生成了一個可運行的Expo項目, 能夠經過運行如下命令來預覽當前的Expo項目

$ cd demo
$ yarn start
複製代碼
配置metro

舊版本metro一般使用rn-cli.config.js做爲配置文件名,而新版本則使用metro.config.js做爲配置文件名。舊版本metro的配置文件格式也與新版本有較大的差異。本文將重點關注新版本metro的配置。

demo目錄中建立名爲metro.config.jsmetro配置文件,並在Expo的應用配置文件app.json中添加以下字段用於重置項目根目錄配置與注入自定義的metro配置文件

"packagerOpts": {
    "projectRoots": "",
    "config": "metro.config.js"
}
複製代碼

metro.config.js中添加以下內容

const path = require('path');
const blacklist = require('metro-config/src/defaults/blacklist');
const escapeRegexString = require('escape-regex-string');

module.exports = {
  resolver: {
    blacklistRE: blacklist([
      new RegExp(
        `^${escapeRegexString(path.resolve(__dirname, '..', 'node_modules'))}\\/.*$`,
      ),
    ]),
    providesModuleNodeModules: [
      'react-native',
      'react',
      'prop-types',
    ],
    extraNodeModules: {
      '@babel/runtime': path.resolve(__dirname, 'node_modules/@babel/runtime'),
    },
  },
  projectRoot: path.resolve(__dirname),
  watchFolders: [
    path.resolve(__dirname, '..'),
  ],
};
複製代碼

來仔細解析一下上面的配置項

  • providesModuleNodeModules: 該配置項爲當前項目提供額外的providesModule路徑解析名。providesModule簡單來講就是一個提供文件路徑別名的手段。例如在一個文件頭部添加以下的註釋,你就能夠在項目別處經過import test from 'test'直接引入該文件。
    /**
    * @providesModule test
    */
    複製代碼
    在這裏咱們將注入在src目錄中被引用的三個庫react-native, react, prop-types,使得src目錄中的引用能正確被metro解析。
  • extraNodeModules: 該配置旨在爲當前項目提供額外引入的模塊,配置格式爲[{ 模塊名 : 路徑 }]。咱們在這裏配置src目錄中須要的額外模塊,例如運行測試時所須要的@babel/runtime模塊。
  • blackListRE: 配置一個正則,打包時忽略掉正則匹配到的路徑。在這裏咱們將根目錄中的node_modules路徑下的全部內容忽略,目的是由於在根目錄下的node_modules中會存在與demo目錄node_modules中相同的庫,例如react-native, react, prop-types。這就會使得providesModule在解析時產生重名,從而致使jest-haste-map報錯。
  • projectRoot: 配置項目的根目錄。
  • watchFolders: 爲項目引入除projectRoot外額外的目錄,在這裏咱們將上層的根目錄加入metro的關注列表。

配置完metro,便可在App.js中引入src目錄中的組件

import React from 'react';
import { StyleSheet, View } from 'react-native';
import Component from '../src';

const App = () => (
  <View style={styles.container}> <Component /> </View>
);

const styles = StyleSheet.create({
  container: {
    flex: 1,
    backgroundColor: '#fff',
    alignItems: 'center',
    justifyContent: 'center',
  },
});

export default App;
複製代碼

如今運行yarn start,就能順利看到你的組件在Expo中展現了。

小結

本文主要提供了一種React Native組件的目錄結構,與「如何在一個React Native組件工程中引入一個含Expo工程的子目錄」的相關配置指南。這裏還須要須要說明的一點是,React Native組件的目錄結構能夠有千萬種,本文只是提供一種可行的思路供你們參考,若有更好的方案也歡迎交流與學習。本文將重點放在了引入Expo的配置指南上,如需查看該目錄結構的全部文件配置,請轉至Github

相關

相關文章
相關標籤/搜索