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

相关

相关文章
相关标签/搜索