cover

概念圖

為什麼要學 npm 指令?

你有沒有想過,前端開發為什麼離不開 npm?

簡單來說,npm(Node Package Manager)就是前端世界的「零件倉庫」。現代前端開發不可能什麼都自己寫 — 你需要打包工具、UI 元件、HTTP 請求工具、測試框架⋯⋯這些全部都從 npm 安裝。可以說,不會 npm 指令,就等於不會現代前端開發。

初始化與版本

指令說明
npm -v查看 npm 版本
npm init互動式建立 package.json
npm init -y使用預設值建立 package.json

安裝套件

指令說明
npm installnpm i安裝 package.json 中的所有套件
npm i <package>安裝套件到 dependencies
npm i <package> -D安裝套件到 devDependencies
npm i <package> -g全域安裝套件

更新與維護

指令說明
npm update更新所有套件
npm ls列出已安裝的套件
npm prune移除 package.json 中沒有的套件
npm dedupe移除重複的套件
npm doctor檢查 Node.js 與 npm 環境

npm run:自訂腳本

這是日常開發最常用的指令之一。你可以在 package.jsonscripts 裡面定義各種快捷指令:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "preview": "vite preview",
    "lint": "eslint src/",
    "test": "vitest"
  }
}

然後用 npm run <名稱> 來執行:

npm run dev       # 啟動開發伺服器
npm run build     # 打包專案
npm run lint      # 檢查程式碼風格
npm run test      # 跑測試

小提醒:npm startnpm test 比較特殊,它們不需要加 run,直接打就可以。

安全性與檢查

套件裝久了,難免會有安全漏洞。npm 有幾個指令可以幫你檢查:

指令說明
npm audit掃描已安裝套件的已知漏洞
npm audit fix自動修復可以修的漏洞
npm outdated列出有新版本可用的套件

我自己的習慣是每隔一段時間跑一次 npm outdated,看看有沒有什麼該更新的。不需要每個都追到最新,但重大安全性更新要注意。

npx 執行指令

npx 可以執行套件中的指令,不需要全域安裝:

# 執行套件指令
npx create-react-app my-app
 
# 排序 package.json
npx sort-package-json

npm vs pnpm vs yarn

你可能聽過其他套件管理工具。簡單比較一下:

npmpnpmyarn
速度一般最快
磁碟空間每個專案各裝一份共用全域 store,省空間每個專案各裝一份
Lock 檔package-lock.jsonpnpm-lock.yamlyarn.lock
Monorepo 支援npm workspaces原生支援,很強yarn workspaces
學習成本最低(內建)低(指令幾乎一樣)

我自己的想法是:如果是新專案,可以試試 pnpm,速度跟磁碟空間的優勢很明顯。但如果團隊已經在用 npm,也沒什麼特別需要換的理由。

常見疑難排解

開發到一半套件出問題?試試這些方法:

# 清除 npm 快取
npm cache clean --force
 
# 核彈級解法:刪掉 node_modules 重裝
rm -rf node_modules package-lock.json
npm install
 
# Windows 上的寫法
rmdir /s /q node_modules
del package-lock.json
npm install

對吧?大部分 npm 的問題,刪掉 node_modules 重裝就能解決。這也是前端圈的經典名言了。

套件管理工具演進:npm → yarn → pnpm

你有沒有注意到,有些專案用 yarn,有些用 pnpm,到底差在哪?要回答這個問題,得先看看這些工具是怎麼一步步演變出來的。

npm(2010)— 一切的起點

npm 是 Node.js 內建的套件管理工具,也是最早出現的。早期的 npm(v1 到 v3)有一個惡名昭彰的問題叫做 dependency hell — 它會把依賴一層一層嵌套在 node_modules 裡面,目錄結構深到 Windows 路徑長度上限都會爆掉。

npm@3 之後改成了 flat(扁平化)的 node_modules,雖然解決了巢狀問題,但也帶來了新問題:幽靈依賴(phantom dependencies)。你沒有在 package.json 裡宣告的套件,卻因為被攤平到最上層而可以直接 import,哪天上游套件不用它了,你的程式就炸了。

yarn(2016)— Facebook 出手解決痛點

Facebook 在 2016 年推出 yarn,主要解決當時 npm 的幾個痛點:

  • lockfileyarn.lock 確保每台機器裝的版本一模一樣(npm 後來也補上了 package-lock.json
  • 平行下載:安裝速度大幅提升
  • 離線快取:裝過的套件不用再下載

yarn 一推出就大受歡迎,也逼著 npm 加速改進。可以說 yarn 的出現,讓整個套件管理的體驗都往前推了一大步。

pnpm 的核心理念是:同一個套件只需要在磁碟上存一份。

它用了 hard link + content-addressable store 的方式,所有專案共用一個全域 store。假設你有 10 個專案都用 React 18,npm 和 yarn 會各裝 10 份,pnpm 只存一份然後用 hard link 指過去。

除了省空間,pnpm 還解決了幽靈依賴的問題 — 它的 node_modules 結構是嚴格的(strict),你只能存取自己宣告過的依賴。

bun(2022)— 不只是套件管理

bun 不只是套件管理工具,它是一整個 JavaScript runtime(類似 Node.js)。它的安裝速度極快,因為底層用 Zig 語言寫的。不過生態系統還在成熟中,目前比較適合個人嘗鮮,團隊專案還是建議觀望。

功能比較

面向npmyarnpnpm
速度最快
磁碟用量低(hard link)
Lockfilepackage-lock.jsonyarn.lockpnpm-lock.yaml
Monorepoworkspacesworkspacesworkspaces(最成熟)
幽靈依賴問題無(strict node_modules)
指令差異npm installyarnpnpm install

常用指令對照

三個工具的指令其實大同小異,pnpm 基本上跟 npm 一樣,yarn 稍有不同:

操作npmyarnpnpm
安裝所有依賴npm installyarnpnpm install
新增套件npm i <pkg>yarn add <pkg>pnpm add <pkg>
新增 dev 依賴npm i -D <pkg>yarn add -D <pkg>pnpm add -D <pkg>
全域安裝npm i -g <pkg>yarn global add <pkg>pnpm add -g <pkg>
移除套件npm uninstall <pkg>yarn remove <pkg>pnpm remove <pkg>
執行腳本npm run <script>yarn <script>pnpm <script>

怎麼選?

不用想太複雜,根據你的情境選就好:

  • 個人專案 / 新手npm:零設定,Node.js 裝好就有,不用額外安裝任何東西
  • 團隊專案pnpm:省磁碟空間、嚴格依賴避免幽靈依賴踩坑,CI 也跑得更快
  • Monorepopnpm:workspace 支援最成熟,搭配 pnpm-workspace.yaml 設定簡單明瞭

如果你的團隊已經在用某個工具而且沒遇到什麼問題,其實也不用特地換。工具是拿來解決問題的,沒有問題就不需要換。


延伸閱讀