一文帶你瞭解前端包管理工具npm、yarn和pnpm

為什麼需要包管理工具?

每種主流編程語言都有包管理工具,比如 java 的 Maven、Gradle,Python 的 pip,nodejs 的 npm、yarn、pnpm 等。

包管理工具的主要作用是管理第三方依賴,也可以看成一個"輪子"工廠,每個人都可以上傳自己造的"輪子"和下載使用別人的"輪子",包管理工具顧名思義就是統一管理這些輪子的軟件或者工具,它以多種方式自動處理項目依賴關系、提供瞭命令行工具(CLI)、支持跟蹤依賴項和版本等功能,
除此之外還可以安裝、卸載、更新和升級包,配置項目設置,運行腳本等等。

有瞭包管理工具,我們可以很簡單地構建一個項目或者引入和管理一個庫,留給我們的則是愉快地編碼。

npm 不隻是包管理工具,它是世界上最大的軟件註冊表(registry),每星期大約有 30億次 的下載量,包含超過 600000個包,開發者使用 npm 互相分享和借鑒。

版本管理規范

版本管理規范 – 語義化版本控制規范 SemVer

在使用 npm 和 yarn 安裝完依賴時,package.json 會有類似以下的版本號:

"vue": "^2.6.11",
"vue-router": "~3.1.3"

2.6.11、3.1.3 這個版本號就是遵循瞭 SemVer 語義化版本控制的規范。

SemVer規范規定,版本的格式為:主版本號.次版本號.修訂號-預發版本(可選),版本號遞增規則如下:

  1. 主版本號:當你做瞭不兼容的 API 修改
  2. 次版本號:當你做瞭向下兼容的功能性新增
  3. 修訂號:當你做瞭向下兼容的問題修正。
  4. 預發佈版本:
    1. alpha(Alpha 版本,通常用於進行中的工作和實驗)
    2. beta(Beta 版本,通常是下一個計劃發佈的功能完整的版本,但可能包含已知錯誤)
    3. rc: 候選版本,通常是可能最終(穩定)的版本,除非出現重大錯誤。

在 nodejs 版本管理中,還允許使用 ~ ^ * 字符來管理版本的范圍:

  • ^: 不允許修改最左邊非0版本 (^2.6.11: 版本 >= 2.6.11 且 < 3.0.0)
  • ~: 如果指定瞭次要版本,則隻允許補丁版本更新,如果沒有,則允許次要版本更新 (~3.1.3: 版本 >= 3.1.3 且 < 3.2.0)
  • *: 任何非預發版本 (版本 >=0.0.0)

前端主流包管理工具

主流的前端包管理工具有 npm、yarn、pnpm、以及國內的鏡像 cnpm、tyarn 等,這是包管理器都是基於 nodejs。

npm 是 2010 年發佈的 nodejs 依賴管理工具,在此之前,前端的依賴管理都是手動下載和管理的。

yarn 是 Facebook 於 2016 年 發佈的替代 npm 的包管理工具,還可以作為項目管理工具,定位是快速、可靠、安全的依賴管理工具。

pnpm 是 2017 年發佈的一款替代 npm 包管理工具,具有速度快、節省磁盤空間的特點。

2010:npm 發佈,支持 Node.js。
2016:yarn 發佈,生成 yarn.lock 文件用於確定 repos 的精確版本,並且比 npm 性能更好。
2017:npm 5 發佈,提供類似 yarn.lock 的 package-lock.json 文件。
2017:pnpm 發佈,pnpm 具有 yarn 相對於 npm 的所有附加功能,並解決瞭 yarn 沒有解決的磁盤空間問題。
2018:npm 6 發佈,在 npm 在安裝依賴項之前檢查安全漏洞,提高瞭安全性。
2020:yarn 2 和 npm 7 發佈,這兩個軟件包都具有出色的新功能。
2021:yarn 3 發佈並進行瞭各種改進。

yarn vs npm vs pnpm

包管理工具安裝和版本切換

因為 node 預裝瞭 npm ,所以安裝 node 後,不需要手動安裝 npm。

相反地,yarn 需要手動安裝。建議全局安裝 yarn:

npm install yarn -g

然後,我們在項目的根目錄設置需要的 yarn 版本:

# yarn set version latest # 最新版
# yarn set version canary # 最新的經典版
# yarn set version classic # 最新的經典版
# yarn set version 3.x
yarn set version <version>

使用 Yarn,在每個項目我們可以使用不同的版本,而在 npm 中,要安裝 nvm 才能完成版本切換。

同樣的,pnpm 也需要全局安裝,才能使用

npm install pnpm -g

pnpm 其他使用命令 和 npm 使用方法一致。

安裝項目依賴

在執行 npm install 安裝項目依賴時,依賴項是順序安裝,並且終端會輸出很多的警告日志,導致覆蓋報錯的日志,從而難以排查問題。

使用 yarn 安裝依賴時,運行 yarn 命令即可,yarn 是並行安裝依賴項,這是它比 npm 快的原因之一,yarn 1 中的日志比較簡介幹凈,是以樹形的形式顯示,但是在 yarn 2 和 yarn 3 中日志發生瞭變化,並不像以前直觀。

