Node.js package.json:專案的核心大腦與配置百科

在任何一個 Node.js 專案中,package.json 不僅僅是一個清單,它更像是專案的「大腦」,定義了專案的身分、依賴控制、自動化指令、甚至是各類開發工具的配置中心。本文將帶你從基礎入門到進階實戰,全面掌握這個核心檔案。

專案身分與搜尋優化 (Metadata)

當你打算發布套件或供他人協作時,這些欄位至關重要:

  • name:專案名稱。必須全小寫,建議使用連字號 -
  • version語意化版本 (SemVer)
  • description & keywords:讓別人在 NPM 官網更容易搜尋到你的專案。
  • repository:原始碼存放位址(如 GitHub 連結)。
  • bugs & homepage:提供專案回報問題與官網連結。
  • author & license:定義專案擁有者與授權條款(常見如 MIT, Apache-2.0)。

模組系統與匯出規範 (The Module System)

隨著現代 JavaScript 的演進,如何定義專案的匯出方式變得越來越精細。

type:模組類型切換

  • "commonjs" (預設):使用 require()
  • "module":強制專案內所有的 .js 檔案皆以 ES Modules (import/export) 運行的開關。

現代匯出規範:exports

傳統上我們使用 main 來指定入口,但 exports 提供了更強大的子路徑對應與環境適應性:

"exports": {
  ".": {
    "types": "./dist/index.d.ts",     // TypeScript 型別定義
    "import": "./dist/index.mjs",    // 用於 ESM 環境
    "require": "./dist/index.cjs"    // 用於 CJS 環境
  },
  "./utils": "./dist/utils.js"       // 對外公開子路徑
}

內部分身代名詞:imports

如果你厭倦了在代碼中寫 ../../../../utils/helper.js,可以使用 imports 定義內部路徑別名(必須以 # 開頭):

"imports": {
  "#utils/*": "./src/utils/*.js"
}

依賴治理:從運行到發布 (Dependency Governance)

正確分配依賴分類,能讓你的專案在生產環境中更輕量、更安全。

基礎分類

  • dependencies:線上環境必須運行的套件(如 express)。
  • devDependencies:僅在本地開發或 CI/CD 建置時需要的工具(如 jest, eslint)。

專業級分類

  • peerDependencies:當你開發的是外掛或 UI 元件庫(如 mui)時,要求使用者必須先手動安裝 react
  • optionalDependencies:即使安裝失敗也不會導致建置失敗的依賴。
  • bundleDependencies:在發布時連同 node_modules 內容一起打包進 .tgz 的特殊依賴。

安全救星:overrides

當你的依賴項 A 使用了過時的依賴項 B,而 B 存在安全性漏洞時,你可以強制覆蓋所有依賴樹中的 B 版本:

"overrides": {
  "fast-xml-parser": "4.2.4"
}

自動化大師:Scripts 深度技巧

scripts 不只能跑指令,它還擁有處理複雜流程的能力。

指令傳參

在執行 npm run 時,可以使用 -- 來傳遞額外參數給底層工具:

# 原理:npm run build -- --profile
"scripts": {
  "build": "next build"
}

命令鉤子 (Hooks)

NPM 自動支持 prepost 字首的連動觸發。例如執行 npm run deploy 前,會自動先跑 predeploy

"scripts": {
  "predeploy": "npm run build && npm test",
  "deploy": "gh-pages -d dist",
  "postdeploy": "echo '已完成部署!'"
}

開發工具的集散地 (Tool Configurations)

許多開發工具為了簡化檔案數量,都支持直接在 package.json 中進行設定。

程式碼與環境規範

  • engines:限制專案運行所需的 nodepnpm 版本範圍。
  • browserlist:告訴 Autoprefixer 或 Babel 你的程式碼需要支持哪些瀏覽器版本。
  • sideEffects:對 Webpack 指明專案哪些檔案有副作用,能極大地幫助 Tree-shaking 減少打包體積。

工具直接配置範例

{
  "eslintConfig": {
    "extends": "react-app"
  },
  "prettier": {
    "singleQuote": true
  },
  "jest": {
    "coverageThreshold": {
      "global": { "branches": 80 }
    }
  }
}

發布與發行控制 (Distribution Logic)

如果你是一個開源作者,請務必關注以下設定:

  • private: true:這是一道保險。設為 true 後,即使誤打 npm publish 也會被拒絕。
  • files:這是一個「白名單」。當你發布套件時,只會包含這裡列出的資料夾(例如 dist),這能顯著降低安裝體積。
  • bin:如果你開發的是 CLI 工具(如 create-next-app),這裡定義了終端機指令與執行檔案的對應。

高階架構與社群互動

單一儲存庫:workspaces

如果您在一個 Git 倉庫中同時開發管理多個 NPM 套件,workspaces 能幫你自動連結本地套件並統一依賴管理:

"workspaces": [
  "packages/*"
]

社群支持:funding

讓想支持你的開源專案的研究者或企業知道捐款管道:

"funding": {
  "type": "opencollective",
  "url": "https://opencollective.com/your-project"
}

總結:package-lock.json 的守護

最後,絕對不要忽略 package-lock.json。它是 package.json 的實例化快照,記錄了此時此刻你所安裝的「所有」依賴的精確版本。

  • 不要手動修改它,並務必將它加入 Git 追蹤。
  • 使用 npm ci:在正式環境部署時,永遠使用 npm ci 而非 npm install,以確保 100% 複刻開發環境。

掌握 package.json 的每一個欄位,代表你不再只是在使用工具,而是在設計與管理整個專案的基礎架構。