npm vs yarn vs pnpm,誰是你的最佳選擇?

Feature image for npm vs yarn vs pnpm,誰是你的最佳選擇?

簡介

在廣闊的軟體開發宇宙中,套件管理器(package manager)就像默默付出的英雄,確保我們的程式碼不會陷入混亂。還記得我們必須手動管理依賴性的日子嗎?自己下載各式各樣的函式庫,自己規劃目錄編譯程式,那確實是黑暗的時代!

現在如果有某個技術,沒有套件管理器的話,應該不會有人要用吧。

淺嚐 npm

Node Package Manager(npm)是一個廣泛使用的 JavaScript 套件管理工具,它使得開發者能夠輕鬆地安裝、共享和管理依賴的 JavaScript 函式庫和應用程式。npm 不僅是一個命令列工具,也是一個強大的生態系統,提供了數以萬計的可重用程式碼套件,這些套件可以被整合到各種 JavaScript 專案中,從而提高開發效率和品質。

npm 的歷史與演進

npm,作為 Node Package Manager 的代表,僅在 Node.js 對外公開的一年後,於 2010 年盛大登場。Isaac Z. Schlueter 建立了 npm,作為 JavaScript 開發者的指路明燈,指導他們分享和重用程式碼模組。

(開發 Node.js 程式時,通常第一件事就是先尋找 npm 中,是不是有人寫過相同的模組了。)

主要功能與優點

npm 就像開發者的瑞士軍刀。從安裝套件到執行腳本,它都會支援你。package.json 檔案是它的忠實助手,詳細描述專案依賴性、腳本等。

常用命令和使用方法

對於許多開發者來說,像 npm installnpm startnpm test 這樣的命令就像他們早上的咖啡一樣不可或缺。它們簡化了管理和執行 JavaScript 項目的過程。

優點和缺點

優點

  • 大量的模組。
  • 與 GitHub 無縫集成。
  • 活躍的社區支持。
  • 最穩定。

缺點

  • 偶爾安裝時間較慢。
  • 依賴性衝突的可能性。

現在 node.js 和 npm 因為競爭對手影響,已改善很多缺點。

如何安裝 npm

用 Homebrew 最方便啦(macOS only),運行:

brew install node

(注意:npm 與 Node.js 綁在一起,所以通過 Homebrew 安裝 Node.js 也會安裝 npm。)

探索 yarn

yarn 的誕生原因

2016 年,Facebook 推出了 yarn,這是他們對 npm 的一些缺點的改進。目標是更好的性能和更嚴格的安全性。

yarn 的獨特賣點

yarn 用 yarn.lock 文件施展了它的魔法,確保在不同的設備上都能進行一致的安裝。這就像你的依賴項有一位守護天使。

npm 後來也有類似的機制了,package-lock.json。

yarn 與 npm:差異

雖然它們都是 package manager,但 yarn 擁有更快的性能、增強的安全性,以及黃金功能 – 支持單一存儲庫的工作區。

優點和缺點

優點

  • 依賴包安裝快速。
  • 使用 yarn.lock 進行一致性的安裝。
  • 用於管理多包存儲庫的工作區。

缺點

  • 如果從 npm 轉換,可能需要一些學習曲線。
  • 不是所有的 npm 模組都兼容。

如何安裝 yarn

要使用 Homebrew 安裝 yarn,運行:

brew install yarn

yarn 2 及其創新

yarn 2,在依賴管理方面帶來了一個典範轉移。以下是它的一些值得注意的功能:

Plug’n’Play (PnP): yarn 2 不再使用 node_modules 文件夾來存儲套件。相反,它使用一個 .pnp.cjs 文件來管理所有的套件,這使得安裝更快、更節省空間。

Monorepos: yarn 2 更好地支持多個項目在同一個存儲庫中共存,這對大型項目非常有用。

Plugin 架構: yarn 2 允許開發者添加自己的功能,這意味著它可以根據您的需求進行定制。

執行二進制文件: 使用 yarn 2,您可以直接運行已安裝的套件,而不需要進入深層的文件夾或修改設定文件。

從網址運行: yarn 2 允許您直接從網址運行代碼,這使得分享和測試變得更加容易。

測試不同版本: 如果您想嘗試不同版本的套件,yarn 2 可以輕鬆幫您做到。

與其他工具的區別: 與 npm 不同,yarn 2 更專注於運行命令,而不只是安裝套件。

yarn 2 提供了許多新功能和改進,使得 JavaScript 開發更加便捷高效。

pnpm 的崛起

pnpm 的起源

pnpm 的出現是為了解決 npmyarn 在某些情況下可能會遇到的問題,特別是與 node_modules 目錄的大小和冗餘有關。當多個項目使用相同的依賴時,npmyarn 會在每個項目的 node_modules 目錄中重複這些依賴,這可能會導致浪費大量的硬碟空間。

pnpm 如何處理 Node Modules

pnpm 的天才之處在於其獨特的存儲方法。它不是每次 install 就複製一次到 node modules,而是創建一個共享儲存位置並將它們鏈接到項目。這就像是對你的依賴函式庫進行近藤麻理惠式的整理!

不需要的東西就移除

2010年出版《怦然心動的人生整理魔法》,作者近藤麻理惠的書中倡導「只留下心動的東西,其他都丟掉」。

主要功能和好處

pnpm 確保沒有 library 重複,從而節省硬碟空間並快速安裝。

pnpm 使用一種稱為“硬鏈接”的技術來解決這個問題。當安裝依賴時,它不會在每個項目中重複這些依賴,而是在一個共享的儲存位置創建同一個版本,然後在每個項目中創建指向這些依賴的鏈接。這意味著,即使多個項目使用相同的依賴,這些依賴也只會在硬碟上儲存一次。

