iT邦幫忙

2026 iThome 鐵人賽

DAY 9
0
Vibe Coding

夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略系列 第 9 篇

Day 9|甜點還沒開始做,先確認廚房能不能開工:從環境建置看懂 package.json 與 npm

  • 分享至 

  • xImage
  •  

昨天,我們替 AI 準備好了一本進專案前要先看的入職手冊。

到這裡,第一關「規劃設計」終於走完了~

接下來要正式進入「核心開發」了。

但一份 Code 要真的跑起來,靠的不只有 Code 本身。

它還需要正確的執行環境、套件、設定和開發工具。

這些東西準備好了,專案才真的有辦法開始工作。

這就是今天要拆的:

環境建置(Environment Setup)。


環境建置,到底在「建」什麼?

我以前聽到「環境建置」,一直以為大概就是:

把該裝的東西裝一裝。

後來才知道,它的範圍其實更大。

環境建置(Environment Setup),可以先理解成:

把這個專案需要的開發環境,準備到可以正常開發與執行的過程。

先把整張地圖攤開來看:

專案開發
│
├─ 開發環境 Development Environment
│
│  ├─ 作業系統 Operating System
│  │    └─ macOS / Windows / Linux
│  │
│  ├─ 執行環境 Runtime
│  │    └─ Node.js
│  │
│  ├─ 套件管理工具 Package Manager
│  │    └─ npm
│  │
│  ├─ 專案依賴 Dependencies
│  │    └─ Vue / Vite / Express ...
│  │
│  ├─ 環境設定 Configuration
│  │    └─ Environment Variables 等
│  │
│  └─ 開發工具 Development Tools
│       ├─ VS Code:Source Code Editor
│       └─ Git:Version Control System
│
└─ 環境建置 Environment Setup
     = 把這個專案需要的環境
       準備到可以正常開發與執行的過程

這張圖不是說每個專案都一定會用完全相同的工具。

換一種語言、框架或團隊,內容本來就可能不同。

但它至少先幫我解開了一個以前一直混在一起的問題:

  • VS Code 是原始碼編輯器(Source Code Editor),拿來讀、寫、修改程式碼
  • Node.js 是 JavaScript 執行環境(JavaScript Runtime)
  • npm 是套件管理工具(Package Manager),負責安裝與管理專案需要的套件

以前在我腦袋裡,它們全部只是:

「反正寫程式都會用到的東西。」

現在才知道,每個工具其實都負責不同工作。


第一次學 npm install,我以為自己裝壞了

我第一次學著安裝套件的時候,其實完全不知道自己在做什麼。

老師要我們輸入:

npm install

我也就照著打。

然後開始看到幾個完全不知道在幹嘛的東西:

package.json
package-lock.json
node_modules/

package.json 跟 package-lock.json 到底差在哪?

為什麼 package-lock.json 打開那麼長?

更誇張的是 node_modules。

我明明也沒記得自己下載幾個東西,為什麼裡面可以塞成這麼大一包?

我當時第一個反應是:

「等一下,我是不是下載錯東西了?」

後來才知道,這三個東西其實剛好分別扮演不同角色。

package.json
→ 專案宣告「我需要什麼」

package-lock.json
→ 記錄「這次實際解析成哪些版本」

node_modules/
→ 套件真正被安裝下來的地方

package.json:這個專案需要什麼?

package.json 是 Node.js / npm 專案裡很重要的一份設定檔,會記錄套件依賴、Scripts 和其他專案設定。

常見欄位大概有這些:

欄位 是什麼
scripts 定義專案可以執行的 Script Command
dependencies Production 執行時需要的套件
devDependencies 開發、測試、Lint、Build 等開發流程需要的工具
engines 描述專案對 Node.js、npm 等執行環境版本的需求
type 決定 Node.js 如何解讀 .js 模組,常見為 module 或 commonjs
private 設為 true 時,避免這個 Package 被意外發布到 npm Registry

今天先抓最常碰到的三個:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vitest"
  },
  "dependencies": {
    "vue": "^3.5.0"
  },
  "devDependencies": {
    "vite": "^7.0.0",
    "vitest": "^3.0.0"
  }
}

