本文為 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"
}
}
常見欄位說明:
補充:你可能會看到的其他欄位(選用)
透過這些資訊,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統整
記得一句話: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 ."
}
常見指令說明:
💡 小提醒:
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)
🧱 使用了哪些框架?
以下是一些常見框架與對應推測:
🧪 有沒有在做測試?
看 devDependencies 裡是否出現以下常見測試工具:
⚠️ 小技巧
你可以用這個指令快速列出套件:
npm list --depth=0這會印出目前安裝的所有套件(不含子依賴),方便你檢查有哪些工具被使用。
看 main:從哪裡開始閱讀程式碼?
在 package.json 裡,main 欄位會指出這個專案的「進入點」,也就是 Node.js 執行時會先讀的主檔案。例如:
"main": "index.js"這表示專案執行時會從 index.js 開始跑。這個檔案通常是程式邏輯的起點,例如建立伺服器、初始化設定、引入主模組等。
📌 小提醒:如果這是套件型專案(比如你開發 npm 套件),那
main也決定了別人引用你這個套件時會讀到哪個檔案。
常見問題與錯誤解析
問題:安裝後專案跑不起來?
可能原因:
- 沒有跑
npm install - 忘記用正確的指令啟動(
npm startvsnpm 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 看一眼吧,它比你想像中有用!