pnpm
是 performant npm
(高性能的 npm
),它是一款快速的,节省磁盘空间的包管理工具,同时,它也较好地支持了 workspace
和 monorepos
,简化开发者在多包组件开发下的复杂度和开发流程。
pnpm
比其他包管理器快 2 倍;
node_modules
中的文件为复制或链接自特定的内容寻址存储库;
pnpm
内置支持单仓多包;
pnpm
默认创建了一个非平铺的 node_modules
,因此代码无法访问任意包;
对于以高效、扁平化管理依赖著称的pnpm,优势不言而喻,大家可以去看看神光这篇文章《pnpm 是凭什么对 npm 和 yarn 降维打击的》。
在某个 package.json
场景下,不同包管理模式的性能对比如下:
action | cache | lockfile | node_modules | npm | pnpm | Yarn | Yarn PnP |
---|---|---|---|---|---|---|---|
install | 33.8s | 20.1s | 20.3s | 40.7s | |||
install | ✔ | ✔ | ✔ | 2.1s | 1.4s | 2.6s | n/a |
install | ✔ | ✔ | 9.1s | 5.3s | 7.8s | 1.7s | |
install | ✔ | 13.5s | 9.3s | 14.1s | 7.7s | ||
install | ✔ | 15s | 17.2s | 14.2s | 33.4s | ||
install | ✔ | ✔ | 2.5s | 3s | 8.8s | n/a | |
install | ✔ | ✔ | 2s | 1.4s | 8.7s | n/a | |
install | ✔ | 2.5s | 11.2s | 14.7s | n/a | ||
update | n/a | n/a | n/a | 8.9s | 12s | 6.9s | 14.9s |
图表分析:
图表横坐标为安装时间
(单位:秒),纵坐标为各包管理的工具在不同场景下的表现
。图中可以看出,无论在缓存、版本锁制约条件下,pnpm
更高效。
pnpm
之所以如此高效,最核心的思想就是:全局store + hard link管理。
全局store
好理解,说白了就是在项目的node_modules
下创建一个.pnpm
名称的目录,把项目中所有的依赖都安装到里面,形成一个包名 + 内部依赖 + 版本信息
的序列目录列表。
hard link管理
指的是外面的依赖包不再以实体文件的形式存在,而是创建了一个链接(有点像windows系统的快捷方式)指向store里面的指定依赖,用到该依赖包时去store里面取,如下图,@babel
里面的依赖全部是hard link,真正的实体文件在.pnpm
目录中。
接下来讲下如何用pnpm
来开发和管理组件,以及这样做有什么好处?
由于有了hard link和全局store
的加持,在开发环境中编码,热更新的开发服务响应是非常快的,给开发者有良好的体验环境。
多个组件间的调用依赖简单,举个例子:在1个pnpm monorepos工程里面有3个组件,其中playground
只提供给开发者本地调试用,small-color-ui
和utils
作为发布包,并且small-color-ui
依赖utils
。
.packages
├── playground #本地调试后台,不发布
├── small-color-ui #代码引用utils
└── utils #基础包
我们只需要把3个包在pnpm workspace注册,便能像引用远程组件那样去引入,而且支持实时本地调试。这个功能像是pnpm
自动帮我们做好了npm link
。
常见于yarn
体系下,例如依赖里面有个包名叫 foo
,foo
里面依赖了 bar
,经过 yarn
的扁平化处理,会把依赖foo
和bar
在 node_modules
同一层级目录下。那么根据 nodejs
的寻径原理,用户能 require
到 foo
,同样也能 require
到 bar
。
这样的bar
就是一个幽灵依赖,它有什么问题呢?直到某一天随着foo
包升级,导致它不再依赖bar
,那么在项目引用bar
就会直接报错,因为根本没安装过这个包。
但这种情况不会发生在pnpm
中。上面讲过pnpm
中node_modules
的结构是包名 + 内部依赖 + 版本信息
的序列目录列表,在项目也根本没法直接require bar
。
就是说不同依赖中的子依赖同一个包,而且这个包版本还不一致,导致项目重复安装子依赖包,致增加依赖的维护成本。
在pnpm
体系下,由于所有依赖都打平到全局store里面了,所以不同版本的依赖只会安装一次,足以被整个项目所用。
当然,假如子依赖的版本不一致,pnpm
还是会安装多次的,但是所有父依赖包的引用地址只会指向一处,这也弥补性能和空间上的性能缺陷。
到这里我们大致了解到pnpm
的优势和适用场景,下一篇文章中,会详细的、手把手教大家用pnpm monorepos
技术体系搭建一个企业级可发布的简单版组件。
感谢大家阅览并欢迎纠错,欢迎大家关注本人公众号「似马非马」,一起玩耍起来!🌹🌹
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。
原创声明:本文系作者授权腾讯云开发者社区发表,未经许可,不得转载。
如有侵权,请联系 cloudcommunity@tencent.com 删除。