還是不明白 Nnnpm、Yarn、Pnpm、Cnpm?
Hello,大家好,我是 Sunday
包管理工具是前端開發中的重要一環,但是現在前端的包管理工具有很多。很多新同學很難搞清這么多不同的包管理工具之間的差異,所以說,咱們今天就針對 npm、yarn、pnpm、cnpm 來進行下統一的介紹,幫大家梳理清楚這些包管理工具的區別!
npm:當之無愧的老大哥
說起前端的包管理工具,就不得不提 npm ——全稱 Node Package Manager,是 Node.js 官方自帶的包管理器,也是前端構建工具鏈的基礎之一。
npm 最初誕生于 2010 年,當時隨著 Node.js 的流行而快速崛起,它解決了 JavaScript 社區長期以來的代碼共享難題 —— 你不再需要手動復制粘貼 JS 代碼片段,而是可以直接通過一個命令安裝和管理第三方模塊。
在那個前端還靠一手 jQuery 打天下的年代,npm 在當年絕對是一種全新的概念。
npm 包含了如下核心功能:
- 依賴安裝:npm install 一鍵安裝項目所需模塊
- 版本管理:通過 package.json 和 package-lock.json 管理依賴版本
- 模塊發布:可將自己的代碼發布到 npm 倉庫(registry),供他人使用
- 腳本系統:支持 npm run 執行構建、測試等命令,成為項目自動化的入口
只不過,最為最初的包管理工具,npm 一開始(當然也包括現在)也存在非常多的問題,比如說:安裝慢、node_modules 過大、依賴庫版本鎖定不一致 等等的問題。
雖然,npm 在 v5 之后,進行了大量的優化,但是很多問題依然存在。比如,很多同學都問過我的這個報錯(使用 cnpm 安裝即可解決):
圖片
同時也是因為這些問題,所以才出現了后續的 yarn、pnpm、cnpm 等
yarn:為解決 npm 的問題而來
2016 年,Facebook 等大廠聯合推出了一個全新的包管理器 —— Yarn,它的誕生不是為了顛覆什么,而是為了解決當時 npm 的諸多“痛點”。
在那個 npm install 慢如蝸牛、依賴版本時常出錯的年代,Yarn 就像是完成了一次大的技術升級,把整個包管理的流程都做了優化。
- yarn.lock 文件:引入了自己的鎖文件(區別于 npm 的 package-lock.json),更早解決了依賴版本不一致的問題
- 更快的安裝體驗:Yarn 通過緩存機制和并行安裝方式,大大提升了安裝速度。裝過一次的包,下次無需重新拉。
- 離線安裝:這是一個非常實用的特性,即使斷網,你也可以依賴緩存離線安裝項目,適合對網絡依賴敏感的開發場景。
- 原子化安裝:安裝失敗會自動回滾,防止項目進入“半安裝”狀態。
目前,Yarn 的最新版本為 V2 代號:Berry(2020 年 1 月發布),在這個版本中 Yarn 將架構進行了重新,提供了一個叫做 Plug'n'Play (PnP) 的概念。這種方式會 跳過 node_modules,依賴通過 .pnp.cjs 文件直接映射,但是對于已經習慣了 node_modules 的前端開發者來說,就有點不太友好了。
pnpm:解決硬盤空間不足的問題
我們項目中所有的包都會被安裝到 node_modules 中,這就導致 node_modules 會變得非常大!有多大呢?大家可以看下自己項目中的 node_modules 大小,你會發現它的體積可能會比你的代碼體積大了 100 倍以上。當時還出現了一個這樣的表情圖:
因此,pnpm 就出現了。其核心就是為了解決 node_modules 占用硬盤空間過大的問題
pnpm 通過一種“硬鏈接 + 內容尋址”的存儲方式,將所有依賴包統一下載到全局緩存中(.pnpm-store),每個項目的 node_modules 并不真的“安裝”包,而是使用軟鏈接指向緩存中的真實文件,同一個包只會下載、存儲一份,再多個項目共用。
這樣就帶來了巨多好處,比如:下載速度飛快,空間占用大幅度下降,并且還可以完美兼容現有生態(保留 node_modules)。
并且,針對 Monorepo 架構,pnpm 也提供了非常好的支持(應該可以說是支持最好的包管理器了)
cnpm:國內的淘寶鏡像
cnpm 和前面所有的包管理工具不太一樣,嚴格來說 cnpm 不應該被叫做包管理工具,而應該被叫做一個 cli 工具。
因為,npm 的官方源服務器在國外,所以,我們在使用 npm install 時常常遇到下載失敗的問題。
那么為了解決下載失敗的問題,阿里巴巴就維護了一套 npm 的鏡像源,每間隔幾分鐘就會自動同步 npm 的數據,從而保證數據與 npm 一直,就好像是 npm 的鏡子一樣。那么在我們就可以直接從國內阿里的鏡像源來安裝依賴了。
所以,cnpm 的正確的概念應該是 cnpm = npm 的國內鏡像 + 一套 CLI 工具。