node 包管理工具对比 npm、yarn、pnpm、yarn berry

飞叶 视频

npm

16~17年 npm@3 之前

依赖通过 简单树形 package 嵌套

两个问题:

  1. 文件深度过深,在window系统一些应用工具下会处理不了过长的路径
  2. 不同包依赖相同包会拷贝大量副本,占用磁盘空间

SemVer 版本管理导致依赖安装不确定
缓存能力存在问题,且无离线模式

npm@3 版本发布后

将依赖拉平到同一级别目录 依赖扁平化

遇到相同依赖的不同版本就无法扁平化(依然会出现重复依赖)
所以只是一定程度解决了文件路径深度问题,
但却带来了新的问题

  1. 同级下皆可互相访问,可能存在安全问题 “幽灵依赖”
  2. 拉平算法是分复杂,运行十分缓慢
  3. 有些包不能被拉平,设计中就依赖路径层级关系(致命)
    更新库,相关依赖也可能不会被提升 (依赖不幂等)

锁文件 - 解决依赖不幂等问题
npm-shrinkwrap.json (v3)
需要手动更新 npm shrinkwrap

v5

受 yarn.lock 启发
package-lock.json 此时的锁文件可以自动更行

本地 package-lock 存在后,npm 就可以不用请求查看依赖包的具体信息,而是直接查找文件缓存,没有缓存则下载。

yarn

npm v3 的思路上,做出了改进。
在较早的时候 yarn 下载速度会快一些,但在依赖处理上依然是扁平化

  • 扁平化算法做了优化,更新依赖时处理更加智能
  • 并行安装
  • 自动更新的锁文件 yarn.lock

同级访问 完全问题实例,
node_modules 中的包 被调用并不需要在packages.json 中体现 (有可能是子依赖)import xx from 'xxx'
但是如果包的子依赖发生变化(对子依赖版本升级或者弃用),项目是不会察觉的,从而导致出错。
npm 中要解决这个问题,就需要检查依赖 dependency-check

workspaces

monorepo 的项目管理方式

pnpm

通过链接树的方式

小满zs 视频
核心内容:

  • symbol link 软连接 相当于快捷方式 ,层级化的包能够复用
  • hard link 硬链接 使用相同的物理地址,使得同一个依赖在电脑上只需要存一份 pnpm-repo

pnpm import 可以将其他包转化

monorepo 技术 可以一键安装子项目依赖 pnpm-workspace.yaml
子模块复用技术 可以将公共部分抽离出来统一管理,实现同步,不需要一次变动多次修改

npm install -g pnpm
pnpm add -g pnpm # 升级 pnpm
pnpm setup # 添加 path

alias 别名

别名优雅解决第三方包出现bug的情况

应急处理
plan1:自己重造轮子 代价太大,不现实
plan2:提 issue 等待,或者自己修复后pr 这些都不会尽快发版,
plan3:git host 改源 但不够优雅git hosted dependency
plan4:自己另发布npm包(自己pr的情况),但项目中包名要全局修改,甚至要修改node_modules中的依赖

这个时候可以使用 pnpm 的别名功能

新思路带来的问题

  1. 有些 npm 包写死了引用路径,导致不支持
  2. 如果需要调试npm包, 全局store会影响所有工程

yarn berry

pnp 模式
移去node_modules,
.pnp.cjs 顶替
不再需要靠目录来寻址

依赖存储在 .yarn/cache

你可能感兴趣的:(npm,前端,node.js,yarn,pnpm)