Sau khi đã nắm vững Micro Frontend, JavaScript Engine, và TypeScript nâng cao, bước tiếp theo để trở thành Principal Frontend Engineer là hiểu cách thiết kế kiến trúc frontend scalable – hệ thống có thể mở rộng, dễ bảo trì và tối ưu hiệu năng khi ứng dụng phát triển lớn hơn.
Trong bài này, chúng ta sẽ đi qua:
✅ Các mô hình kiến trúc frontend phổ biến
✅ Cách tổ chức codebase cho dự án lớn
✅ Công cụ và best practices từ các công ty lớn
1. Các Mô Hình Kiến Trúc Frontend Scalable
1.1. Monolithic vs Modular
Monolithic | Modular |
---|---|
Toàn bộ ứng dụng nằm trong 1 codebase lớn | Chia thành các module độc lập |
Khó scale khi dự án phình to | Dễ mở rộng, từng phần có thể phát triển riêng |
👉 Khi nào dùng Modular?
- Khi team lớn (>5 dev)
- Khi ứng dụng có nhiều tính năng độc lập (Ví dụ: Admin Dashboard + User App)
- Khi cần deploy từng phần riêng biệt
1.2. Micro Frontends (Đã học ở P1)
- Chia ứng dụng thành các "mini-app" độc lập (Ví dụ: Checkout, Product, User Profile)
- Mỗi phần có thể dùng framework khác nhau (React, Vue, Svelte)
- Giao tiếp qua Custom Events hoặc State Management (Redux, Zustand)
1.3. Layered Architecture (Onion, Clean Architecture)
Lớp UI (Presentation Layer)
- Components, Pages
- Xử lý render & user interactions
Lớp Business Logic (Domain Layer)
- Use Cases, Services
- Xử lý nghiệp vụ (Ví dụ: tính toán giá, validate data)
Lớp Data (Infrastructure Layer)
- API calls, Local Storage, Cache
- Độc lập với UI & Business Logic
Ví dụ:
// ❌ Cách thông thường (logic trộn lẫn trong component)
function OrderPage() { const [orders, setOrders] = useState([]); useEffect(() => { fetch('/api/orders').then(res => setOrders(res.data)); }, []); const total = orders.reduce((sum, order) => sum + order.price, 0); return <div>Total: {total}</div>;
} // ✅ Clean Architecture (tách biệt layers)
// Lớp Infrastructure
class OrderApi { static async fetchOrders() { /* API call */ }
} // Lớp Business Logic
class OrderService { static calculateTotal(orders) { return orders.reduce((sum, order) => sum + order.price, 0); }
} // Lớp UI
function OrderPage() { const [orders, setOrders] = useState([]); useEffect(() => { OrderApi.fetchOrders().then(setOrders); }, []); const total = OrderService.calculateTotal(orders); return <div>Total: {total}</div>;
}
2. Cách Tổ Chức Codebase Cho Dự Án Lớn
2.1. Feature-Based Structure (Thay vì Tech-Based)
❌ Tech-Based (Khó maintain)
/src /components /pages /hooks /utils
✅ Feature-Based (Dễ mở rộng)
/src /features /auth /components /hooks /services /dashboard /components /hooks /services /shared (Global components, utils)
Lợi ích:
- Mỗi tính năng độc lập, dễ thêm/xóa
- Giảm file conflicts khi nhiều người làm chung
- Dễ áp dụng code splitting
2.2. Atomic Design (Cho UI Scalable)
Cấp độ | Ví dụ | Mục đích |
---|---|---|
Atoms | Button, Input | Thành phần nhỏ nhất |
Molecules | SearchBar (Input + Button) | Kết hợp atoms |
Organisms | Header (Logo + SearchBar + Nav) | Nhóm molecules |
Templates | Page Layout (Header + Sidebar) | Bố cục chung |
Pages | HomePage, ProductPage | Logic & data binding |
Ví dụ:
// Atoms/Button.tsx
export const Button = ({ children }) => ( <button className="btn">{children}</button>
); // Molecules/SearchBar.tsx
import { Button, Input } from '../Atoms'; export const SearchBar = () => ( <div> <Input placeholder="Search..." /> <Button>Search</Button> </div>
);
3. Công Cụ & Best Practices Từ Các Công Ty Lớn
3.1. Tooling
- Monorepo: Turborepo, Nx (Quản lý nhiều dự án chung)
- Linting/Formatting: ESLint + Prettier + Husky (Git hooks)
- CI/CD: GitHub Actions, CircleCI (Auto test/deploy)
3.2. Documentation
- Storybook (UI component docs)
- Swagger/OpenAPI (API docs)
**Kết Luận
Qua bài này, hy vọng anh chị em mình có thể phần nào nắm vững một vài kiến trúc và có thể tận dụng nó vào thực tế.
Nếu anh em đang gặp vấn đề gì khi scale frontend? Hãy comment để mình giải đáp nhé! 🚀