เมื่อโปรเจกต์ของคุณเติบโตขึ้นจนมีทั้งฝั่งหน้าบ้าน และหลังบ้าน การแยก Repository หรือการแยกโฟลเดอร์ออกจากกันโดยเด็ดขาดมักจะสร้างความยุ่งยากในการจัดการ Dependency (เช่น ต้องตามอัปเดตไลบรารีแยกกัน, เสียพื้นที่ดิสก์ซ้ำซ้อน)
NPM Workspaces คือฟีเจอร์ที่ติดมากับ Node.js ตั้งแต่เวอร์ชัน 15+ มันถูกออกแบบมาเพื่อทำ Monorepo ช่วยให้เราสามารถรวมหลาย ๆ โปรเจกต์ ไว้ภายใต้โฟลเดอร์หลักอันเดียว โดยที่สามารถแชร์ node_modules ร่วมกันได้ และยังคงแยกโค้ดของแต่ละฝั่งได้อย่างเป็นสัดส่วน
🏗️ โครงสร้างโฟลเดอร์หลัก
ก่อนจะเริ่มลงมือทำ ให้วางโครงสร้างโฟลเดอร์ของโปรเจกต์ให้ออกมาในลักษณะนี้
Plain Text
my-monorepo/
├── package.json <-- [Root] จุดควบคุมหลักของทุกโปรเจกต์
├── package-lock.json <-- [Root] มีตัวเดียวควบคุมทั้งระบบ
├── node_modules/ <-- [Root] ที่เก็บ Library ทั้งหมด (แชร์ร่วมกัน) │
├── frontend/ <-- โฟลเดอร์ Frontend (เช่น Vue 3 + Vite) │ ├── package.json │ ├── vite.config.ts
│ └── src/
│
└── backend/ <-- โฟลเดอร์ Backend (เช่น Node.js + Express) ├── package.json └── src/
🛠️ ขั้นตอนการตั้งค่าทีละ Step
สร้าง Root Package.json
ให้สร้างโฟลเดอร์หลักนอกสุดขึ้นมา จากนั้นเปิด Terminal ในโฟลเดอร์นี้แล้วสร้างไฟล์ package.json ตัวหลักขึ้นมา และระบุคีย์ "workspaces" ลงไป
Plain Text
{ "name": "my-monorepo", "version": "1.0.0", "private": true, "workspaces": [ "frontend", "backend" ], "scripts": { "dev:frontend": "npm run dev -w frontend", "dev:backend": "npm run dev -w backend", "build:all": "npm run build --workspaces" }
}
💡 อธิบายคีย์สำคัญ
"private": true จำเป็นต้องใส่ เพื่อป้องกันไม่ให้เราเผลอ Publish โฟลเดอร์ Root นี้ขึ้นไปยัง npm registry
"workspaces" เป็นการบอก NPM ว่ามีโฟลเดอร์ไหนบ้างที่นับเป็นลูกทีมใน Monorepo นี้
ตั้งค่าในโปรเจกต์ลูก
ย้ายโฟลเดอร์โปรเจกต์ของคุณเข้ามาด้านใน หรือสร้างขึ้นใหม่ โดยที่ใน package.json ของโปรเจกต์ลูก ให้ตั้งชื่อ "name" ให้เป็นเอกลักษณ์
frontend/package.json
Plain Text
{ "name": "frontend", "version": "0.1.0", "type": "module", "scripts": { "dev": "vite", "build": "vue-tsc -b && vite build" }, "dependencies": { "vue": "^3.5.13", "axios": "^1.8.4" }
}
backend/package.json
Plain Text
{ "name": "backend", "version": "0.1.0", "scripts": { "dev": "nodemon src/index.js", "start": "node src/index.js" }, "dependencies": { "express": "^4.19.2" }
}
ลบของเก่าแล้วคลีนระบบ
หากก่อนหน้านี้คุณเคยรัน npm install แยกในโฟลเดอร์ frontend หรือ backend ไปแล้ว ให้ทำการลบโฟลเดอร์ node_modules และ package-lock.json ในโปรเจกต์ลูกออกให้หมด
จากนั้นกลับมาที่โฟลเดอร์นอกสุด แล้วรันคำสั่ง
npm install
NPM จะทำการสแกนดู package.json ของตัวลูกทุกตัว แล้วดึงเอา Dependency ทั้งหมดมารวมกันและติดตั้งไว้ที่ node_modules ของ Root ตัวบนสุดเพียงที่เดียว!
🚀 วิธีการรัน Frontend และ Backend พร้อมกัน
เมื่อเปลี่ยนมาใช้ระบบ Workspaces เราไม่จำเป็นต้องเปิด Terminal หลาย ๆ หน้าต่างแล้วคอย cd เข้าโฟลเดอร์นู้นโฟลเดอร์นี้อีกต่อไป เราสามารถควบคุมทุกอย่างจากโฟลเดอร์นอกสุดได้ทันที
วิธีที่ 1: รันพร้อมกันด้วยคำสั่งเดียว
หากต้องการเปิด Terminal อันเดียวแล้วให้มันรันทั้ง Frontend และ Backend ขึ้นมาพร้อมกันในหน้าจอเดียว เราจะใช้เครื่องมือที่ชื่อว่า concurrently เข้ามาช่วย
- ติดตั้ง
concurrently ไว้ที่โฟลเดอร์ Root
npm install concurrently --save-dev
- ไปเพิ่ม Script ใน
package.json ตัวนอกสุด
Plain Text
"scripts": { "dev:frontend": "npm run dev -w frontend", "dev:backend": "npm run dev -w backend", "dev": "concurrently \"npm run dev:frontend\" \"npm run dev:backend\""
}