NVM 是什麼?NVM vs NPM vs Node.js 差異完整解析

2024/01/01

許多剛接觸前後端開發的工程師,第一次看到 NVMNPMNode.js 這三個名詞時,往往一頭霧水,分不清楚它們各自的用途與關係。本文用白話文幫你一次搞懂這三者的差異,並提供完整的安裝與使用指南。

Node.js 是什麼?

Node.js 是一個基於 Google Chrome V8 JavaScript 引擎的開源執行環境(Runtime Environment),讓 JavaScript 不只能在瀏覽器中執行,還能在伺服器端(Server-side)運行。

V8 Engine 是什麼?

V8 是 Google 開發的 JavaScript 引擎,最初設計用來提升 Chrome 瀏覽器中 JavaScript 的執行速度。它的核心技術是 JIT(Just-In-Time)編譯,在執行時將 JavaScript 直接編譯成機器碼,而不是逐行解譯,因此效能極高。Node.js 將 V8 引擎帶出了瀏覽器,讓它可以在任何作業系統上直接執行 JavaScript 程式碼。

為什麼後端需要 Node.js?

在 Node.js 出現之前,後端開發主要依賴 PHP、Java、Python、Ruby 等語言,前端工程師若想涉足後端,就必須學習另一套語言。Node.js 的出現讓前端工程師可以用同一種語言(JavaScript)同時開發前後端,大幅降低了全端開發的門檻。

Node.js 的另一個重要特性是**非同步 I/O(Asynchronous I/O)事件驅動(Event-driven)**架構。傳統的多執行緒伺服器在等待資料庫查詢或檔案讀取時,會阻塞執行緒(blocking)。Node.js 採用單執行緒的事件迴圈(Event Loop),在等待 I/O 的同時可以繼續處理其他請求,非常適合高併發(high-concurrency)的應用場景。

LTS vs Current 版本策略

Node.js 有兩個主要的發布頻道:

頻道說明建議對象
LTS(Long Term Support)長期支援版本,穩定、Bug 修復週期長(18 個月 Active + 12 個月 Maintenance)生產環境、企業專案
Current最新功能版本,每 6 個月一次大版本,穩定性相對較低開發測試、嘗鮮新功能

偶數版本號(如 18, 20, 22)會成為 LTS 版本,奇數版本號(如 19, 21)只在 Current 頻道短期維護。正式專案建議一律使用 LTS 版本。

Node.js 的常見應用場景

  • API 伺服器:搭配 Express.js 或 Fastify 建立 RESTful API 或 GraphQL API。
  • CLI 工具:許多知名的命令列工具(如 ESLint、Webpack、Vite)都是以 Node.js 開發。
  • SSR(Server-Side Rendering):Next.js、Nuxt.js 等框架在伺服器端執行 JavaScript 來渲染頁面,提升 SEO 效果。
  • 即時應用:結合 WebSocket 實作聊天室、通知系統等需要即時更新的應用。
  • 微服務架構:Node.js 輕量的特性非常適合微服務的容器化部署。
# 查看當前 Node.js 版本
node -v

# 直接執行 JavaScript 程式碼(REPL 模式)
node

# 執行 .js 檔案
node index.js

# 查看 Node.js 內建模組
node -e "console.log(require('module').builtinModules)"

NPM 是什麼?

NPM(Node Package Manager) 是 Node.js 的預設套件管理工具(Package Manager),在安裝 Node.js 時會自動一起安裝。NPM 的核心功能是讓開發者可以輕鬆地安裝、分享與管理第三方套件(Package)。

NPM 的套件庫(Registry)是全球最大的開源軟體倉庫,截至 2024 年已擁有超過 200 萬個套件,從工具函式庫(如 lodash)到完整的框架(如 express)都能找到。

npm 常用指令一覽

指令說明
npm init在當前目錄初始化一個新的 Node.js 專案,產生 package.json
npm init -y使用預設值快速初始化,跳過問答流程
npm install安裝 package.json 中所有的相依套件
npm install <套件名>安裝指定套件並加入 dependencies
npm install <套件名> --save-dev安裝指定套件並加入 devDependencies
npm install -g <套件名>全域安裝套件
npm uninstall <套件名>移除套件
npm update更新所有套件至允許的最新版本
npm run <腳本名>執行 package.json 中定義的腳本
npm list列出已安裝的所有套件
npm outdated列出有新版本可用的套件

package.json 與 package-lock.json

package.json 是 Node.js 專案的核心設定檔,記錄了專案名稱、版本、描述、腳本(scripts)以及所有相依套件的版本範圍。

package-lock.json 是 NPM 自動產生的鎖定檔,精確記錄了每個套件(包含間接相依)安裝時的確切版本號,確保在不同機器或 CI/CD 環境中可以重現完全一致的套件樹。

