前语

年前为公司晋级了新的monorepo项目架构,近来不必加班,在家得闲。便想再搭个monorepo项目,随便记载一下。
用到以下pnpm + vite3 + vue3 + ESLint + Stylelint + TypeScriptmonorepe实战记载,此篇为其中一个的简单介绍。

pnpm是什么

pnpm是一个JavsScript包管理东西,是现有东西(npm、yarn)的衍生产品,拥有和npm、yarn类似的功用,以及和类似的运用方法。和很多产品一样,它的呈现是为了处理现有东西的某些问题。而pnpm越来越受开发者喜爱,经过这篇文章你也将会了解到pnpm的优势。

官网介绍:快速的,节约磁盘空间的包管理东西。这儿一切说的快速和节约磁盘空间是相对于现在传统包管理东西(yarn,npm)而言,pnpm愈加快速,更节约磁盘。

符号链接(软链接)和硬链接

pnpm运用了软衔接和硬链接两种方法管理依靠包,在此之前需求先了解下什么是软衔接和硬链接。这儿我按自己所理解的介绍,也可自行百度了解哈。

  • 软链接
    软链接和快捷方法有点类似,是一个指向其他方位的文件[夹],软链接可正常读写文件(读写的便是源文件的内容)。和快捷方法一样,当源文件删去,软链接也无法访问了。但它和快捷方法又有所不同,快捷方法会跳转到实际方位,但软链接不会。

  • 硬链接
    硬链接支撑文件的链接,而不支撑文件夹的链接。硬链接和源文件几乎没有什么区别,和源文件同享一个inode号(文件在文件体系上的仅有标识)。他们同享同样的文件内容,假如一个源文件(或硬链接)改变内容,那么硬链接(或源文件)内容也同样改变。删去源文件后,硬链接可仍旧正常运用。

包管理

为什么有了yarnnpm,还会推出pnpm呢。那就不得不聊聊yarn和npm所存在的问题了。

yarn和npm包管理方法

yarnnpm(3.x之后)选用的平铺的方法,将一切依靠平铺装置的node_modules下。如图

pnpm介绍
package.json只有几个依靠,但在node_modules下却装置了一堆的包,这是因为yarnnpm将依靠(包括依靠的依靠)平铺到node_modules下。
每一个项目都需求将对应的依靠装置到node_modules下,哪怕不同项目有相同的依靠,也都需求下载装置到各自的项目node_modules下。这既消耗时刻,又浪费磁盘空间

平铺方法还存在一个鬼魂依靠的问题,比如某库A依靠库B,那么A、B库都会被平铺装置到node_modules下。假如项目中引入了库B,因为库B也被装置到node_modules下,所以项目可直接访问。假如哪天项目不再需求库A,而将库A删去(或有人重拉项目装置完依靠后),却发现项目因找不到依靠B而跑不起来。这便是所谓的鬼魂依靠:项目中引入没有被界说在其package.json文件中 的包

npm2.x版别选用的是嵌套的方法,将一级依靠装置到node_modules下,二级依靠装置到对应的一级依靠的node_modules下,三级依靠又被装置的二级依靠的node_modules下,以此类推…。这样嵌套的装置方法存在严重的磁盘糟蹋,下载愈加费时,并且window的文件路径还存在长度限制。于是后面版别就选用平铺的方法。

pnpm的包管理方法

了解npm和yarn现在存在的一些问题,能够先停下来想想假如是你会怎样优化呢?

是不是能够将依靠装置到一个公用的存储库中,当项目在装置依靠时,假如存储库中有该项目某些依靠就经过某种方法直接链接到当时项目的node_modules下,那么这些依靠就不必再从网上下载装置了。pnpm运用的便是这种方法。

pnpm有个公共包存储.pnpm store(方位在当时盘的/.pnpm-store/v3/files/下),硬链接着node_modules/.npm下对应的依靠包。
当项目运用pnpm装置依靠包时,只会将package.json中注册的依靠包到node_modules下,并且pnpm的node_modules是基础符号链接(软衔接)的结构,里边的依靠包都会软链到node_modules/.npm下,包括多级依靠也都经过软链的方法平铺在.pnpm下。
如图,node_modules下根据package.json装置的依靠包都有软链符号,它们是都被软链到.npm下了。依靠装置包的实际方位在node_modules/.npm/包名@版名号/node_modules/包名

pnpm介绍
并且装置时会校验存储库中是否有对应的包

  • 假如有直接从.pnpm store创立硬链接到 node_modules/.npm/对应包/node_modules/包名 下。
  • 没有则会下载,再创立硬链接到.npm store

如官方提供的原理包所示。

pnpm介绍

pnpm运用存储库,减少了重复包的下载,假如运用了相同包的不同版别也只会将差异部分添加到库房,大大减少了包装置时刻以及磁盘空间的消耗。并在只会将package.json里的依靠装置到node_modules下,避免了鬼魂依靠的问题。

作业空间(Workspace)

pnpm 内置了对单一存储库(也称为多包存储库、多项目存储库或单体存储库)的支撑, 能够创立一个 workspace 以将多个项目合并到一个库房中,便利我们管理monorepo项目。
项目根目录新建pnpm-workspace.yaml文件,用于界说作业空间包括或排除了哪些目录。

packages:
  // 包括
  - 'packages/*'
  // ! 排除作业区外
  - '!**/test/*'

Workspace 协议 (workspace:)

假定作业区内有两个项目(common 和 layout),common有两个依靠layout@1.0.0, baba@1.0.0

+ packages
| + common   packages: { name: "common", "version": "1.0.0", dependencies: { "layout": "^1.0.0", "baba": "^1.0.0" } }
| + layout   packages: { name: "layout", "version": "1.0.0", }

作业空间下的包能够相互引证,并且默认情况下会优先测验从作业空间下查找,没有查找到再从npm registry装置(当然从npm registry装置前会先判别存储库是否有)。
如上面假定,当common装置依靠时会先在作业区查找(查到包layout@1.0.0),pnpm会从作业区将layout@1.0.0链接到common。依靠包baba@1.0.0在作业区没找到则从npm registry装置。

pnpm 支撑 workspace 协议workspace:。 例如当项目common的依靠这样设置"layout": "workspace:1.0.0",那么pnpm只会从本地作业区查找,如作业区没有则会装置失败。

当根目录下的.npmrc文件(需手动创立)设置link-workspace-packages选项被设置为false时,仅当运用workspace:协议声明依靠,pnpm 才会从此 workspace 链接所需的包。

.npmrc有很多配置,可自行前往查阅。

workspace 协议还能够经过有以下方法引证 workspace包。以 common 引证 layout 为例:

  • 别号:"layout": "workspace:*"
  • 相对路径:"layout": "workspace:../layout"

结语

pnpm的介绍到此就结束了,当然还很多东西没介绍,引荐到pnpm官网翻阅。如有不对的当地还请体谅,欢迎指出~