
北鱼扶摇
2022/12/06阅读:66主题:自定义主题1
谈谈前端包管理进化简史
前言
欢迎关注公众号:逻魔代码
前端开发者们每天都在接触 xxx install,前端生态如此繁荣,包管理工具功不可没。最早的包管理工具是 npm(Node Package Manager pkgmakeinst/pm)。
2010 年前端的包管理先驱 npm 正式发布,并被 node 支持,有着功不可没的贡献,同时创造出了比世界上人类已知黑洞更可怕的Object。
经典物理学理论总是脱离不了对于时间、空间的探索,有黑洞,也必然有虫洞...

1、历史的车轮
作为一个与时俱进的前端开发者,每天都会接触 xxx install,包管理器是必不可少的工具。在开始之前我们先来回顾一下前端包管理的发展的简单脉络,去感受一下历史的红尘。

-
2010年之前:前端依赖项需要手动下载并,保存到存储库中 -
2010年1月: npm第一个版本正式发布; -
2015年5月:npm发布v3.x 版本; -
2016年1月:pnpm 提交诞生并发布第一个版本; -
2016年: yarn发布第一个v0.x 正式版本; -
2016年: npm 发布v4.x 版本; -
2017年: npm 发布v5.x 版本; -
2018年: npm 发布v6.x 版本; -
2020年:yarn 发布正式版本 2; -
2020年:npm 发布v7.x 版本; -
2021年: yarn 发布正式版本 3; -
2021年: pnpm发布6.0 版本;
2、npm是什么
刚开始 npm 的设计非常的简单:有一个标准的包管理器供大家下载和查阅,将开发人员从那个“_网上下载资源,在手动解压添加近项目_”的年代中解放出来。
2.1 npm v2.x 黑洞终结者
最初版本的 npm v1.x 、 v2.x 使用了很简单的 嵌套结构 来进行版本管理,第一次使前端开发者从手动管理依赖的开发流程中解放了双手。但是真的就一劳永逸了吗?

问题1: 为什么我的项目占用存储体积这么大,说好的复用呢?
问题2:为什么我的window电脑右键删除失效了呢?
问题3:为什么同一个依赖包同一个版本安装了这么多次呢?
子子孙孙无穷尽也..........
2.2 npm v3.x 的扁平化 大家真的平等吗?
看到npm v2.x 带来的好处的同时,我们也看清了它磁盘杀手的真面目,那么必然会有时代的进步者试图来填补这个黑洞, 既然要换取空间,那最简单的办法就是牺牲时间了。
为了将嵌套的依赖尽量打平,避免过深的依赖树和包冗余,npm v3 将子依赖「提升」(hoist),采用扁平的 node_modules 结构,子依赖会尽量平铺安装在主依赖项所在的目录中。但是项目的依赖们,真的平等了吗?


-
幽灵依赖: -
双生不确定性 -
依赖分身 Doppelgangers
为什么我的项目开发、测试、上线一切正常,突然就线上bug了呢?
2.3 npm 5.x 统筹规划,动态管制,静默别动
扁平化的管理真的无效吗,引发这么多新的问题,既然npm采用语义化的版本号 semver 进行控制,是不是我们可以再改进一下,分级统筹管理,严格控制依赖,就可以解决了.

-
缓存机制:npm cache -
版本锁定: shrinkwrap.json 、package-lock.json
理想很丰满,现实确从来不会让你失望!
3、yarn 新一代包管理工具?
yarn 是 Facebook 在 2016 年推出的新一代包管理工具,不仅具有版本锁定,安装失败自动重试。
3.1 yarn v1.x
使用了并行下载(相比而言 npm 是串行依次下载的),提升了下载速度。

嗯,速度真的很快 ???
3.2 yarn 2.x
2020年发布的yarn v2.x版本,还有一个神奇的 feature:PnP (Plug and Play)安装模式,用一个 .pnp.js 文件代替整个 node_modules 文件夹,这已经超出nodejs的国界了...
由于这个惊人的模式太反常规了,存在兼容性问题,一些包在 pnp 模式下出现依赖错误,目前接受度不高。

4、pnpm(performant npm) 时空中的虫洞?
历史证明,没有创新就没有进步,物质世界不是除了层层依赖的树状结构,就只有散落尘埃的沙子,如果有黑洞那一定存在虫洞。
pnpm 的作者Zoltan Kochan发现 yarn 并没有打算去解决上述的这些问题,于是另起炉灶,写了全新的包管理器,开创了一套新的依赖管理机制

在引用项目 node_modules 的依赖时,pnpm采用内容寻址存储 CAS 机制,通过硬链接与符号链接在全局 store 中找到这个文件。为了实现此过程,node_modules 下会多出 .pnpm 目录,而且是非扁平化结构。
-
硬链接 Hard link:硬链接可以理解为源文件的副本,项目里安装的其实是副本,它使得用户可以通过路径引用查找到全局 store 中的源文件,而且这个副本根本不占任何空间。同时,pnpm 会在全局 store 里存储硬链接,不同的项目可以从全局 store 寻找到同一个依赖,大大地节省了磁盘空间。 -
符号链接 Symbolic link:也叫软连接,可以理解为快捷方式,pnpm 可以通过它找到对应磁盘目录下的依赖地址。
5、pnpm 是前端包管理的银弹吗?

pnpm是终结者吗?可能是,但肯定不是。
正如Sebastian在Twitter上指出的那样,他最初是打算在yarn中使用符号链接的,最终 Sebastian还是放弃了。
-
pnpm 创建的 node_modules 依赖软链接,在不支持软链接的环境中,无法使用,比如 Electron 应用; -
非扁平化破坏性的结构和必须使用自身锁文件pnpm-lock.yaml,都给迁移带来了写成本; -
不同应用的依赖是硬链接到同一份文件上,如果在调试时修改了某个依赖的文件,可能无意间影响了其他项目
参考文章:
欢迎关注公众号:逻魔代码
作者介绍