並且,yarn 還支持離線安裝,隻要以前裝過的包,可以在沒有網絡鏈接的情況下進行。yarn 具有重試機制,單個包安裝失敗不會導致整個安裝失敗。

在 yarn 安裝不同版本的依賴時,會將多個版本歸結為單個版本,避免創建多個副本。

npm 、yarn 和 pnpm 常用命令

  • npm init| yarn init| pnpm init: 初始化命令
  • npm run| yarn run/yarn | pnpm: 運行腳本
  • npm publish| yarn publish: 發佈包
  • npm cache clean| yarn cache clean:清除緩存
  • npm install| yarn | pnpm install/i: 安裝所有依賴
  • npm install [package]| yarn add [package]| pnpm add [package]: 安裝某個依賴項
  • npm install –save-dev/-D [package]| yarn add –dev/-D [package]| | pnpm add –dev/-D [package]: 安裝開發依賴
  • npm uninstall [package]| yarn remove [package]| pnpm remove/rm [package]: 卸載依賴
  • npm update| yarn upgrade| pnpm update/up: 更新全部依賴
  • npm update [package]| yarn upgrade [package]| pnpm update/up [package]|: 更新某個依賴

安全性

npm 最不好的缺點之一就是安全性,曾經的版本發生過幾個嚴重的安全漏洞, npm 6 開始則是在安裝之前會檢查安全漏洞,並且支持使用 npm audit 手動檢查安裝包的安全性,如果發現安全問題,可以運行 npm audit fix 修復漏洞。

因為 npm/yarn 是扁平化依賴結構,有個非常嚴重的問題就是可以非法訪問未聲明的包,而 pnpm 是將依賴通過 link 的形式避免瞭非法訪問依賴的問題,如果沒在 package.json 聲明的話,是無法訪問的。

yarn 和 pnpm 同樣也支持 yarn/pnpm audit 手動檢查安裝包的安全性。

yarn 和 npm 都是使用 hash加密算法 確保包的完整性。

lock 文件

在 package.json 跟蹤的依賴項和版本總是不準確的,因為 ~ ^ * 等前綴表示依賴更新時對應的版本范圍。

范圍版本可以在更新依賴時自動升級依賴到兼容性的次要版本或者補丁版本,讓軟件包支持最新的功能或者修復最近的錯誤。

所以,為瞭避免不同設備安裝依賴時的版本不匹配的問題,在 lock 文件中定義瞭精確的安裝版本。在每次新裝(更新)依賴時,npm 和 yarn 會分別

創建(更新) package-lock.json 和 yarn.lock 文件。這樣就能保證其他設備安裝完全相同的包。

在 pnpm 中,則是使用 pnpm-lock.yaml 文件定義依賴包的精確版本。

性能對比

npm/pnpm/yarn/yarnPnp install 性能對比

測試 package.json 位置

action cache lockfile node_modules npm pnpm Yarn Yarn PnP
install       51s 14.4s 39.1s 29.1s
install 5.4s 1.3s 707ms n/a
install   10.9s 3.9s 11s 1.8s
install     33.4s 6.5s 26.5s 17.2s
install     28.3s 11.8s 23.3s 14.2s
install   4.6s 1.7s 22.1s n/a
install   6.5s 1.3s 713ms n/a
install     6.1s 5.4s 41.1s n/a
update n/a n/a n/a 5.1s 10.7s 35.4s 28.3s

根據上面的測試結果我們可以看出,首次執行 npm install 安裝依賴時 pnpm 比 npm 和 yarn 大約快瞭 3 倍左右,在有緩存和已安裝過依賴的情況,比 npm 也快瞭不少,yarn 則是更快,其他場景 pnpm 也是占瞭很大優勢。

pnpm 的優勢

速度很快、節約空間

pnpm 的所有依賴包統一存儲在 store,不會出現像 npm 或 yarn 每個項目會下載獨立的依賴,yarn 是從緩存下載文件,而 pnpm 是從 store 中鏈接依賴,pnpm 更節約空間,當安裝某個依賴時,新項目會使用硬鏈接到 store 的這個依賴,多個項目不會出現多次安裝依賴的情況,磁盤隻有一次寫入。

對於依賴的不同版本,在 pnpm 中,則隻會保存增量文件。比如:某個包有100個文件,如果更新版本隻會修改其中的一個文件,不會因為新版本的存在而保存所有的依賴文件。

因為 pnpm 的依賴包存儲在 store 同樣也支持離線安裝的功能。

沒有扁平化 node_modules 結構

pnpm 不會扁平化依賴數,它的 node_modules 佈局使用符號鏈接來創建依賴關系的嵌套結構。

pnpm 所有包都有自己的依賴項組合在一起,內部每個包使用符號鏈接將它們組合在一起。

一個 vue3 項目 的 pnpm node_modules 結構

modules-tree-1.png

vite 包的 pnpm 結構

modules-tree.png

參考鏈接

  • pnpm
  • Why should we use pnpm?
  • yarn
  • 語義化版本 2.0.0
  • 漫談前端包管理工具

總結

到此這篇關於前端包管理工具npm、yarn和pnpm的文章就介紹到這瞭,更多相關前端包管理工具npm yarn pnpm內容請搜索WalkonNet以前的文章或繼續瀏覽下面的相關文章希望大傢以後多多支持WalkonNet!

推薦閱讀: