tags:

  • React
  • React Native

categories:

  • React Native
  • 组件库

作为一个前端 er,谁不想拥有一个自己的组件库。我也想,所以它来了 - rn-vant,使用 vant 设计规范的 React Native 组件库。

组件库目前已经拥有了 40+ 组件(虽然还是很简陋,bug 也是一堆,主要还是我太懒了 😅),也算圆了我的一个梦想,现在是时候做个阶段总结了,将这段时间开发遇到的问题都记录下来,一方面是怕自己忘了,另一方面也是给看到这系列文件的朋友做个参考。

Mono or Multi Repo

from https://juejin.cn/post/6949882490324516894#heading-9

这里简单解释下什么是 MonoRepo 以及 MultiRepo,以及他们的优缺点:

  • MonoRepo:把多个项目放在一个仓库里面管理。
  • MultiRepo:每个项目都对应着一个单独的代码仓库每个项目进行分散管理。

MonoRepo 优缺点:

优点:

  • 统一了工作流由于所有的项目放在一个仓库当中,复用起来非常方便,如果有依赖的代码变动,那么用到这个依赖的项目当中会立马感知到
  • 降低基建成本:所有项目复用一套标准的工具和规范,无需切换开发环境,如果有新的项目接入,也可以直接复用已有的基建流程,比如 CI 流程、构建和发布流程。
  • 提升团队协作效率一方面大家都在一个仓库开发,能够方便地共享和复用代码,方便检索项目源码,另一方面,git commit 的历史记录也支持以功能为单位进行提交,之前对于某个功能的提交,需要改好几个仓库,提交多个 commit,现在只需要提交一次,简化了 commit 记录,方便协作。

缺点:

  • 体积问题:因为所有 code 都在一个 repo 下,这就导致了随着项目越来越复杂,整个 repo 的体积会变得很大。据说某大公司员工想要修改项目中的某个小样式,需要将数以十 G 的 repo 拉到本地,听起来确实是个噩梦。
  • 权限问题:Monorepo 模式下的权限是开放的。代码安全,文档安全,都会是一个需要好好考虑的问题。这个方面如果处理不好的话,对整个团队整个项目带来的后果可能是灾难性的。
  • 版本控制:仓库变得太大,对版本控制技术会有很大的挑战。因为 Git 社区建议的是使用更多更小的代码库,Git 本身并不适合单个巨大的代码库。

Monorepo 和 Multirepo 都是管理组织代码的方式,并没有什么优劣之分,还是那句话“存在即合理”,工具都是用来服务生产的,能更有效解决当下问题的,就是更好的。回到组件库上,按照最初的规划,组件库最少会产出两个 npm 包,组件库本体和 icon 组件,并且组件库会依赖 icon 组件,自然采用 Monorepo 的方式是最好的。

Monorepo 工具

既然选择了 Monorepo,自然就需要看看社区里有哪些好的 Monorepo 工具:

  • Bit用于组件驱动开发的工具链
  • Turborepo:用于 JavaScript 和 TypeScript 代码库的高性能构建系统。
  • Rush:一个可扩展的 web 单仓库管理器。
  • Nx:具有一流的 monorepo 支持和强大集成的下一代构建系统。
  • Lerna:用于管理包含多个软件包的项目

上面这些工具中,我最熟悉的就是 Lerna 了,简单而不简陋,完全能够胜任组件库编排的工作,因此首选 Lerna 了。(性能确实不如其他的工具,比如 Turborepo,但是目前也并没有太大的性能诉求,以后遇到了,可以在迁移)

组件库构建工具

我们的组件库最终是需要发布到 npm 上的,因为组件库的运行环境不在浏览器中,因此只需要提供 ES ModuleCommonJS模块的组件即可,另外如果是 Typescript 工程,构建时还需要输出类型文件,在调研社区开源的组件库会锁定一个工具 - react-native-builder-bob

安装 react-native-builder-bob:

1
yarn add react-native-builder-bob -D

配置及使用都很简单,在 package.json 中新增如下配置:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
"scripts": {
"build": "bob build"
},
"react-native-builder-bob": {
"source": "src",
"output": "lib",
"targets": [
"commonjs",
"module",
[
"typescript",
{
"project": "tsconfig.build.json"
}
]
]
}
}

运行 yarn build后,会在 lib 目录下生成相应模块的文件:

最后在 package.json 中,添加这些模块的入口说明:

1
2
3
4
5
6
7
{
"main": "lib/commonjs/index",
"module": "lib/module/index",
"types": "lib/typescript/index.d.ts",
"react-native": "src/index",
"source": "src/index"
}

代码质量 and 代码风格

代码质量目前只配置了 eslint,后面如果有更好的工具,可以尝试接入。现在使用的是 https://github.com/youngjuning-archive/eslint-config 这个,主要看中它将 prettier 和 eslint 集成到一起了,省了自己配置(prettier 和 eslint 有些规则是冲突的,解决起来超级麻烦),而且 eslint 的规则来自 airbnb,代码质量也有了保障。

代码风格用的是 prettier,因为已经集成到 @youngjuning/eslint-config了,只需要安装 @youngjuning/prettier-config,并简单配置下就能使用了。

1
2
// .prettierrc.js
module.exports = require("@youngjuning/prettier-config");

除了 eslint 和 prettier,我们还能借助一些工具,来帮助我们更好的组织代码:

  • husky:管理 git hook 的工具,可以在 git commit 时,强制校验和格式化代码。
  • lint-staged:针对 git 暂存文件执行一些脚本,结合 husky 可以实现只对改动的文件,校验和格式化,毕竟改一行代码就要校验整个仓库成本还是太高了。
  • commitlint:git commit messages 风格校验工具。

至于如何在 lerna 项目中如何集成这些工具,可以看我的另一篇博客 【lerna 项目中集成 husky、lint-staged、commitlint 和 cz-customizable】,里面做了详细的说明。

总结

本文主要介绍了开发一个组件库需要的一些工具的选型,实际上这些工具熟悉前端工程化的同学都不会陌生,具体的配置可以参考我的组件库项目 - rn-vant。后面我会再介绍下组件方的文档及 CI/CD 的相关配置。