{
  "name": "my-project",
  "version": "1.0.0",
  "scripts": {
    "start": "node index.js",
    "dev": "nodemon index.js",
    "build": "webpack --mode production",
    "test": "jest"
  },
  "dependencies": {
    "express": "^4.18.2"
  },
  "devDependencies": {
    "nodemon": "^3.0.1",
    "jest": "^29.7.0"
  }
}

dependencies vs devDependencies

  • dependencies:應用程式在生產環境(production)執行時必需的套件,例如 express、react、axios。
  • devDependencies:只在開發階段使用的套件,不會包含在生產環境的部署中,例如測試框架(jest)、打包工具(webpack)、程式碼格式化工具(prettier)。

在部署伺服器時,可以執行 npm install --production,這樣只會安裝 dependencies 中的套件,節省空間與時間。

語義化版本控制(Semantic Versioning)

NPM 套件版本遵循 SemVer(Semantic Versioning) 規範,格式為 主版本.次版本.修補版本(MAJOR.MINOR.PATCH):

  • MAJOR:不相容的 API 破壞性變更
  • MINOR:新增向後相容的功能
  • PATCH:向後相容的 Bug 修復

package.json 中,版本號前面的符號有不同含義:

符號範例說明
^(插入符號)^4.18.2允許安裝 4.x.x 的最新版,但不跨主版本
~(波浪符號)~4.18.2允許安裝 4.18.x 的最新修補版,但不跨次版本
*(星號)*安裝最新版本(不建議在生產環境使用)
無符號4.18.2精確鎖定特定版本

NVM 是什麼?

NVM(Node Version Manager) 是一個用來管理多個 Node.js 版本的工具。它讓你可以在同一台機器上同時安裝多個不同版本的 Node.js,並隨時切換使用。

為什麼需要管理多個 Node.js 版本?

實際開發中,你可能同時維護多個專案:

  • 專案 A 使用 Node.js 16(因為某個舊套件不支援更新版本)
  • 專案 B 使用 Node.js 18 LTS
  • 專案 C 想測試最新的 Node.js 22 的新功能

如果沒有版本管理工具,在同一台機器上切換 Node.js 版本會非常麻煩,甚至需要完整解除安裝再重新安裝。NVM 讓版本切換變得非常簡單——只需要一行指令。

NVM 的工作原理

NVM 的核心概念是:它不依賴系統層級的安裝,而是將所有 Node.js 版本安裝在使用者的家目錄下(預設為 ~/.nvm)。每個版本的 Node.js 及其對應的 npm 都被獨立存放,互不干擾。

NVM 透過修改 Shell 的 PATH 環境變數來切換版本,讓當前 Shell 指向你指定版本的 Node.js 執行檔。

NVM 基本操作

# 查看 NVM 版本
nvm --version

# 列出所有可安裝的 Node.js 版本
nvm ls-remote

# 只列出 LTS 版本
nvm ls-remote --lts

# 安裝最新的 LTS 版本
nvm install --lts

# 安裝指定版本
nvm install 20.10.0

# 列出已安裝的 Node.js 版本
nvm ls

# 切換到指定版本
nvm use 20

# 切換到最新 LTS 版本
nvm use --lts

# 設定預設版本(開新 Shell 時自動使用)
nvm alias default 20

# 查看當前使用的版本
nvm current

# 解除安裝特定版本
nvm uninstall 16

.nvmrc 檔案

.nvmrc 是一個放在專案根目錄的文字檔案,裡面只記錄這個專案所使用的 Node.js 版本號。當團隊成員 clone 這個專案後,只需在專案目錄下執行 nvm use,NVM 就會自動讀取 .nvmrc 並切換到對應版本,確保所有人使用一致的環境。

# .nvmrc 的內容(只需要一行版本號)
20.10.0

# 或者使用別名
lts/iron
# 在專案目錄下執行,自動讀取 .nvmrc
nvm use

# 也可以搭配自動切換(需要在 .zshrc 或 .bashrc 中額外設定)

NVM vs NPM vs Node.js 差異比較

面向Node.jsNPMNVM
是什麼JavaScript 執行環境(Runtime)套件管理工具Node.js 版本管理工具
主要用途在伺服器端執行 JavaScript 程式碼安裝、管理、發布第三方套件在同一台機器上安裝並切換不同版本的 Node.js
安裝方式直接從官網下載或透過 NVM 安裝隨 Node.js 自動安裝,不需單獨安裝透過 curl 指令或 Homebrew 安裝
主要指令nodenode -vnpm installnpm runnvm installnvm use
設定檔無(由環境變數設定)package.json.npmrc.nvmrc
安裝位置/usr/local/bin/node~/.nvm/versions/隨 Node.js 安裝,全域套件在 npm root 目錄~/.nvm/

簡單來說:

  • Node.js 是引擎(讓 JS 能跑)
  • NPM 是加油站(提供各種套件)
  • NVM 是車庫(管理多個版本的引擎)

安裝流程(推薦順序)

推薦的安裝順序是:先裝 NVM → 用 NVM 裝 Node.js → NPM 隨 Node.js 一起安裝