也就是:

dependencies、devDependencies、scripts。


dependencies 和 devDependencies:都是套件,為什麼要分開?

這兩個區塊真正的差別在於:

這個套件是 Production 所需要的依賴,還是主要用在開發流程?

可以先這樣記:

類型 什麼時候需要
dependencies Production 所需要的依賴
devDependencies 開發、測試、Lint、Build 等開發流程需要的工具

例如:

{
  "dependencies": {
    "vue": "^3.5.0"
  },
  "devDependencies": {
    "vite": "^7.0.0",
    "vitest": "^3.0.0"
  }
}

package-lock.json:package.json 明明已經有版本了,為什麼還要一份?

這是我以前最不懂的第二個檔案:

package-lock.json

因為 package.json 裡明明就已經有:

"vue": "^3.5.0"

為什麼還需要另一份版本紀錄?

原因是 package.json 裡的版本不一定代表:

永遠只能安裝這一個精確版本。

例如 ^3.5.0 允許 npm 在符合版本規則的範圍裡解析版本。

而真正安裝時,也不只有 Vue 自己。

Vue 可能還依賴其他 Package,那些 Package 又可能再依賴其他東西。

最後會形成一整棵:

依賴樹(Dependency Tree)。

這時候就需要 Lockfile(鎖定檔)。

npm 使用的 Lockfile,就是:

package-lock.json

它會把這次實際解析出的完整 Dependency Tree 和精確版本記錄下來。

所以:

package.json
→ 我要哪些套件+允許哪些版本範圍

package-lock.json
→ 這次整棵依賴樹實際解析成哪些版本

這也是為什麼 package-lock.json 打開來常常長得很可怕。

不是它壞掉了。

只是它記錄的比我原本想像的多很多。


node_modules:真正被安裝下來的地方

最後就是那個第一次看到很容易被嚇到的:

node_modules/

它不是套件清單。

而是:

套件真正被安裝到本機之後所在的資料夾。

而且裡面不只會有我直接安裝的套件。

例如我的專案需要 A:

我的專案
└─ A

但是 A 自己又需要 B 和 C:

我的專案
└─ A
   ├─ B
   └─ C

B、C 這種被其他套件間接帶進來的依賴,就叫做傳遞依賴(Transitive Dependencies)。

所以 node_modules 才常常大得很誇張。

原來不是我一次下載錯了一整座倉庫。

是 npm 把這道菜真正需要的材料和材料的材料,都一起搬進廚房了。


所以 npm install 到底做了什麼?

搞懂前三個角色之後,再回頭看:

npm install

就清楚很多。

它會根據 package.json 宣告的依賴,並在有 package-lock.json 時參考其中鎖定的依賴樹,把需要的套件安裝到 node_modules。

node_modules/

所以團隊開發時,一個很常見的流程會是:

git clone 專案
      ↓
進入專案資料夾
      ↓
npm install
      ↓
安裝專案需要的套件
      ↓
產生 node_modules
      ↓
準備環境設定
      ↓
npm run dev
      ↓
執行專案定義好的開發指令

也就是說,我不需要把自己電腦裡的 node_modules 整包傳給隊友。

專案已經透過 package.json 和 package-lock.json 留下依賴資訊。

隊友 Clone 專案後,再執行:

npm install

就可以重新把需要的套件安裝到自己的電腦。


套件裝好了,環境設定也要準備好

不過做到這裡,環境建置還沒有完全結束。

有些設定會隨著開發環境、測試環境或正式環境不同而改變,例如 API URL、Database URL、PORT,甚至 API Key、JWT Secret 等。

這類設定常會透過 環境變數(Environment Variables) 提供給程式。

而 .env,就是本機開發時很常用來保存這些 Environment Variables 的檔案形式之一。

例如:

API_URL=http://localhost:3000
PORT=5173

可以先這樣分:

Environment Variables
→ 程式執行時取得的環境設定

.env
→ 保存這些設定的一種常見檔案形式

