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.jsonpackage-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 模組,常見為 modulecommonjs
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"
  }
}

也就是:

dependenciesdevDependenciesscripts


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.jsonpackage-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.jsonscripts 裡找到指定名稱,再執行右邊真正的 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 installnpm run dev 不再只是要背起來的咒語;package.jsonpackage-lock.json.env 也不再只是散落在專案根目錄的檔案。

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

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

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

現在開始知道:

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

環境準備好了。

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

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

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

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


參考資料


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

尚未有邦友留言

立即登入留言