2024年Stack Overflow開發者調查里,有個數據被大多數人忽略了——在"最常用工具"榜單上,包管理器的滿意度分化比框架本身還劇烈。npm以67%的使用率穩居第一,但"愿意繼續使用"的比例只有54%。與此同時,pnpm的使用率僅11%,推薦意愿卻高達78%。
這組數字說明一件事:大多數人用著默認工具,但知道更好選擇的人已經回不去了。
2025年的JavaScript生態里,四個包管理器各自占據不同生態位。npm是空氣,無處不在;Yarn是遺產,維護著舊帝國的邊界;pnpm是效率狂的私藏;Bun則是新貴,帶著運行時一起砸場子。它們都能把代碼裝到本地,但"怎么裝"這件事,已經分化出四條完全不同的技術路線。
npm:從"能用"到"還行",花了7年
npm 10在2025年的表現,放在五年前會被當成科幻片。冷啟動安裝200個依賴,30-40秒完成。這個數字在npm 6時代是3分鐘以上,而且中途崩潰的概率不低。
速度追上來了,但磁盤開銷仍是硬傷。每個項目的node_modules都是獨立王國,300個依賴膨脹到300-500MB是常態。十個項目就是3-5GB的重復存儲,SSD用戶也開始皺眉。
npm Workspaces(v7引入)解決了多包倉庫的基礎需求,但hoisting機制帶來的"幽靈依賴"問題至今讓人頭疼。你明明沒裝某個包,卻能require進來,CI環境一跑就報錯。這種"本地能跑"的幻覺,調試成本往往比直接報錯更高。
package-lock.json的冗長是另一道風景。一個中型項目的鎖文件輕松突破5萬行,代碼審查時滑半天找不到有效信息。但好處是生態兼容性——每個安全掃描工具、每個CI系統都認得它,這是二十年積累的基礎設施紅利。
npm的真正護城河從來不是技術,而是"默認"。Node.js安裝包自帶,教程默認提及,新人零門檻上手。這種路徑依賴構成的壁壘,比任何功能特性都更難打破。
Yarn:一場分裂造就兩個物種
Yarn的歷史是技術史上最典型的"第二代困境"。2016年Facebook推出Yarn Classic,用鎖文件和并行下載把npm按在地上摩擦。2020年Yarn Berry(v2+)發布,徹底重寫架構,引入Plug'n'Play——然后社區裂成兩半。
分裂至今沒有愈合。Yarn Classic仍在維護模式接收安全補丁,但新功能凍結。大量存量項目依賴yarn.lock,遷移成本讓它們困在v1。Yarn Berry的PnP機制理論上更優:包存在全局zip緩存,通過loader解析,徹底消滅node_modules黑洞。
但PnP的兼容性代價是真實的。不少原生模塊、舊版工具鏈需要額外配置才能跑通。Yarn Berry團隊做了大量兼容層,但"能跑"和"跑得順暢"之間總有縫隙。
Yarn Berry的零安裝(Zero-Installs)是另一個被低估的特性。把緩存提交到Git,CI直接跳過下載步驟。對于網絡環境復雜的團隊,這是救命功能。但代價是倉庫體積暴漲,權衡并不總是值得。
選擇Yarn的人,本質上是在選擇一種工程文化:愿意接受一定復雜性,換取確定性的性能收益。這種 trade-off 在大型團隊里更容易被接受——有專人維護工具鏈,個體開發者感知到的摩擦被組織消化了。
pnpm:磁盤效率的暴力美學
pnpm的技術路線可以用一個類比理解:npm像每個項目各自買全套工具,pnpm像社區共享工具庫,用時去取。全局內容尋址存儲(content-addressable store)讓同一個包版本只存一份,硬鏈接到各項目的node_modules。
實測數據很直觀。10個項目都依賴lodash@4.17.21,npm存10份,pnpm存1份。磁盤節省比例隨項目規模遞增,單開發者機器上省出幾十GB并不夸張。CI環境的緩存效率同樣提升,因為緩存鍵的命中率更高。
速度方面,pnpm與Yarn Berry處于同一梯隊,顯著快于npm。內容尋址存儲的副作用是"秒級復用"——曾經下載過的包,新項目安裝時幾乎無感知。
pnpm的嚴格依賴樹是另一張王牌。默認不允許訪問未聲明的依賴,幽靈依賴問題從源頭消失。這對大型monorepo至關重要——包之間的隱式耦合是技術債的溫床,pnpm的嚴格性相當于強制性的代碼審查。
Workspace功能的設計也體現出對monorepo場景的深度理解。過濾命令(--filter)讓開發者精準操作子集,任務編排(pnpm run --parallel)替代了專門的工具如lerna。很多團隊砍掉了一層工具鏈復雜度。
React、Vue、Astro的新項目模板紛紛默認pnpm,這不是偶然。框架作者對開發者體驗的敏感度,讓他們更早意識到磁盤和速度的長期價值。
Bun:帶著運行時一起掀桌
Bun的特殊性在于,它根本不是純粹的包管理器。Jarred Sumner在2022年發布的這個工具,把JavaScript運行時、打包器、測試運行器、包管理器塞進同一個二進制文件。包管理只是它的四分之一功能,但單拎出來已經能打。
速度是Bun最直觀的標簽。用Zig語言編寫,直接操作syscall,繞過Node.js的抽象層。安裝依賴的速度比pnpm再快30-50%,這種差距在大型項目上會被放大到"體感明顯"的級別。
但Bun的包管理器與Node.js生態的兼容性仍在追趕。2024年底的1.0版本解決了大部分阻塞性問題,邊緣案例依然存在。某些postinstall腳本、原生模塊的編譯場景,Bun的處理方式與npm有微妙差異。
更深層的問題是鎖定策略。Bun使用bun.lockb二進制鎖文件,體積小巧、解析飛快,但生態工具鏈的支持度遠不及package-lock.json和yarn.lock。安全掃描、依賴分析、SBOM生成,這些企業級流程的適配需要時間。
選擇Bun的人,本質上是在押注一個更激進的未來:JavaScript工具鏈的重新統一。如果Bun的運行時市場份額持續增長,它的包管理器會獲得天然的協同優勢。但這條路的風險同樣真實——技術棧的押注錯誤成本,在2025年仍然高昂。
2025年的選擇矩陣
沒有 universally correct 的答案,但有清晰的決策路徑。
團隊規模小、項目數量少、追求零配置——npm 10已經足夠。它的改進被低估了,"默認"本身就有工程價值。
維護 legacy 項目,yarn.lock 已經存在——Yarn Classic是務實選擇。遷移到Berry的收益,往往不值得測試覆蓋的成本。
大型monorepo、磁盤敏感、CI賬單刺眼——pnpm是當前的最優解。它的設計哲學與這類場景天然契合,社區 momentum 也在向上。
愿意承擔風險、追求極致速度、或者已經在用Bun運行時——bun install是合理嘗試。但建議保留npm作為fallback,關鍵流程的兼容性驗證不可跳過。
一個容易被忽略的細節:Corepack。Node.js 16.13+內置的這個工具,讓切換包管理器變得無痛。corepack enable之后,項目目錄下的packageManager字段自動鎖定版本,團隊協作的"我用yarn你用npm"問題基本消失。
2025年的包管理器戰爭,本質上是"默認夠用"與"優化值得"兩條路線的博弈。npm守住了前者,pnpm和Bun證明了后者的市場空間。Yarn的分裂則是個警示:技術迭代中的連續性斷裂,代價往往由用戶承擔。
你的node_modules今天占了多少G?
特別聲明:以上內容(如有圖片或視頻亦包括在內)為自媒體平臺“網易號”用戶上傳并發布,本平臺僅提供信息存儲服務。
Notice: The content above (including the pictures and videos if any) is uploaded and posted by a user of NetEase Hao, which is a social media platform and only provides information storage services.