- vừa được xem lúc

Từ Zero đến Principal Frontend Engineer (P4: Kiến trúc Frontend Scalable)

0 0 4

Người đăng: Albert Huynh

Theo Viblo Asia

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é! 🚀

Bình luận

Bài viết tương tự

- vừa được xem lúc

Thủ thuật nhỏ để căn chỉnh image với object-fit

Chào các bạn,. Có lẽ trong hành trình code của các bạn thì không ít lần gặp vấn đề méo ảnh do fix cứng cả width, height của ảnh nhỉ? Hoặc kể cả khi bạn set value cho 1 thuộc tính weigth hoặc height còn thuộc tính còn lại để auto thì nhiều lúc ảnh cũng không được hiển thị toàn vẹn cho lắm.

0 0 55

- vừa được xem lúc

Tìm hiểu về CSS framework - Bulma

Mở đầu:. Mấy bữa nay đang lướt web thấy có giới thiệu framework bulma này, được mọi người giới thiệu gọn nhẹ và dễ sử dụng, nên mình mới tìm hiểu thử và hôm nay xin viết 1 bài viết giới thiệu sơ qua với các bạn.

0 0 39

- vừa được xem lúc

Một số mẹo vặt "hay ho" của ES6 có thể bạn chưa biết - Phần 4

Xin chào, ở 3 bài trước của series "Một số mẹo vặt "hay ho" của ES6", mình đã chia sẻ 1 số tips/tricks nhỏ với ES6, hy vọng ít nhiều nó sẽ có ích với các bạn khi áp dụng vào thực tế. Hôm nay, xin mời các bạn theo dõi phần 4 của series này.

0 0 50

- vừa được xem lúc

Tìm hiểu về Jest Mocks Test phía frontend

Giới thiệu. Chắc hẳn không ai phủ nhận rằng UnitTest là 1 phần quan trọng trong giai đoạn phát triển phần mềm, đảm bảo cho code được coverage tránh các bug không mong muốn.

0 0 41

- vừa được xem lúc

Convert từ SVG sang Icon Font như thế nào?

Chào các bạn. Như câu hỏi trên title của bài viết, hôm nay mình sẽ hướng dẫn các bạn cách convert 1 file svg 1 cách khá đơn giản và vô cùng tiện lợi cho các bạn. https://icomoon.io/app/#/select.

0 0 62

- vừa được xem lúc

Một vài thủ thuật làm việc với các dạng layout - Phần 4

. Chào mọi người, cũng đã lâu rồi mình không thấy nhau. Để tiếp tục với series's về các dạng layout hôm nay mình sẽ chia sẻ thêm một trick thú vị nữa về step layout.

0 0 49