不建議直接從 Node.js 官網下載安裝,因為那樣安裝的版本之後難以切換,且可能造成權限問題。

第一步:安裝 NVM

macOS / Linux:

# 使用官方 curl 指令安裝(版本號請至 NVM GitHub 查詢最新版)
curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.39.7/install.sh | bash

# 安裝完後,重新載入 Shell 設定
source ~/.bashrc   # 如果使用 Bash
source ~/.zshrc    # 如果使用 Zsh(macOS 預設)

# 驗證安裝成功
nvm --version

安裝腳本會自動在你的 .bashrc.zshrc 中加入 NVM 的初始化設定。

詳細的 Linux/Mac 安裝步驟請參考:Linux/Mac 安裝 NVM

Windows:

Windows 需要使用獨立的工具 nvm-windows,它是一個獨立的專案,操作指令類似但有些差異。

詳細的 Windows 安裝步驟請參考:Windows 安裝 NVM

第二步:使用 NVM 安裝 Node.js

# 安裝最新的 LTS 版本(推薦)
nvm install --lts

# 安裝特定版本
nvm install 20

# 設為預設版本
nvm alias default 20

# 驗證安裝
node -v
npm -v

第三步:NPM 隨 Node.js 自動安裝

安裝完 Node.js 之後,NPM 就已經自動安裝好了,無需額外操作。可以用以下指令確認:

# 確認 npm 版本
npm -v

# 更新 npm 到最新版(選用)
npm install -g npm@latest

完整的 NVM 常用指令可以參考:NVM 常用指令一覽表


NVM 替代方案:FNM

雖然 NVM 是最廣泛使用的 Node.js 版本管理工具,但它有一個明顯的缺點:啟動速度較慢,因為它是用 Shell Script 撰寫的,每次開啟新的 Shell 視窗都需要執行初始化腳本。

FNM(Fast Node Manager) 是一個用 Rust 語言開發的替代方案,具有以下優勢:

  • 速度快約 40 倍:因為是編譯後的原生二進位執行檔,不像 NVM 是 Shell Script。
  • 跨平台:原生支援 macOS、Linux 和 Windows。
  • 相容 .nvmrc:可以直接讀取 .nvmrc 檔案,不需要修改專案設定。
  • 自動切換:可以設定在進入目錄時自動切換版本。
# 安裝 FNM(macOS 使用 Homebrew)
brew install fnm

# 常用指令(與 NVM 高度相似)
fnm install --lts      # 安裝最新 LTS
fnm install 20         # 安裝指定版本
fnm use 20             # 切換版本
fnm list               # 列出已安裝版本
fnm default 20         # 設定預設版本

FNM 的詳細使用方式請參考:FNM 使用教學


常見問題(FAQ)

Q1:NPM 和 Yarn 有什麼差別?應該用哪個?

Yarn 是 Facebook 開發的套件管理工具,用來解決早期 NPM 的速度慢和不確定性問題。主要差異如下:

面向NPMYarn
安裝速度較慢(NPM v7+ 後已改善)較快(並行安裝)
鎖定檔package-lock.jsonyarn.lock
工作區支援npm workspaces(v7+)yarn workspaces
Plug’n’Play不支援Yarn Berry 支援
普及度最廣泛使用特別在 React 生態圈常見

現代的 NPM(v7/v8/v9)已經大幅改善了速度和確定性,對於新專案兩者皆可選擇。如果是加入現有專案,通常依照專案本身的設定(看 lockfile 是哪種)來決定。

Q2:.nvmrc 檔案的用途是什麼?怎麼用?

.nvmrc 的用途是讓所有團隊成員和 CI/CD 環境都使用相同版本的 Node.js,避免「在我的電腦上可以跑」的問題。

使用方法:

# 1. 在專案根目錄建立 .nvmrc,寫入版本號
echo "20.10.0" > .nvmrc

# 2. 加入版本控制(git add .nvmrc)

# 3. 其他成員 clone 後,在專案目錄執行:
nvm use
# NVM 就會自動讀取 .nvmrc 並切換到 20.10.0

Q3:npm install 的全域安裝和局部安裝有什麼差別?

  • 局部安裝(預設):套件安裝在當前專案的 node_modules 目錄下,只有這個專案可以使用。適合絕大多數套件。
  • 全域安裝(加上 -g 旗標):套件安裝在系統的全域目錄,可以在任何地方作為命令列工具使用。適合 CLI 工具,如 npm install -g typescripttsc 指令可在全域使用。
# 局部安裝(加入 package.json)
npm install express

# 全域安裝(不加入 package.json)
npm install -g nodemon

# 查看全域安裝了哪些套件
npm list -g --depth=0

如果你的應用需要定期向伺服器同步資料,可以搭配 Polling 輪詢技術 來實作。若要處理請求失敗的情況,可以參考 Backoff 退避策略 來實作更穩健的重試機制。