這裡還有一個很重要的資安問題。

因為 .env 可能包含 API Key、Database Password、JWT Secret 等敏感資訊,因此含有真實敏感值的 .env 通常不應提交進 Git。

團隊反而常留一份:

.env.example

只告訴其他開發者:

「這個專案需要哪些環境變數。」

但不把真正的密鑰放進去。

所以環境建置不只是:

「套件有沒有安裝好?」

還要確認:

「這個環境需要的設定,有沒有準備好?」


npm run dev,到底是在 run 什麼?

環境和套件準備完之後,開發時下一個很常看到的指令就是:

npm run dev

以前我一直下意識覺得:

dev 應該是 npm 裡某種固定的開發模式吧?

其實不是。

npm run 會去 package.json 的 scripts 裡找到指定名稱,再執行右邊真正的 command。

例如:

script 名稱 要執行的 command
dev vite
build vite build
test vitest

放回 package.json:

{
  "scripts": {
    "dev": "vite",
    "build": "vite build",
    "test": "vitest"
  }
}

所以:

npm run dev

其實是在做:

npm run dev
      ↓
去 scripts 找名稱叫 dev 的項目
      ↓
找到:

"dev": "vite"

      ↓
執行 vite

一般自訂 Script 的名稱可以自己取。

只是團隊通常會用:

dev
build
test
lint
format

這類大家一看就知道用途的名字。

右邊放的則是實際要執行的 command,不一定是某個 npm 套件。

所以:

npm run 不是「執行某個套件」,而是「執行專案定義好的一條 Script」。


同一份 Code,也要考慮團隊實際使用的開發環境

前面解決的是:

怎麼讓大家把同一個專案需要的套件和設定準備起來。

但就算 Code 和套件完全相同,開發者使用的環境還是可能不同。

BuJo 團隊成員使用的開發環境不完全一樣,因此有些 Script 也需要考慮不同作業系統的執行方式。

例如後端測試 Script 需要先設定:

NODE_OPTIONS

這類環境變數,再執行 Jest。

Windows 常見的 Command Prompt 與 macOS / Linux 常見的 POSIX Shell,在設定環境變數的語法上並不相同。

如果把某一套 Shell 的寫法直接寫死在 package.json,就可能變成:

某些環境可以直接執行
某些環境卻跑不起來

所以 BuJo 後端使用了:

cross-env

讓同一條 npm Script 可以用比較一致的方式設定 Environment Variables,不需要每個作業系統各維護一套 command。

這也是環境建置很實際的一部分:

團隊需要考慮的,不只是某一台電腦能不能跑,而是實際會參與開發的環境能不能用同一套方式工作。


原來那些指令,不是要背的咒語

我現在重新看環境建置,最有感的不是學會更多指令。

而是那些以前只會照著 README 複製貼上的東西,終於開始有了前因後果。

npm install、npm run dev 不再只是要背起來的咒語;package.json、package-lock.json、.env 也不再只是散落在專案根目錄的檔案。

它們其實都在回答同一件事:

這個專案需要什麼,才能被重新跑起來。

以前我只知道把專案跑起來。

現在開始知道:

跑得起來,本身也有一套可以被理解、記錄和重現的條件。

環境準備好了。

下一篇,就真的要走進 Code 裡面了。

而 Code 一多,下一個問題很快就會冒出來:

這麼多檔案,到底應該怎麼分,才不會最後連自己都找不到?

下一篇,就來拆專案結構設計。


參考資料


上一篇
Day 8|AI 也需要一本入職手冊:CLAUDE.md、AGENTS.md 怎麼讓它進專案前先讀懂規矩?
下一篇
Day 10|廚房工具不能全塞一櫃:從專案結構看懂 Code 怎麼分類
系列文
夢幻甜品師闖工程世界:Vibe Coding vs 專業開發的 0→1 冒險攻略 共 30 篇
圖片
  熱門推薦
圖片
{{ item.channelVendor }} | {{ item.webinarstarted }} |
{{ formatDate(item.duration) }}
直播中

尚未有邦友留言

立即登入留言