React Native组件开发指南

9次阅读

共计 3558 个字符,预计需要花费 9 分钟才能阅读完成。

React Native 的组件开发一直处在一个比较尴尬的处境。在官方未给予相关示例与脚手架的情况下,社区中依然诞生了许许多多的 React Native 组件。因为缺少示例与规范,很多组件库仅含有一个 index.js 文件。这种基础的目录结构也导致了一些显而易见的问题,例如“如何测试”,“如何预览”,“如何开发”…… 本文将为各位提供一种 React Native 组件开发的示例目录结构及相关配置指南。
示例目录结构
.
├── 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 目录。
根目录包含了 eslint 配置,babel 配置,README, gitignore, package.json。其中 babel 配置与 package.json 中的依赖定义是为了运行测试用例而存在的。
src 目录包含了当前 React Native 组件的源码,是组件开发最主要的目录。
test 目录包含了当前 React Native 组件的测试相关代码。
demo 目录包含了一个独立的 Expo 项目,其中 App.js 文件是开发组件示例最主要文件,其中会引用 src 目录中提供的组件来进行开发与展示。该目录的配置详情会在下文中继续展开。
为什么用 Expo 来进行开发与展示?
Expo 是一个基于 React Native 包裹的 React Native 应用开发框架。许多 React Native 的开发者对于 Expo 依然持怀疑态度。不可否认的是用 Expo 来开发 React Native 应用确实存在一些问题,例如:

引入 Expo SDK 后,应用体积过大的问题
缺乏应用在后台运行的能力

但是绝大多数 Expo 的弊端是我们在组件开发中不会遇到或者可以避开的,那么随之而来的便是 Expo 的优点:

快速安装与上手
快速在网页、模拟器、实机上预览或测试
与 React Native 的无缝兼容性

相信开发过 React Native 的同学一定会抱怨它沉重的依赖安装,与繁琐的调试过程,而 Expo 正好轻量化了这两个过程,不仅加速了我们的组件开发与预览,也在我们的组件目录中去除了 Native 端相关的代码,轻量化了我们的目录结构。
相关配置指南
引入 Expo
为组件项目引入 Expo 可能没有听上去这么容易,因为我们在上文的目录结构中将 src 目录定义成与 demo 目录平行的目录结构,这就导致了 metro(React Native 打包工具)的默认配置将无法正常打包 demo 目录中的 React Native 代码。为了解决这个问题,我们就需要手动去调整 metro 的配置文件,而 metro 配置文档又以“精简”著称,于是配置 metro 便成了一个极大的困难点。
准备工作
首先我们需要安装 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.js 的 metro 配置文件,并在 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’ 直接引入该文件。
/**

*/
“`
在这里我们将注入在 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。
相关

react-native-component-cli – 快速生成该目录结构的脚手架工具

react-native-hsv-color-picker – 基于该目录结构的组件案例

正文完
 0