---
# System prepended metadata

title: 'JavaScript Runtime: Node.js'
tags: [JavaScript, nodejs, npx, npm, frontend, nvm, backend, runtime, JS]

---

JavaScript Runtime: Node.js
===
###### tags: `JavaScript`
###### tags: `JavaScript`, `JS`, `frontend`, `backend`, `runtime`, `nodejs`, `npm`, `nvm`, `npx`

<br>

[TOC]

<br>

## JavaScript vs Node.js vs nvm
### 摘要
- **JavaScript**
    - 程式語言本體。
- **Node.js**
    - 執行 JavaScript 的「執行時環境（runtime）」，常見於後端與各種工具鏈（不是程式語言）。
    - Node.js 不只用在後端，也常用來跑 CLI、建置工具、甚至桌面應用（Electron）。
- **nvm (Node Version Manager)**
    - Node.js 的版本管理工具（開發工具，不屬於前端/後端/語言）。
- **npm (Node Project Manager)**
    - Node.js 的預設套件管理器（通常隨 Node 安裝）。
- **npx (Node Package eXecute)**
    - 不用先安裝，就能直接執行 npm 套件的工具。

<br>

### Node.js
**Node.js 是「JavaScript 的執行時環境（runtime）」**，不是 IDE 那種「開發環境」。
- **作用**：讓 JS 離開瀏覽器、直接在作業系統上執行。
- **用途**：常拿來做**後端服務**、**指令列工具**、以及**前端建置工具鏈**。
- **內建**：`npm`（套件管理器）與核心模組（如 `fs`、`http`、`path`）。

<br>

### npm

**npm 是「Node.js 的預設套件管理器」**（不是語言也不是執行環境），提供套件生態與工具。 ([Node.js][1])

- **作用**：管理專案相依、版本解析與安裝位置；預設連線到公開 Registry（`https://registry.npmjs.org`）。 ([Node.js][1])
- **用途**：安裝/更新/移除套件（`npm install`）、管理 `package.json` 與腳本（`npm run`）、發佈套件（`npm publish`）。 ([npm Docs][2])
- **組成**：三件組 —— **網站**（npmjs.com）、**CLI**（`npm`）、**Registry**（套件登錄）。 ([npm Docs][3])
- **關聯**
    - 和 **Node.js**：npm 是 Node.js 的標準套件管理器，通常隨 Node 一起提供。 ([Node.js][1])
    - 和 **npx**：`npx` 是「執行器」；現行 `npx` 其實走的是 `npm exec`，用來**直接執行**套件提供的指令（即使未全域安裝）。 ([npm Docs][4])
    - 和 **nvm**：nvm 切換的是 **Node** 版本；由於 **npm 隨 Node 分發**，因此**切換 Node 也等同切換對應的 npm 版本**（此為根據官方分發方式的合理推論）。 ([Node.js][5])

要不要我把這段直接插回你那份〈JavaScript vs Node.js vs nvm〉成一張完整小抄？

[1]: https://nodejs.org/en/learn/getting-started/an-introduction-to-the-npm-package-manager?utm_source=chatgpt.com "Node.js - An introduction to the npm package manager"
[2]: https://docs.npmjs.com/cli-documentation/?utm_source=chatgpt.com "npm CLI"
[3]: https://docs.npmjs.com/about-npm/?utm_source=chatgpt.com "About npm"
[4]: https://docs.npmjs.com/cli/v8/commands/npx/?utm_source=chatgpt.com "npx"
[5]: https://nodejs.org/api/corepack.html?utm_source=chatgpt.com "nodejs/corepack: Zero-runtime-dependency package ..."

<br>

---

<br>

