Monorepo + pnpm

217 阅读4分钟

什么是Monorepo?

Monorepo 是一种项目代码管理方式,指单个仓库中管理多个项目,有助于简化代码共享、版本控制、构建和部署等方面的复杂性,并提供更好的可重用性和协作性。

阶段一:单仓库巨石应用, 一个 Git 仓库维护着项目代码,随着迭代业务复杂度的提升,项目代码会变得越来越多,越来越复杂,大量代码构建效率也会降低,最终导致了单体巨石应用,这种代码管理方式称之为 Monolith。

阶段二:多仓库多模块应用,于是将项目拆解成多个业务模块,并在多个 Git 仓库管理,模块解耦,降低了巨石应用的复杂度,每个模块都可以独立编码、测试、发版,代码管理变得简化,构建效率也得以提升,这种代码管理方式称之为 MultiRepo。

阶段三:单仓库多模块应用,随着业务复杂度的提升,模块仓库越来越多,MultiRepo这种方式虽然从业务上解耦了,但增加了项目工程管理的难度,随着模块仓库达到一定数量级,会有几个问题:跨仓库代码难共享;分散在单仓库的模块依赖管理复杂(底层模块升级后,其他上层依赖需要及时更新,否则有问题);增加了构建耗时。于是将多个项目集成到一个仓库下,共享工程配置,同时又快捷地共享模块代码,成为趋势,这种代码管理方式称之为 MonoRepo。

image.png

优势

  • 便于管理多个相互依赖的项目;
  • 便于团队共享知识库;
  • 减少项目管理的成本;

劣势

  • 版本管理混乱;
  • 代码质量参差不齐,相互影响;
  • 技术栈升级困难;
  • 难以进行权限管理;

适用场景

充分条件

  • 多个项目之间相互依赖;
  • 功能,版本之间存在强关联;
  • 项目中存在多个编译入口,且构建条件存在差异;

次要条件

  • 希望在团队中共享知识库(代码库);
  • 降低项目管理成本;

pnpm

pnpm 全称是 “Performant NPM”,即高性能的 npm。它结合软硬链接与新的依赖组织方式,大大提升了包管理的效率,也同时解决了 “幽灵依赖” 的问题,让包管理更加规范,减少潜在风险发生的可能性。

安装命令: npm i pnpm -g

pnpm的优势

  • 快速,pnpm会将包缓存到本地,减少二次安装需要的时间;
  • 节省磁盘空间:它会把包硬链接到项目本地,不需要反复安装;
  • 更好的依赖处理逻辑(pnpm可以解决Monorepo项目中存在的幽灵依赖和包的重复引用问题);

幽灵依赖是指,项目代码引用的某个包没有直接定义在 package.json 中,而是作为子依赖被某个包顺带安装了。

Monorepo 实战

一,创建Monorepo工程

创建一个文件夹并cd到该文件夹下执行 pnpm init,获得一个 package.json文件.

创建一个pnpm-workspace.yaml文件(此文件定义了该工程工作空间的目录结构),并将如下的内容粘贴至文件内:

packages:
  # 所有子包的位置
  - 'packages/*'
  # 所有子包/项目公用的组件
  - 'components/**'
  # 所有的api
  - 'api/**'
  # 公用的工具函数
  - 'utils/**'

二,创建子项目

创建packages文件夹并在其路径下执行npm create vue@latest创建两个子项目,之后使用pnpm install安装依赖.

image.png

三,创建并使用项目依赖的公共部分

项目公共部分的使用基本可以分为三种情况:

  1. 没有其他依赖的工具类函数或者静态资源;
  2. 有依赖库的工具类;
  3. 公共的UI组件;

1,没有其他依赖的工具类函数或者静态资源

  1. 创建utils文件夹,pnpm init并修改package.json文件;
  2. 定义并导出公共函数;
  3. 在子项目中使用pnpm add xxx引入工具包;

2.有依赖库的工具类

这里以封装请求工具为例:

  1. 创建api文件夹,pnpm init并修改package.json文件;
  2. 安装axios并对其进行简单封装;
  3. 在子项目中使用pnpm add xxx引入工具包;

3.公共的UI组件

  1. 使用npm create vite 创建一个vue项目,需要包含vue相关才能定义vue组件;
  2. 工程创建成功之后删除其他没有用的文件,留下node_moudles和package.json即可;
  3. 在子项目中使用pnpm add xxx引入工具包;

四,pnpm的一些命令

  • 安装pnpm add xxx 或者 pnpm install xxx;
  • 卸载pnpm remove xxx 或者 pnpm uninstall xxx;
  • 想把插件安装到全局需要使用 -w,例如:安装lodash到全局以保证每个子项目都能直接使用,cd 到顶层文件夹然后执行pnpm add lodash -w;

参考资料

www.modb.pro/db/626876