[엔지니어링] 최고 성능의 패키지 매니저 - pnpm

계속 만들고 성장을 가속화하십시오! "너겟 데일리 뉴플랜 · 6월 업데이트 챌린지" 참여 2일차 입니다 . 이벤트 상세보기 클릭

개념

고성능 npm. 고성능 npm. 슬로건은 다음과 같습니다.

빠르고 디스크 공간 효율적인 패키지 관리자。

빠른 디스크 공간 절약 패키지 관리 도구.

특징

  • 빠른. pnpm은 대안보다 2배 빠릅니다.

데이터 소스

  • 효율적인. Node_modules의 파일은 콘텐츠 주소 지정이 가능한 단일 저장소에서 연결됩니다. 글로벌 매장에서 구하는 것으로 이해하시면 되며, 이에 대해서는 추후에 자세히 언급하겠습니다.
  • Monorepos가 지원됩니다. pnpm은 단일 웨어하우스에서 여러 패키지를 기본적으로 지원합니다. --filter 다음에 하위 패키지 이름이 오는 것과 유사합니다. 즉, 새로 설치된 패키지만 이 패키지에 포함됩니다. 간단한 실용 참고서
  • 엄격한. pnpm은 기본적으로 타일이 아닌 node_modules를 생성하므로 코드는 임의의 패키지에 액세스할 수 없습니다.

npm 및 yarn 패키지 관리 메커니즘

npm@3 이전

중첩 설치 방법을 채택합니다. 아래 그림과 같이:

node_modules
└─ foo
   ├─ index.js
   ├─ package.json
   └─ node_modules
      └─ bar
         ├─ index.js
         └─ package.json
复制代码

결점:

  • 패키지는 종종 너무 깊은 종속성 트리를 생성하여 Windows에서 긴 디렉터리 경로로 이어질 수 있습니다.
  • 패키지가 서로 다른 종속성에 필요한 경우 여러 번 복사하여 붙여넣고 여러 파일을 생성합니다.

npm@3+ 및 원사

종속성 편향을 평평하게 합니다.

node_modules
├─ foo
|  ├─ index.js
|  └─ package.json
└─ bar
   ├─ index.js
   └─ package.json
复制代码

결점:

  • 팬텀 종속성. 팬텀 종속성은 package.json에 선언되지 않고 다른 패키지의 종속성을 사용하는 node_modules의 종속성을 나타냅니다.
  • 종속 구조 불확실성. 여기에서 [email protected]아니라 [email protected] 이 강화된 이유는 무엇 입니까?

설치 순서에 따라 모두 가능합니다. 자세한 내용은 를 참조하십시오 . 이 문제를 피하기 위한 솔루션: 파일 잠금

  • npm 包分身。同样的也因为打平了 node_modules 中的依赖,就会造成了相同版本的子依赖包在被不同的项目依赖所依赖时会安装两次(即上面的图,B/C 两个包都依赖了 [email protected]
    • 安装很慢。相同的包安装了两次,占用磁盘空间,相对的安装的速度也会变慢
    • 非单例。当两个不同的组件调用 require("library-f") 时,它们可能会得到两个不同的库实例,这意味着可能会突然出现两个单例的实例(换言之,底层的 “global” 变量被分配到两个不同的闭包中)。会使我们的调试变得非常困难

pnpm 的解决方案

前置知识

inode

每一个文件都有一个唯一的 inode,它包含文件的元信息,在访问文件时,对应的元信息会被 copy 到内存去实现文件的访问。

可以通过 stat 命令去查看某个文件的元信息。

stat README.md
复制代码

hard link

硬链接可以理解为是一个相互的指针,创建的 hardlink 指向源文件的 inode,系统并不为它重新分配 inode。 硬链接不管有多少个,都指向的是同一个 inode 节点,这意味着当你修改源文件或者链接文件的时候,都会做同步的修改。 每新建一个 hardlink 会把节点连接数增加,只要节点的链接数非零,文件就一直存在,不管你删除的是源文件还是 hradlink。只要有一个存在,文件就存在。

.pnpm 中的每个文件都是来自内容可寻址存储的硬链接

soft link

软链接可以理解为是一个单向指针,是一个独立的文件且拥有独立的 inode,永远指向源文件,这就类比于 Windows 系统的快捷方式。删除源文件,软链接就会失效。

修改了软链接或硬链接的文件,另外的硬链接或软链接以及源文件都会发生变化,这里感觉是需要小心的,特别是修改文件以调试的时候,记得还原回去,否则另外一个项目用到的时候,可能会出问题

几个重点结果表现

项目根目录下的 node_modules 中

node_modules 中只有直接依赖的包,而没有间接依赖的包。通过软链接到.pnpm 目录中

.pnpm

虚拟存储目录——.pnpm,所有直接和间接依赖项都链接到此目录中。该目录通过 <package-name>@<version> 来实现相同模块不同版本之间隔离和复用。

Store

pnpm在全局通过Store来存储所有的 node_modules 依赖,并且在 .pnpm 中存储项目的hard links

在使用 pnpm 对项目安装依赖的时候,如果某个依赖在 sotre 目录中存在了话,那么就会直接从 store 目录里面去 hard-link,避免了二次安装带来的时间消耗,如果依赖在 store 目录里面不存在的话,就会去下载一次。

假如全局的包变得非常大怎么办?使用方法为 pnpm store prune ,它提供了一种用于删除一些不被全局项目所引用到的 packages 的功能,例如有个包 [email protected] 被一个项目所引用了,但是某次修改使得项目里这个包被更新到了 1.0.1 ,那么 store 里面的 1.0.0 的 axios 就就成了个不被引用的包,执行 pnpm store prune 就可以在 store 里面删掉它了。

原理分析

我们来看一张原理图:

我们项目中有一个依赖 [email protected][email protected]也有一个依赖 [email protected]

마이그레이션 및 문제

우리는 지금 npm이나 yarn을 사용하고 있는데 pnpm으로 어떻게 더 잘 전환할 수 있습니까?또는 문제가 있습니까?

마이그레이션:

  • 잠금 파일을 마이그레이션합니다. pnpm import를 통해 . 인용하다
  • pnpm만 허용됩니다. 인용하다
  • 갈등을 해결합니다. npm 및 yarn과 동일합니다. package.json의 충돌을 해결하고 다시 설치하십시오.
  • 더...

의문:

  • CI/CD의 전역 저장소 문제. 다른 컴퓨터에 충돌할 수 있으며 권한 문제가 있을 수 있습니다.

  • npm 및 yarn과 비교. 커뮤니티가 아직 활성화되지 않았습니다.

  • 하드 링크에는 Windows와의 호환성 문제가 있습니다.

  • 더…

요약하다

pnpm은 독창적인 하드 링크와 소프트 링크의 조합을 통해 종속성 트리 구조의 node_modules를 완전히 구현하고 Node.js의 모듈 해상도 표준을 엄격히 준수하여 팬텀 종속성 및 npm 아바타 문제를 해결합니다. 그리고 전역적으로 ~/.pnpm-store에 하나의 복사본만 저장하면 다른 프로젝트의 설치 속도도 빨라지고 디스크 공간 점유 문제도 해결됩니다.

참고문헌

おすすめ

転載: juejin.im/post/7103139607243391012