NVM 是什麼?NVM vs NPM vs Node.js 差異完整解析
許多剛接觸前後端開發的工程師,第一次看到 NVM、NPM、Node.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.js | NPM | NVM |
|---|---|---|---|
| 是什麼 | JavaScript 執行環境(Runtime) | 套件管理工具 | Node.js 版本管理工具 |
| 主要用途 | 在伺服器端執行 JavaScript 程式碼 | 安裝、管理、發布第三方套件 | 在同一台機器上安裝並切換不同版本的 Node.js |
| 安裝方式 | 直接從官網下載或透過 NVM 安裝 | 隨 Node.js 自動安裝,不需單獨安裝 | 透過 curl 指令或 Homebrew 安裝 |
| 主要指令 | node、node -v | npm install、npm run | nvm install、nvm 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 的速度慢和不確定性問題。主要差異如下:
| 面向 | NPM | Yarn |
|---|---|---|
| 安裝速度 | 較慢(NPM v7+ 後已改善) | 較快(並行安裝) |
| 鎖定檔 | package-lock.json | yarn.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 typescript讓tsc指令可在全域使用。
# 局部安裝(加入 package.json)
npm install express
# 全域安裝(不加入 package.json)
npm install -g nodemon
# 查看全域安裝了哪些套件
npm list -g --depth=0
如果你的應用需要定期向伺服器同步資料,可以搭配 Polling 輪詢技術 來實作。若要處理請求失敗的情況,可以參考 Backoff 退避策略 來實作更穩健的重試機制。