優點和缺點

優點

  • 高效的硬碟空間使用
  • 更快的安裝速度
  • 一致且可重複的建置

缺點

  • 沒有像 npm 或 yarn 那樣被廣泛採用

使用 Homebrew 安裝

要使用 Homebrew 安裝 pnpm,執行:

brew install pnpm

“Innovation distinguishes between a leader and a follower. (創新區分領導者和跟隨者。)”

– Steve Jobs

pnpm 需要建立 global bin directory

pnpm setup
source ~/.zshrc

比較分析

效能指標

參考跑分測試

這三個套件管理器都是效能強大的,但在速度上,尤其是對於龐大的專案,Yarn 和 pnpm 通常優於 npm。

安全性

pnpm 與 yarn 一樣,有一個特殊檔案,其中包含所有已安裝軟體套件的校驗和。這確保了所有已安裝套件在程式碼執行之前的完整性。

在非特權存取方面,pnpm 也優於 npm 和 yarn。在 npm 和 yarn 的情況下,如果套件 A 依賴於套件 B,並且套件 B 依賴於套件 C,那麼即使 A 沒有將 C 宣告為它的依賴項,A 也會隱式地存取 C。在大型 monorepo 設定中,這個問題會更加嚴重。另一方面,pnpm 使用不同的依賴解析演算法和不同的 node_modules 資料夾結構來防止非法存取套件。

社群和生態系統

npm 作為資深的領袖,擁有最大的社群。但 yarn 和 pnpm 這些後起新秀,正在迅速擴大影響力。

空間使用比較

選擇套件管理器時的一個重要因素是它如何有效地使用硬碟空間。讓我們稍微分析一下:

  • npm:傳統的 npm 方法可能會導致專案之間的套件重複,從而消耗更多的硬碟空間。如果你有多個具有相似依賴性的專案,node_modules 目錄可能會迅速膨脹。
  • yarn:yarn 引入了更有效的快取機制,減少了一些冗餘。但是,它仍然保留了一個 node_modules 目錄,尤其是在大型專案中,這可能會很大。
  • pnpm:真正的空間節省者!pnpm 使用共享儲存機制。它不是在專案之間重複複製,而是建立一個單一版本,然後連結到它。如果你有多個具有重疊依賴性的專案,這可能會帶來顯著的硬碟空間節省。

實際範例

讓我們捲起袖子,深入一些程式碼範例!

// npm 範例
npm init
npm install <package>
npm help

// yarn 範例
yarn init
yarn add <package>
yarn help

// pnpm 範例
pnpm init
pnpm add <package>
pnpm help

可以發現各自有不同的 command 用法,npm 比較簡潔,yarn 的參數超級多,pnpm 有分類說明,但實際上的用途,只有基本的幾個指令。

套件管理器大部分都是在安裝套件,init 也很少用,開發當中就是 run devrun test,不會有太大的區別。如果使用 CI/CD 自動化,那 build 的機會也沒了。

套件執行工具: npx

什麼是 npx?

npx 是隨 npm 一起提供的套件執行工具,npxnpm 版本 5.2.0 中被引入,旨在幫助執行來自 Node 模組的二進制檔案,以及可以在本地專案的 node_modules/.bin 目錄中執行的指令。

npx 的主要功能

  • 執行二進制檔案:沒有 npx,如果你想執行一個本地安裝的套件,你必須深入到 node_modules/.bin/ 或在你的 package.json 中新增一個腳本。有了 npx,你可以直接執行它。
  • 執行未全域安裝的套件:想要執行一個套件而不全域安裝它嗎?npx 可以讓你做到這一點。例如,你可以建立一個 React 應用程式,而不必全域安裝 create-react-app
  • 從 URL 執行程式碼npx 允許你直接從 URL 執行程式碼,使分享和執行腳本變得容易,而不需要將它們發布到 npm 註冊表。
  • 測試不同版本:你可以使用 npx 來執行具有不同套件版本的指令,這對於測試非常方便。

npx 與套件管理器的區別

  • 目的:雖然像 npmyarn 這樣的套件管理器旨在獲取和安裝套件,但 npx 是為了執行指令和二進制檔案而建立的。它更像是 npm 的伴侶工具,而不是替代品。
  • 暫時安裝npx 可以暫時安裝套件和指令,而不必全域安裝它們,確保你的全域空間保持整潔。
  • 靈活性npx 提供了一種靈活的方式來執行工具的不同版本,而不必在全域安裝或在 package.json 中切換版本。

pnpm vs npx

pnpm 也有類似指令:pnpm dlxpnpm exec

在下載的依賴項中執行可執行檔,例如:

npx jest

pnpm 的相對指令是:

pnpm exec jest

在暫時下載的套件中執行可執行指令,例如:

npx create-react-app my-app

pnpm 的相同指令是:

pnpm dlx create-react-app my-app

最後

那麼,你應該選擇哪一個套件管理器呢?是擁有廣大社群的 npm?還是效能出色的 yarn?或是節省空間的 pnpm?

pnpm 非常新潮有趣,yarn 依舊強大,npm 已不可同日而語。我覺得使用上其實並不會有太大差異,重點還是你正在開發的專案,而不是花很多時間在選擇套件管理器。

但我比較喜歡 pnpm,因為比較新、節省空間,node_modules 真的令人討厭,而且和 npm 的指令一模一樣,不用另外學。

選擇權在你手中!根據你的專案需求和特點來選擇。而且,在軟體開發的世界中,沒有萬能的解決方案!