## 討論
### 如何在 Ubuntu 上安裝 node 指令 (Node.js ≥ 20) ？
- ### gpt-5 (2025/09/25)

    下面給你兩種最好用的做法：系統層級（適合伺服器與多使用者）與使用者層級（不用 sudo、最彈性）。兩種都能裝到 Node.js ≥ 20。

    ---

    ### 方法 A：用 NodeSource（系統層級，全機可用）

    > 建議裝「LTS 版」；目前 LTS 為 22（也可改成 20）。([NodeSource][1])

    ```bash
    # 1) 先準備基本工具
    sudo apt-get update
    sudo apt-get install -y ca-certificates curl gnupg

    # 2) 啟用 Node.js 22.x LTS 的套件庫（要 20.x 就把 22.x 改成 20.x）
    curl -fsSL https://deb.nodesource.com/setup_22.x | sudo -E bash -

    # 3) 安裝
    sudo apt-get install -y nodejs

    # 4) 驗證
    node -v
    npm -v
    npx -v
    ```
    - 備註：2025/09/25
        - `node -v` -> `v22.20.0`
        - `npm -v` -> `10.9.3`
        - `npx -v` -> `10.9.3`
    - 備註：2026/02/02
        - `node -v` -> `v22.22.0`
        - `npm -v` -> `10.9.4`
        - `npx -v` -> `10.9.4`


    > NodeSource 首頁提供一鍵腳本（`setup_22.x`），並說明如何在 Ubuntu 安裝；選不同版本會產生相對應指令。([NodeSource][1])

    ---

    ### 方法 B：用 nvm（使用者層級，最彈性）

    > 不動系統套件、可在同一台切換多版本（推薦日常開發）。([GitHub][2])

    ```bash
    # 1) 安裝 nvm
    curl -o- https://raw.githubusercontent.com/nvm-sh/nvm/v0.40.3/install.sh | bash

    # 2) 讓當前 shell 載入 nvm（或重開終端機）
    export NVM_DIR="$HOME/.nvm"
    [ -s "$NVM_DIR/nvm.sh" ] && . "$NVM_DIR/nvm.sh"

    # 3) 安裝 LTS（目前會抓 22）或指定 20
    nvm install --lts    # 取得最新 LTS
    # 或
    nvm install 20       # 明確安裝 20.x

    # 4) 設為預設並使用
    nvm alias default --lts
    nvm use --lts

    # 5) 驗證
    node -v
    npm -v
    npx -v
    ```

    > nvm 官方文件提供安裝腳本與「安裝/切換版本」指令。([GitHub][2])

    ---

    ### （可選）啟用 Corepack 以使用 Yarn / pnpm

    Node 16.9+ 內建 Corepack，可直接管理 Yarn、pnpm 版本：

    ```bash
    corepack enable
    corepack prepare yarn@stable --activate
    corepack use pnpm@latest
    ```

    > Corepack 由 Node.js 提供，用來管理套件管理器版本（Yarn、pnpm）。([Node.js][3])

    ---

    ### 小提醒 / 常見狀況

    * `node -v` 顯示版本過舊：你可能用到 Ubuntu 內建套件庫（版本常落後）。改用上面的 **NodeSource** 或 **nvm**。([DigitalOcean][4])
    * 裝好 nvm 卻出現 `nvm: command not found`：重開終端機，或執行 `source ~/.bashrc`（或 `~/.zshrc`）。([GitHub][2])
    * 想編譯原生模組（如 node-gyp）：可再裝編譯工具 `sudo apt-get install -y build-essential python3`.

    以上兩種方法擇一即可；要「一次搞定、全系統可用」就用 **方法 A**，要「版本切換彈性」就用 **方法 B**。

    [1]: https://deb.nodesource.com/ "Nodesource Node.js DEB"
    [2]: https://github.com/nvm-sh/nvm "GitHub - nvm-sh/nvm: Node Version Manager - POSIX-compliant bash script to manage multiple active node.js versions"
    [3]: https://nodejs.org/download/release/v18.17.0/docs/api/corepack.html?utm_source=chatgpt.com "Corepack | Node.js v18.17.0 Documentation"
    [4]: https://www.digitalocean.com/community/tutorials/how-to-install-node-js-on-ubuntu-22-04?utm_source=chatgpt.com "How to Install Node.js on Ubuntu (Step-by-Step Guide)"

<br>

---

