前端组件库架构设计

3,835 阅读4分钟

这是我参与8月更文挑战的第3天,活动详情查看:8月更文挑战

1. 整体架构

前两天我们已经搭建好了 npm 私有库,但光是有私库是不够的,考虑到私库需要迭代,也需要提供使用说明,因此我们还需要一个存放私库源码的仓库。这个仓库用于维护私库的基础信息,使用方法,在线 demo,同时它也应该具备有发布到 npm 私有库的功能。

基于以上考虑,我们的前端资源仓库整体架构如下:

2. 源码架构设计

从上图来看,我们已经解决了 npm 私有库的问题,对于组件库的整体架构设计而言,核心问题是组件库的代码是如何组织和管理。

业界一般会把同一类组件库用单个仓库的形式维护,并且把组件开发成 NPM 包的形式。这里的重点是,你要考虑把所有的组件打包成一个大的 NPM 包,还是分割是一个个独立的小 NPM 包 。 这两种选择会使仓库的目录结构有不小的差异,进一步又会影响到后面组件的开发,构建,发布。

单包架构

如果你选择把所有的组件看成一个整体,一起打包发布,这叫做单包架构。单个仓库,单个包,统一维护统一管理,比如 antd。

优点

  • 可以通过相对路径实现组件与组件的引用,公共代码之间的引用。

缺点

  • 组件完全耦合在了一起,必须把它作为一个整体统一发包。

PS:选择使用单包架构的话,那么必须提供按需加载的能力,以降低使用者的成本。

多包架构

多包架构的每个组件彼此独立,单独打包发布,单个仓库多个包,统一维护单独管理。

优点

  • 组件发布灵活,支持按需使用。

缺点

  • 组件与组件之间物理隔离。对于相互依赖,公共代码,只能通过 NPM 包引用的方式来实现。

在前端领域,我们使用第三方库 Lerna 来维护这样的架构,Lerna 针对包之间有依赖的场景做了一些特殊优化,开发模式下,它会把所有存在依赖关系的包通过软链的形式连在一起,就可以很方便的本地开发联调。

如何区分是单包还是多包架构

每个组件都没有 package.json,不能单独发布到 npm,每次改动都需要一起打包发布,也不能单独下载,这个是单包架构。

每个组件都有 package.json,可以单独发布到 npm,这个是多包架构。

3. 基于 Lerna 的多包管理架构

经过考虑,我们的组件库基础框架是基于【Lerna】的多包管理架构。Lerna 是一个管理工具,用于管理包含多个软件包(package)的 JavaScript 项目。

基于 Lerna 的多包管理架构的优点在于:

  • 组件级别解耦,独立版本控制,每个组件都有版本记录可追溯
  • 组件单独发布,支持灰度、版本回滚以及平滑升降级
  • 按需引用,用户安装具体某个组件包,无需配置即可实现按需加载的效果
  • 关注点分离,降低大型复杂度、组件之间依赖清晰且可控制
  • 单一职责原则,降低开源基友的参与和贡献难度

Lerna 安装和使用教程

1. 安装和初始化

全局安装

npm install -g lerna

初始化 lerna,会在项目根目录下添加 lerna.json 配置文件。

lerna init -i  // -i 独立模式,包版本单独管理

2. Lerna 常规命令使用

安装依赖

// 安装所有 packages 的依赖项并且连接本地包的交叉依赖项
lerna bootstrap

// 将各包中相同的依赖提取到根 node_modules, 最好先 lerna clean 删除各包依赖
lerna bootstrap --hoist

删除依赖

// 删除所有 packages 下的 node_modules,不会删除 root 目录的 node_modules
lerna clean

// 删除指定包下面的 node_modules
lerna clean --scope=<package-name>

创建 package(也可以在packages目录下手动创建)

// -y 通过lerna 快速创建
lerna create <packageName> -y 

安装依赖

// 将本地或者远程的包作为依赖项添加到当前的packages中,每次只能添加一个包;
// 如果使用 workspaces,各个包都安装一遍
lerna add axios

// 安装到指定的包中,--scope 指定需要安装的包名
lerna add axios --scope=<package-name> 

使用 import 命令导入本地包

lerna import <path-to-external-repository>

发布到 npm,发布包到npm需要登录,可以通过npm whoami查看当前登录用户,通过npm login进行登录。

lerna publish

4. 开发 npm 包

Lerna 是管理包和包之间的关系的工具,在基础框架搭建起来之后,就进入到组件库的开发流程中。为避免篇幅过长,这部分明天开一个单章简述。