NPM 套件管理員 (Node Package Manager)

NPM (Node Package Manager) 是隨同 Node.js 安裝的預設套件管理員,也是目前全球最大的軟體註冊表 (Registry)。它不僅僅是一個安裝工具,更是現代 JavaScript 開發工作流的核心,負責處理專案依賴、腳本自動化以及套件發布。

NPM 的三大組成部分

理解 NPM 如何運作,首先要了解它的三個重要組成部分:

  1. 網站 (Website)npmjs.com。你可以在這裡搜尋開源套件、管理個人設定檔或查看套件的下載數據。
  2. 註冊表 (Registry):一個龐大的資料庫,存放了數百萬個 JavaScript 代碼包以及相關的元數據。
  3. 命令列工具 (CLI):開發者透過終端機執行 npm 指令來管理本機專案的套件。

基礎指令:安裝、升級與移除

初始化專案:npm init

在開始一個新專案時,首先需要建立 package.json

# 互動式建立,會詢問專案名稱、版本等資訊
npm init

# 快速建立,全部使用預設值 (推薦在練習時使用)
npm init -y

安裝套件:npm install

這是最常用的指令,用於下載並安裝依賴。

# 安裝並加入 dependencies (正式環境運行依賴)
# 例如:npm install express
npm install <package-name>

# 安裝並加入 devDependencies (開發環境專用依賴)
# 例如:npm install jest --save-dev
npm install <package-name> --save-dev (簡寫 -D)

# 安裝 package.json 中列出的所有套件 (通常在接手別人的專案後執行)
npm install (簡寫 i)

升級套件:npm update

當你想更新已安裝的套件到符合 SemVer 規範範圍的最新版本時:

# 更新所有套件
npm update

# 更新特定套件
npm update <package-name>

進階工具:npm-check-updates (ncu)
內建的 npm update 通常只會更新小版本。如果你想將 package.json 中的所有依賴直接升級到「最新且可能包含破壞性更新」的版本,業界常使用 ncu

npx npm-check-updates -u
npm install

移除套件:npm uninstall

當你不再需要某個套件時,務必透過指令移除,它會自動同步更新 package.jsonnode_modules

# 移除套件
npm uninstall <package-name>

核心靈魂:npm run 與腳本生命週期

許多開發者只知道 npm start,但其實 npm run 的運作原理非常強大。

什麼是 npm run?

npm run <script-name> 會去 package.json 裡的 scripts 欄位尋找對應的指令並執行。它最棒的地方是會自動將本地的 node_modules/.bin 加入到環境變數中,這代表你不需要全域安裝工具也能直接呼叫它。

// package.json 範例
"scripts": {
  "dev": "nodemon index.js",
  "build": "webpack",
  "lint": "eslint ."
}

自動執行的生命週期鉤子 (Hooks)

NPM 自動支持 prepost 字首。這能讓各個指令邏輯更清晰地自動連動:

"scripts": {
  "pretest": "npm run lint",      // 跑測試前自動先跑 lint 檢查
  "test": "jest",
  "posttest": "echo '測試完成!'",  // 跑完測試後自動執行
  "prebuild": "rimraf dist"       // 編譯前先清空舊的目錄
}

傳遞參數:--

如果你想透過 npm run 將參數傳遞給底層的工具,必須使用 -- 分隔:

# 假設 "test" 指令是 "jest"
# 下方指令等同於執行:jest --watchAll
npm run test -- --watchAll

檢查與除錯工具

檢視安裝樹:npm list (ls)

當代碼行為怪異,你想確認到底是哪個版本被安裝了,或是依賴關係如何疊加時:

# 顯示當前專案的所有層級依賴
npm list

# 只顯示第一層 (最常用的方式)
npm list --depth=0

查閱遠端資訊:npm view (info)

如果你想在不安裝的情況下,確認某個套件的最新版本、依賴項或是歷史版本:

# 查看 express 的基本資訊
npm view express

# 列出所有發布過的版本號
npm view express versions

解答「為什麼這在這裡」:npm explain (why)

這是除錯時的殺手鐧。當你發現一個不明套件出現在 node_modules 時,問問 NPM:

npm explain <package-name>

穩定生產環境:npm ci (Clean Install)

這是在業界開發時「最重要」的區別之一。

  • npm install:用於開發期。它可能會根據版本規範自動更新 lock 檔。
  • npm ci:用於部署期 (CI/CD/Production)
    • 它會直接刪除 node_modules 並嚴格按照 package-lock.json 重新安裝。
    • 如果 package-lock.jsonpackage.json 內容不一致,它會直接報錯中斷安裝。
    • 這能確保正式環境與你的電腦環境 100% 相同

進階開發與安全性

如果你正在開發一個套件 A,並想在另一個本地專案 B 中即時測試它,而不想反覆發布到 NPM 官網:

  1. 在套件 A 目錄執行:npm link (建立全域捷徑)。
  2. 在專案 B 目錄執行:npm link <套件A名稱> (建立本地連結)。 這樣任何對 A 的修改都會立即反映在 B 中。

安全性審核:npm audit

NPM 會自動比對你的依賴套件與已知的安全性漏洞資料庫。

# 檢查報告
npm audit

# 自動嘗試修復 (會更新 package.json)
npm audit fix

快取與效能優化

有時候安裝出現奇怪的報錯,或是你想清除佔用空間的暫存檔:

  • npm cache verify:檢查並清理損壞的快取內容。
  • npm cache clean --force:強行清空。注意這會導致下次安裝變慢,因為所有檔案需重新從網路下載。

總結:最佳實踐清單

  1. 區分依賴:務必將工具類放進 devDependencies
  2. 善用腳本:透過 npm run 封裝複雜指令,保持開發環境整潔。
  3. 鎖定版本:永遠將 package-lock.json 加入 Git,並在伺服器上使用 npm ci
  4. 定期審計:養成習慣定期跑 npm audit 檢查專案安全性。

掌握了這些指令與概念,你就不再只是在「下指令」,而是在專業地「管理」你的代碼生態系。