前端工程化之Monorepo 与 workspaces| 青训营笔记 & 青训营大项目笔记 第 14 天

576 阅读6分钟

这是我参与「第五届青训营 」伴学笔记创作活动的第 14 天

前端工程化之Monorepo 与 workspaces| 青训营笔记 & 青训营大项目笔记

这是我们的青训营项目Bear-ui,欢迎查看交流学习。

零、前言

无论是维护npm包还是开发大型前端系统,都存在在不同功能模块中管理着多个功能相近的包,或者这些包之间存在依赖关系的场景。如果将这些包拆分在不同仓库里,那么面临要跨多个包进行更改时,工作会非常繁琐和复杂。 重复安装、管理繁琐的缺点从npm package诞生起便一直存在,node_modules hell就是该问题的集中体现

一-、项目简介

前端工程化一直是前端圈大热的话题,诚然在一个项目框架和各种脚手架都趋于成熟的年代。一个前端小白几乎可以在不具备任何工程化知识的情况下,利用成熟的脚手架搭建一个前端应用。里面的工程化细节也无需过多去关心。当然这只是限于初级的程序员,一旦项目趋于复杂,会提出各种定制化的要求,或者引入新的技术,也或许需要更过兼容性和性能提升的要求,这就需要不断地修改自己的工程化方案进行适应。

Workspaces 是一个用来在本地的root package 包下面管理多个包的npm 术语和功能。

Workspace 能更好的统一管理有多个项目的仓库,既可在每个项目下使用独立的 package.json 管理依赖,又可便利的享受一条命令安装或者升级所有依赖等。更重要的是可以使多个项目共享同一个 node_modules 目录,提升开发效率和降低磁盘空间占用。

为了简化流程,很多大型项目采用了Monorepo的做法,即把所有的包放在一个仓库中管理,很多知名的开源项目也使用了 Workspace,如 VueReactJest 等。

一句话总结就是可以大大简化对多个项目的统一管理。

二、涉及技术&知识点:

Menorepo的利弊

Menorepo的优点是可以在一个仓库里维护多个package,可统一构建,跨package调试、依赖管理、版本发布都十分方便,搭配工具还能统一生成CHANGELOG; 代价是即使只开发其中一个package也需要安装整个项目的依赖。

在不同包管理中的使用

Monorepo 与 workspaces主要涉及了包管理器的使用,但在NPM、Yarn、Pnpm中都有着相关设置。

NPM

npmv7x新增的workspace,也就是npm15以上能够使用。

Workspaces 是一个通用术语,指的是 npm cli 中的一组功能,这些功能支持从单个顶级根包中管理本地文件系统中的多个包。

这组功能弥补了从本地文件系统处理链接包的更加简化的工作流程。自动链接过程作为 npm install 的一部分,避免手动使用 npm link 来添加对应该符号链接到当前 node_modules 文件夹中的包的引用。

这些在 npm install 期间自动符号链接的包称为单个工作区,这意味着它是当前本地文件系统中的嵌套包,在 package.json workspaces 配置中明确定义。

它可以避免我们再手动的去执行npm link命令,而是在npm install的时候,会自动把workspaces 下面的合法包,自动创建符号链接到根目录的node_modules 里。

能够被单独作为一个包创建符号链接的文件夹,我们就称为一个workspace,所以是可以有多个workspace 的,可以在package.jsonworkspaces 字段中进行配置。

Yarn

Yarn 从 1.0 版开始支持 Workspace (工作区)Yarn Workspaces(工作空间/工作区,本文使用工作空间这一名称)是Yarn提供的Monorepo依赖管理机制,从Yarn 1.0开始默认支持,用于在代码仓库的根目录下管理多个project的依赖。

Yarn Workspaces的目标是使用Monorepo(Monorepository)变得简单,以一种更具声明性的方式处理yarn link的主要使用场景。简而言之,它们允许多个项目共存在同一个代码库中,并相互交叉引用,并且保证一个项目源代码的任何修改都会立即应用到其他项目中。

在以Monorepo为代码组织方式的项目中,依赖管理的规模和复杂度均有不小的提升(这也不难理解,随着”数量“的增加,任何小的问题都会变得复杂)。 如何减少依赖重复安装?如何优雅实现跨目录代码共享?如何对依赖版本进行统一管理以避免版本冲突? 所以这些问题都可以借助Yarn Workspaces来解决。

在Workspace作用空间下的任何一个目录下执行yarn命令都会安装整个Workspace的依赖。

Pnpm

但是我们选择Pnpm,理由如下:

  • 科学的管理依赖,解决了很多 npm 安装依赖存在的问题,node_modules 过大、幽灵依赖。所需空间远小于其他管理器,安装速度数倍快
  • 配置简单清楚、只需几行配置即可
  • 结合了NPM和Yarn的优点、操作习惯,简单易上手

三、实践过程:

  1. 全局安装pnpm
  2. 在 projects 目录(根目录)下增加如下pnpm-workspace.yaml文件即可。并填入需要管理的文件夹
  3. 然后在每个项目下新建package.json 文件,并配置好所需依赖
  4. 没有使用pnpm workspaces前,需要分别在 project1project2 目录下分别执行 pnpm install 来安装依赖包到各自的 node_modules 目录下。或者使用 pnpm upgrade 来升级依赖的包。
  5. 安装完毕后只需要在根目录下pnpm i 即可安装好根目录依赖和各个配置的项目依赖。
  6. bug修复,在yarn和npm中还需要配置好设置,并且npm15以下并不支持,然后配置package.json,添加以下字段,填入项目
 "workspaces": ["project1", "project2"] // 也可以使用通配符设置为 ["project*"]

此时查看目录结构如下:

 projects/
 |--package.json
 |--project1/
 |  |--package.json
 |--project2
 |  |--package.json
 |--node_modules/
 |  |--a/
 |  |--project1/ -> ./project1/

四、总结思考:

  • 查找资料学习,并且达到了目的:简单、便捷的管理多个项目依赖。
  • 遗憾是pnpm并不能解决所有情况,不同依赖会导致冲突
  • 这个功能让我们在本地开发包,尤其是多个互相依赖的包时更加得心应手。

五、 引用参考:

Monorepo最佳实践之Yarn Workspaces

Yarn Workspace 使用指南

工作区 - npm文档

npm7.x 原生支持workspaces,让monorepo更简单