赞
踩
在 必不可少的UI组件——组件库开发的基础知识(Vue篇) 中,我们介绍了一些封装 Vue 组件的过程中高频使用到的框架技巧,但是,这并不足以支持我们实现完善的组件库。
建设一个成熟的组件库就像盖一幢大楼,工程化基础就如同脚手架一般,虽然不是组件库核心、必备的部分,但没有它们,整个施工过程就会充满危险、处处收到掣肘。
构建组件库的工程基础需要的工具又广又杂。考虑一个成熟的组件库,它的工程化应当有以下需求:
package.json
,熟练运用一款包管理工具(npm
/yarn
/pnpm
)。monorepo
模式提供了在一个代码仓中集中管理多个零散模块的优秀实践,我们需要掌握这种架构。cjs
、esm
、browser
、d.ts
、样式),满足用户在各个场景下的使用。semver
版本号、git 仓打 tag、生成版本更新记录 CHANGELOG
等操作。本章节主要给大家介绍组件库开发工程化方面的基础知识,先从最基础的包管理和文件组织入手,理清下面两个问题。而后续的构建、测试、发布等流程将在未来实践性更强的篇章中分享。
monorepo
架构对它们进行集中的组织管理?组件库工程往往会拆分出许多子模块:
我们可以先来参考 tinyVue 是如何进行拆分的:
renderless
- 为了使组件的视图与逻辑分离,tinyVue
在这个模块实现组件的逻辑。theme
- 实现组件的主题与样式。vue
- 组件的主体实现,将 renderless
中的逻辑、theme
中的样式与 <template>
模板关联起来。其中每一个组件都被进一步划分为了子模块:vue-common
- 与 Vue
相关的公用方法,包括兼容不同 Vue
版本的适配器模块。vue-icon
- 实现 icon 矢量图标。vue-locale
- 多语言支持。examples/docs
- 组件库的文档。按照传统的 mutirepo
思路,需要为每一个模块建立一个代码仓进行管理。在这种分散管理的模式下,每一个包都有其独立的版本号、配置、发布流程。
而 monorepo
模式就是把所有这些模块集中到一个代码仓中,对它们进行集中统一管理。
monorepo
是当下构建复杂的多模块前端工程更为推崇的一种方式。 我们用下面的例子直观地说明 monorepo
的核心优势:
假设存在以下依赖关系:文档模块 docs
作为本地开发环境,依赖于组件模块 vue
,而组件模块又依赖公共方法 vue-common
。
假如我更新了最下游 vue-common
包中的工具方法,我当然希望上层组件 vue
也能立即适应更新,并即刻反馈在 docs
模块的 demo 示例中,实现丝滑的热更新。
但是很可惜,在传统的 mutirepo
模式下,我们必须先发布 vue-common
模块,再更新组件 vue
包中的依赖版本,接下来执行 vue
包的发布,最后升级 docs
项目中的依赖,才能够查看到更新后的效果。
上述整个过程在顺序上不能出现失误,否则只能废弃这个版本号重新发布。更难受的是,如果我们的修改不到位,再次微调仍然要走一遍发布流程!
另一方面,这些包虽然功能不同,但是它们的项目配置、构建流程、发布流程是不是也有很多相似之处?分散在多个代码仓中,对于许多相似的配置,免不了一顿复制粘贴,一旦我有整体性修改 CI 流程的需求,是不是也要分别修改多个仓,再分别验证其正确性?
从上面的例子,我们可以梳理出 monorepo
对于大部分库的构建者而言最无法拒绝的优势:
更多关于 mutirepo
和 monorepo
的优劣对比,可以参考下面的表格。
通常来说,只要你的项目由多模块组成,并对于各个模块代码的权限管控不敏感,就可以放心使用 monorepo
架构。这里再给大家推荐两篇文章,它们更加理性、全面地对比了两种模式的优劣:
monorepo
不仅仅适用于组件库的开发。这里我们列举其他的适用场景,帮助大家更好地理解这种架构。
核心库与周边适配器
例子:
├── packages
| ├── core
| ├── adapterA
| ├── adapterB
| ├── pluginA
| ├── pluginB
| ├── ...
├── package.json
常规 Web 应用
即使是传统 Web 应用,采用 monorepo
模式也有利于代码的复用,促使团队成员以组件化的思想进行开发,不断抽离公共模块,产生技术沉淀。
├── packages
| ├── portal # 门户网站
| ├── mis # 管理后台
| ├── mobile # 移动端网站
| ├── docs # 开发文档
| ├── shared # 公共库
| ├── api # API 层
| ├── ... # 监控埋码、Nodejs 服务、更多公共模块...
├── package.json
monorepo
的重点在与单仓多包管理,这自然地引出了包管理这一概念。
包管理是处理模块之间依赖关系的核心,在当今的开源模式下,几乎没有任何的项目在开发过程中不需要引用他人发布的公共模块,缺少成熟的包管理机制,我们就只能通过源码拷贝的方式去复用他人的产出。
在正式上手搭建组件库之前,我们应该对“什么是包”有一个清晰的概念,去了解 npm 包的配置文件 package.json
。
一个包或者子模块不一定发布到 npm
仓库,但一定有 package.json
文件。package.json
所在的目录就代表了一个模块/包,这个 json
文件定义了包的各种配置,例如基本信息、依赖关系、构建配置等等。所有包管理器(npm
/yarn
/pnpm
)以及绝大多数构建工具都依赖于这个配置文件的信息。
package.json
中的字段并没有一个绝对统一的标准,除了官方约定的部分标准字段外,很多字段其实是特定的工具约定的。我们在分析配置的时候,要明确各个字段到底由谁读取。
我们只介绍后续搭建组件库的过程中将用到的字段,如果你希望对 package.json
建立更加全面的了解,可以前往以下文章:
包管理器、Node.js
、构建工具都会读取标识字段,未正确设置会导致模块无法被被识别为 npm
包。
name
是区分 npm
包的唯一标识。当一个 npm
仓库中的包被安装到本地,我们能通过名称引用,而不必写复杂的 node_modules/...
引入路径就是得益于此。
对于包名称我们还要了解一个概念叫坐标,具有相同坐标的包会被安装到同一子目录下。例如 @vue/reactivity
和 @vue/runtime-core
会被安装到 node_modules
目录的 @vue
目录下,vue
不属于任何坐标,就会被安装到 node_modules
根目录。
声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/AllinToyou/article/detail/620393
Copyright © 2003-2013 www.wpsshop.cn 版权所有,并保留所有权利。