不用看 README!從 package.json 快速掌握一個專案的完整指南
更新日期: 2025 年 3 月 23 日
本文為 Node.js 基礎,第 8 篇:
當你第一次接觸一個 JavaScript 或 Node.js 專案時,最常見的兩個檔案之一就是 package.json
和 package-lock.json
。
許多人第一時間會去找 README.md
看看這個專案是幹嘛的,但有些專案可能沒有寫 README,或內容不夠清楚。
這時,理解 package.json
就變得超級重要。
什麼是 package.json
?
簡單來說,package.json
是每個 Node.js 專案的核心設定檔,可以把它想像成這個專案的「身份證」或「說明書」。
它不只是 npm 安裝套件時會參考的文件,更是一個讓開發者快速了解專案架構、功能模組、執行方式的重要參考點。
以下是 package.json
所扮演的幾個關鍵角色:
- 描述專案的基本資訊:如名稱、版本、簡介等,讓你知道這是什麼專案。
- 列出專案依賴的套件(libraries):分為正式運行需要的(
dependencies
)和開發過程中用的(devDependencies
)。 - 定義可以執行的指令(scripts):像是啟動伺服器、測試、編譯等等,這些指令可以用
npm run
一鍵執行。 - 指定程式進入點:告訴 Node.js 或其他工具,當載入這個專案時要從哪裡開始執行。
- 作為發佈與版本控制的依據:如果你要把這個專案上傳到 npm registry 或跟其他人協作,
package.json
是不可或缺的。
graph LR PKG[package.json] --> BASIC[基本資訊] PKG --> DEPS[依賴管理] PKG --> FILE[檔案相關] PKG --> BUILD[建置配置] PKG --> PUB[發布設定] BASIC --> BASIC1[name: 套件名稱] BASIC --> BASIC2[version: 版本號] BASIC --> BASIC3[description: 描述] BASIC --> BASIC4[author: 作者] DEPS --> DEPS1[dependencies: 生產依賴] DEPS --> DEPS2[devDependencies: 開發依賴] DEPS --> DEPS3[peerDependencies: 對等依賴] FILE --> FILE1[main: 主程式入口] FILE --> FILE2[module: ES模組入口] FILE --> FILE3[bin: 指令工具] FILE --> FILE4[files: 發布檔案清單] BUILD --> BUILD1[scripts: 腳本命令] BUILD --> BUILD2[eslintConfig: 程式碼檢查] BUILD --> BUILD3[babel: 轉譯配置] PUB --> PUB1[private: 私有設定] PUB --> PUB2[license: 授權方式] PUB --> PUB3[repository: 程式倉庫] style PKG fill:#6a6a8c,stroke:#333,stroke-width:2px,color:#fff style BASIC fill:#5d8392,stroke:#333,color:#fff style DEPS fill:#8c6351,stroke:#333,color:#fff style FILE fill:#7a9251,stroke:#333,color:#fff style BUILD fill:#7b5192,stroke:#333,color:#fff style PUB fill:#51928c,stroke:#333,color:#fff
即使沒有 README.md
,你也可以從 package.json
觀察以下幾件事:
- ✅ 這個專案的用途是什麼?(看
description
和套件) - 🧰 用了哪些第三方套件?(看
dependencies
) - 🏁 要怎麼啟動或執行?(看
scripts
裡的 start 或 dev) - 🧪 有沒有測試機制?建置流程?(看
scripts
和devDependencies
)
基本結構解說
以下是一份簡單的 package.json
範例,說明每個欄位的用途:
{
"name": "my-project",
"version": "1.0.0",
"description": "這是一個測試專案",
"main": "index.js",
"scripts": {
"start": "node index.js",
"test": "jest"
},
"dependencies": {
"express": "^4.18.2"
},
"devDependencies": {
"jest": "^29.6.1"
}
}
常見欄位說明:
欄位名稱 | 用途說明 |
---|---|
name | 專案名稱,通常小寫、無空格,例如 my-app。這在 npm 發佈套件時非常重要。 |
version | 專案版本,依照語意化版本規則(SemVer),例如 1.0.0 表示主版號 1。 |
description | 一段簡單的專案描述,用於辨識與說明專案功能。 |
main | 專案的進入點檔案,當其他人使用 require() 或 import 時,會預設從這裡開始讀取程式碼。 |
scripts | 預設可執行的指令集,常見如 start(啟動)、test(測試)、dev(開發模式)等。用 npm run [指令] 執行。 |
dependencies | 專案執行時所需的函式庫,例如 Web 框架、資料庫驅動等等。部署到伺服器時這些都會一併安裝。 |
devDependencies | 只在開發階段需要的套件,例如測試框架(如 Jest)、打包工具(如 Webpack)、Linter 等,這些不會在生產環境安裝。 |
補充:你可能會看到的其他欄位(選用)
欄位名稱 | 用途說明 |
---|---|
keywords | 關鍵字陣列,有助於在 npm 搜尋時被找到。 |
author | 作者資訊,例如姓名與 email。 |
license | 授權條款,例如 MIT、ISC 等。 |
repository | 專案原始碼的儲存位置,通常是 GitHub 連結。 |
engines | 指定此專案相容的 Node.js 或 npm 版本,避免版本不符。 |
透過這些資訊,package.json
就像一本為你量身打造的開發說明書,不只能幫助你啟動專案,還能讓你快速了解整個開發生態與依賴架構。真正熟練這個檔案,就等於會看懂一個專案的「骨架」。
什麼是 package-lock.json
?為什麼需要它?
當你執行 npm install
安裝套件時,除了會更新 node_modules/
資料夾與 package.json
(如果你安裝了新的套件),npm 還會自動產生或更新一個名為 package-lock.json
的檔案。
這個檔案不是多餘的,它非常關鍵。它的主要作用是:準確地記錄「實際安裝下來的每一個套件版本」,而不只是你在 package.json
中寫的那些主要依賴。舉個例子:
"dependencies": {
"express": "^4.18.0"
}
這段的意思是允許安裝 4.18.x 的任一版本(x 可變),只要版本相容。但如果你今天執行 npm install
時裝的是 4.18.2
,那 package-lock.json
就會明確記下來:
"express": {
"version": "4.18.2",
...
}
不只這樣,它還會詳細記下 express 這個套件底下又使用了哪些其他套件,它們的版本是什麼,這一整個「依賴樹」都會被記錄下來。
graph TD subgraph package-lock.json A[專案根目錄 package.json] B[依賴套件 A v1.2.0] C[依賴套件 B v2.1.0] D[依賴套件 C v0.5.0] E[子依賴 D v1.0.0] F[子依賴 E v3.2.1] G[子依賴 F v0.8.5] H[子依賴 G v2.0.0] I[子依賴 H v1.1.0] end A --> B A --> C A --> D B --> E B --> F C --> F C --> G D --> H F --> I style A fill:#f9f,stroke:#333,stroke-width:2px style B fill:#bbf,stroke:#333,stroke-width:1px style C fill:#bbf,stroke:#333,stroke-width:1px style D fill:#bbf,stroke:#333,stroke-width:1px style E fill:#ddf,stroke:#333,stroke-width:1px style F fill:#ddf,stroke:#333,stroke-width:1px style G fill:#ddf,stroke:#333,stroke-width:1px style H fill:#ddf,stroke:#333,stroke-width:1px style I fill:#ddf,stroke:#333,stroke-width:1px classDef locked stroke-dasharray: 5 5 class A,B,C,D,E,F,G,H,I locked
在這個圖中:
- 專案根目錄 (粉紅色節點) 是你的主要
package.json
定義的專案 - 直接依賴 (淺藍色節點) 是專案中直接安裝的套件 (A、B、C)
- 間接依賴/子依賴 (更淺藍色節點) 是由直接依賴引入的套件 (D、E、F、G、H)
圖中的虛線表示所有這些依賴都在 package-lock.json
中被「鎖定」到特定版本,這是 package-lock.json
的核心功能:
- 它確保每個套件的確切版本都被記錄
- 它記錄完整的依賴樹結構
- 它保證團隊中每個人和部署環境都使用完全相同的依賴版本
- 它避免了「我的電腦上可以運行」的問題
當你執行 npm install
時,npm 會優先使用 package-lock.json
來安裝確切的套件版本,而不是根據 package.json
中的版本範圍重新解析依賴,這樣就能確保環境的一致性。
為什麼這很重要?不能只有 package.json
嗎?
✅ 1. 確保所有人安裝的版本「完全一致」
在多人開發的環境中,如果只有 package.json
而沒有 package-lock.json
,每個人執行 npm install
可能會安裝到不同的子套件版本,因為 "^"
或 "~"
這些符號會讓 npm 去抓「相容的最新版本」。
這會導致一個常見的問題:
- A 在他的電腦上開發一切正常
- B 在另一台電腦上跑卻報錯、功能壞掉
- 為什麼?因為套件版本不一樣
而有了 package-lock.json
,npm 就會完全依照這份檔案來安裝所有套件,包括主套件與其所有依賴套件的版本,確保 A、B、C 三個開發者裝到的版本 100% 一致。
✅ 2. 安裝速度更快(npm 不用重新演算版本)
當 package-lock.json
存在時,npm 不需要花時間去查詢「哪些版本可用」、「怎樣組合才相容」等問題,因為所有依賴的版本組合都已經被記錄下來。
這樣安裝過程就能跳過一大段計算與決策,加快速度。
✅ 3. 專案更容易除錯與回溯
如果某次更新套件後出現 bug,只要你有保留舊的 package-lock.json
,就能準確回到原本的狀態,完全重建當時的環境,這對於找出問題、進行版本比對非常有幫助。
它不該被手動編輯
是的,package-lock.json
是由系統自動生成與維護的,開發者通常不需要(也不建議)手動修改它。
你唯一需要注意的事情是:
- ✅ 確保它被加入版本控制(如 Git)
很多新手會把它漏掉,或者錯誤地加入.gitignore
裡,這樣其他開發者就會安裝出不一樣的環境,產生「你跑得動我跑不動」的經典災難。 - 🚫 不要隨意刪除或修改內容
如果你發現 lock file 跟實際安裝的有衝突,最常見的做法是刪除整個node_modules/
與package-lock.json
,再重新跑一次npm install
,讓 npm 幫你生成乾淨的版本。
rm -rf node_modules package-lock.json
npm install
統整
功能 | 說明 |
---|---|
精準版本記錄 | 記錄實際安裝的每個套件版本與完整依賴樹 |
保證一致性 | 所有人執行 npm install 時都會安裝到一樣的版本 |
加速安裝流程 | 省去重新解析依賴的時間 |
回溯與除錯方便 | 出錯時可還原到特定版本組合 |
與 npm ci 搭配 | 確保 CI/CD 安裝環境完全一致 |
記得一句話:package.json
告訴 npm「我要什麼」,package-lock.json
記錄「我實際上拿到了什麼」。兩者缺一不可,合作無間!
如何從 package.json
看懂專案?
當你拿到一個陌生專案,裡面沒有寫 README,或內容太陽春,最直接的方式就是:打開 package.json
。
這個檔案就像專案的說明書,藏著大量能幫助你快速上手的線索。
我們可以從三個地方著手:
看 scripts
:快速知道怎麼啟動專案、執行開發任務
在 package.json
中,scripts
區塊定義了這個專案能執行的自訂指令。
這些指令通常會對應開發者日常常做的動作,例如啟動伺服器、打包前端資源、執行測試、格式化程式碼等等。
範例如下:
"scripts": {
"start": "node server.js",
"dev": "nodemon server.js",
"test": "jest",
"build": "vite build",
"lint": "eslint ."
}
常見指令說明:
指令 | 說明 |
---|---|
npm start | 啟動主程式,一般用於正式執行或本地伺服器啟動 |
npm run dev | 啟動開發模式,通常具備熱重載、自動重編譯等功能 |
npm test | 執行測試,通常搭配 Jest、Mocha 等測試框架 |
npm run build | 編譯或打包程式碼,常見於前端專案 |
npm run lint | 進行程式碼格式檢查或自動修正問題 |
💡 小提醒:
start
是唯一一個可以省略run
的指令,其他都需要寫npm run xxx
。
▶️ 怎麼用?
你可以直接打開終端機,在專案根目錄輸入其中一個指令:
npm start
看看有沒有什麼畫面跑出來?伺服器有沒有啟動?有報錯嗎?
這種「實際下指令、觀察結果」的方式,比看說明文件更直覺有效!
看 dependencies
和 devDependencies
:判斷這個專案用了哪些技術
這兩個區塊是 package.json
裡最關鍵的部分之一,裡面列出這個專案使用到的所有 npm 套件。
dependencies
:專案正式執行時需要的套件devDependencies
:開發階段才會用到的工具,如測試、打包器、Linter 等
透過這兩區的內容,我們可以快速判斷這個專案:
🔍 是前端還是後端?
- 有
react
、vite
、vue
、webpack
→ 大多是前端專案 - 有
express
、koa
、mongoose
→ 多半是後端 API 或伺服器 - 有
next
、nuxt
→ 屬於全端框架(Full Stack / SSR)
🧱 使用了哪些框架?
以下是一些常見框架與對應推測:
套件 | 可能用途 |
---|---|
react | 前端 UI 框架 |
vue | 前端 UI 框架 |
next | React + SSR 全端框架 |
nestjs | 後端 TypeScript 架構化框架 |
express | 傳統後端 REST API 框架 |
vite | 前端開發伺服器與打包工具 |
svelte | 現代輕量前端框架 |
🧪 有沒有在做測試?
看 devDependencies
裡是否出現以下常見測試工具:
套件 | 說明 |
---|---|
jest | 最常見的 JavaScript 單元測試框架 |
mocha | 彈性強、輕量的測試框架 |
vitest | Vite 的原生測試工具,速度快、與前端整合佳 |
@testing-library/react | 專為 React 組件設計的測試套件 |
⚠️ 小技巧
你可以用這個指令快速列出套件:
npm list --depth=0
這會印出目前安裝的所有套件(不含子依賴),方便你檢查有哪些工具被使用。
看 main
:從哪裡開始閱讀程式碼?
在 package.json
裡,main
欄位會指出這個專案的「進入點」,也就是 Node.js 執行時會先讀的主檔案。例如:
"main": "index.js"
這表示專案執行時會從 index.js
開始跑。這個檔案通常是程式邏輯的起點,例如建立伺服器、初始化設定、引入主模組等。
📌 小提醒:如果這是套件型專案(比如你開發 npm 套件),那
main
也決定了別人引用你這個套件時會讀到哪個檔案。
常見問題與錯誤解析
問題:安裝後專案跑不起來?
可能原因:
- 沒有跑
npm install
- 忘記用正確的指令啟動(
npm start
vsnpm run dev
) - 套件版本衝突,試試
rm -rf node_modules && npm install
問題:套件安裝出錯?
可能原因:
node
版本太舊package-lock.json
記錄的版本和系統衝突- 用的是
yarn
卻只有package-lock.json
(應該用npm
)
問題:明明寫著 ^1.2.3
,為什麼裝的是 1.2.5
?
因為 ^
符號允許安裝「相容的較新版本」。如果你不希望這樣,可以手動指定版本,例如 "1.2.3"
,或使用 npm ci
根據 package-lock.json
安裝。
結語:讓 package.json
成為你的好幫手
雖然很多初學者會把 package.json
當作 npm 自動生成的「背景設定檔」,但其實它就是整個專案的說明書,只是格式是 JSON 而已。
掌握它,你就可以:
- 不靠 README 也能搞懂專案
- 解決環境出錯的問題
- 更快上手別人的代碼
下一次 clone 一個新專案時,先打開 package.json
看一眼吧,它比你想像中有用!