Chúng ta sẽ xây dựng một hệ thống Thương mại điện tử (E-commerce) thu nhỏ nhưng đầy đủ các thành phần của một dự án Enterprise.
1. Yêu cầu hệ thống (System Requirements)
Hệ thống bao gồm 3 ứng dụng riêng biệt nhưng liên kết chặt chẽ:
-
Storefront (Customer App):
- Dành cho người mua hàng.
- Tối ưu SEO, tốc độ tải trang (Next.js App Router).
- Features: Browse Product, Cart, Checkout.
-
Merchant Portal (Seller App):
- Dành cho người bán hàng/đối tác.
- Dashboard quản lý sản phẩm, đơn hàng của riêng họ.
- Features: Analytics, Inventory Mananagement.
-
Admin Portal (Platform Owner):
- Dành cho Super Admin.
- Quản lý toàn bộ Merchant, Users, System Settings.
2. Tại sao chọn Monorepo?
Thay vì tạo 3 repo git riêng biệt, chúng ta dùng Monorepo (Turborepo) để giải quyết bài toán:
- Shared UI: Button, Input, Table giống hệt nhau ở cả 3 app.
- Shared Logic: Hàm định dạng tiền tệ, xử lý ngày tháng, Zod Schema validation dùng chung.
- Unified DX: Chạy
npm installmột lần cho cả 3 dự án.
3. Cấu trúc thư mục (Folder Structure)
apps/
├── store/ (Next.js - Port 3000)
├── admin/ (Next.js - Port 3001)
└── merchant/ (Next.js - Port 3002)
packages/
├── ui/ (Shared Components)
│ ├── Button.tsx
│ ├── Card.tsx
│ └── ...
├── database/ (Prisma Config)
├── config/ (ESLint, TSConfig)
└── utils/ (Formatters, Constants)4. Công nghệ sử dụng (Tech Stack)
- Framework: Next.js 14 (App Router).
- Monorepo Tool: Turborepo.
- Styling: Tailwind CSS + Shadcn/ui (trong
packages/ui). - Database: PostgreSQL + Prisma (trong
packages/database). - Authentication: NextAuth.js (Auth.js) v5.
- State Management: Zustand (Client) + React Query (Server state).
5. Architectural Decision: Monorepo vs Microfrontends
Tại sao chúng ta chọn Monorepo (Code Splitting at Build Time) thay vì Microfrontends (Composition at Runtime)?
| Tiêu chí | Monorepo (Turborepo) | Microfrontends (Module Federation) |
|---|---|---|
| Độ phức tạp | Thấp. Phát triển như một dự án bình thường. | Cao. Cần cấu hình Webpack/Vite phức tạp để share dependencies. |
| Consistency | Cao. UI/Logic được import trực tiếp và type-safe tuyệt đối. | Khó. Dễ bị lệch version giữa các micro-app (VD: App A dùng React 18, App B dùng React 16). |
| Performance | Tối ưu tốt nhờ Next.js Compiler. | Có thể bị chậm do duplicate dependencies tải xuống browser. |
| Deploy | Deploy cả cụm hoặc từng app. CI/CD đơn giản. | Cần quy trình CI/CD orchestration phức tạp. |
| Phù hợp với | Team < 50 người. Cần share code nhiều. | Team > 100 người. Các team hoạt động độc lập hoàn toàn. |
Kết luận: Với quy mô dự án này (và đa số startup/SME), Monorepo là sự lựa chọn cân bằng nhất giữa tốc độ phát triển (DX) và khả năng mở rộng. Microfrontends thường là "Over-engineering" trừ khi bạn là Netflix hay Amazon.
6. Chiến lược chia sẻ (Sharing Strategy)
Shared UI Component
Component trong packages/ui sẽ được export dưới dạng library.
Ví dụ: import { Button } from "@repo/ui/button".
Shared Config
File tailwind.config.js sẽ được cấu hình chung để đảm bảo Brand Colors giống nhau trên toàn hệ thống.
// packages/ui/tailwind.config.js
module.exports = {
theme: {
extend: {
colors: {
primary: "#0F172A",
// ...
}
}
}
}Đây là bước khởi đầu quan trọng để đảm bảo khả năng mở rộng (Scalability) sau này.