### [接續] 什麼是 系統層級？使用者層級？
- ### gpt-5 (2025/09/25)
    好問題！這裡的「層級」其實是在說**安裝範圍**與**生效對象**：

    ### 兩種安裝「層級」

    #### 1) 系統層級（system-wide）

    * **裝到哪**：系統目錄（通常是 `/usr/bin`, `/usr/lib`）
    * **需要 sudo？**：需要（`sudo apt install ...`）
    * **誰能用？**：這台機器上的**所有使用者**都能用
    * **版本管理**：整台機器通常只有**一個版本**，用 apt 升降級
    * **典型用途**：伺服器、CI、要跑 systemd 服務給大家用
    * **辨識方式**：
      `command -v node` → 路徑多半像 `/usr/bin/node`

    #### 2) 使用者層級（per-user）

    * **裝到哪**：使用者家目錄（例如 `~/.nvm/versions/node/...`）
    * **需要 sudo？**：**不需要**（像 nvm 這種工具）
    * **誰能用？**：**只有當前帳號**有效（其他帳號看不到）
    * **版本管理**：同一台可切換**多個版本**（`nvm install 20`, `nvm use 22`）
    * **典型用途**：個人開發、同時維護多專案多版本
    * **辨識方式**：
      `command -v node` → 路徑多半在 `~/.nvm/.../bin/node`

    ---

    ### 我該選哪一種？

    * **我要在伺服器上跑服務、給多人共用，同一版就好** → 用**系統層級**（apt + NodeSource 套件庫）。
    * **我是開發者，常要切換 Node 20/22/next** → 用**使用者層級**（nvm），不影響別人與系統。

    ---

    ### 快速自我檢查（你現在是哪一種）

    ```bash
    command -v node     # 看 node 實際路徑
    node -v             # 看版本
    echo $PATH          # 看搜尋路徑順序
    ```

    * 出現 `/usr/bin/node` → 系統層級
    * 出現 `~/.nvm/versions/node/vXX/bin/node` → 使用者層級
    * 進一步確認是否 apt 管：
      ```bash
      dpkg -S "$(command -v node)"  # 若有輸出套件名，多半是系統層級
      ```

    ---

    ### 小提醒

    * **不要混裝**：同時有 apt 版 + nvm 版，容易搞不清誰在生效（看 `$PATH` 決定）。
    * **systemd 服務**通常看不到你的 shell 設定（不會自動載入 nvm），要嘛：

      1. 用**系統層級** Node；或
      2. 在 service 裡寫死完整路徑（例如 `ExecStart=/home/xxx/.nvm/.../node app.js`）。

    如果你願意，我可以依你的情境（單人開發機/多人伺服器/要跑服務）幫你挑一種並給出一組一步到位的指令。

<br>

---

### npx 用途
- ### gpt-5 (2025/09/25)
    * **用途**：**直接執行 npm 套件的可執行檔（bin）而不需先全域安裝**。會**優先使用專案本地**的 `node_modules/.bin`，若沒有，再**暫時下載到快取**後執行，不會改動你的 `package.json`。
    * **與 npm 的關係**：在 **npm 7+** 之後，`npx` 本質上等同 **`npm exec`** 的指令介面：
      * `npx <指令>` ≈ `npm exec -- <指令>`
      
    * **何時用它**：

      * 一次性工具或腳手架：`npx create-vite@latest myapp`
      * 執行已在專案安裝的 CLI：`npx eslint .`（會用專案版本，避免全域版本不一致）
      * 試跑某個 CLI 而不汙染全域：`npx cowsay "hello"`

    * **與 `npm install -g` 的差異**：

      * `npm i -g foo`：把 `foo` 裝到全域，之後到處可用，但容易版本漂移。
      * `npx foo`：不需全域安裝，臨時取用；**專案內執行會鎖定本地版本**，更可重現。

    * **常用參數**：

      * `--yes` / `-y`：自動同意提示（例如腳手架問題）。
      * `--package <name>`：指定要暫裝的套件並執行其 bin，例如：
        ```bash
        npx --package typescript tsc --init
        ```
      * `--no-install`：**只用現有**（本地/全域）可執行檔，找不到就失敗，不會下載。
      * `--`：分隔參數，將其後參數傳給目標指令：
        ```bash
        npx eslint -- --fix
        ```

    * **安全與版本建議**：

      * 儘量加上 **版本或 tag**（如 `@latest`），並留意拼字（避免 typo-squatting）。
      * **經常使用的工具**建議加到 `devDependencies` 並用 npm script 執行，以固定版本、利於 CI：
        ```json
        {
          "scripts": { "lint": "eslint ." }
        }
        ```
        之後用 `npm run lint`（或 `pnpm/yarn` 對應指令）即可。


<br>

{%hackmd vaaMgNRPS4KGJDSFG0ZE0w %}