Dựa trên repo nổi tiếng bulletproof-react. Đây là tiêu chuẩn vàng cho các dự án Enterprise.
1. Cấu trúc thư mục (Canonical)
Code:
src/
├── assets/ # Ảnh, Fonts, Icons tĩnh
├── components/ # UI Components CHUNG (Button, Modal, Input)
├── config/ # Biến môi trường, config global
├── features/ # Business Logic (Domain Driven)
├── hooks/ # Hooks CHUNG (useDebounce, useToggle)
├── lib/ # Cấu hình thư viện (axios setup, queryClient)
├── providers/ # Tất cả Context Provider (AppProvider)
├── routes/ # Cấu hình Routing (App Router thì bỏ cái này)
├── stores/ # Global State Management (Zustand)
├── types/ # TypeScript Types chung
└── utils/ # Hàm tiện ích thuần túy (formatDate, currency)2. Quy tắc quan trọng
A. Component UI vs Feature Component
src/components/Button.tsx: Dumb Component. Chỉ nhận props và hiển thị. Không gọi API, không biết Business Logic.src/features/auth/components/LoginForm.tsx: Smart Component. Gọi API, xử lý validation, state. Sử dụngButtontừsrc/components.
B. Providers Pattern
Đừng làm file App.tsx hay layout.tsx dài ngoằng với 10 tầng Provider.
Hãy gom chúng lại vào src/providers/app.tsx.
tsx:
// src/providers/app.tsx
export const AppProvider = ({ children }) => {
return (
<ErrorBoundary FallbackComponent={ErrorFallback}>
<HelmetProvider>
<QueryClientProvider client={queryClient}>
<AuthProvider>
<Router>{children}</Router>
</AuthProvider>
</QueryClientProvider>
</HelmetProvider>
</ErrorBoundary>
);
};C. Barrel Exports (index.ts)
Mỗi feature nên có file index.ts để public API ra ngoài.
ts:
// src/features/auth/index.ts
export * from './routes';
export * from './api/getUser';
// KHÔNG export LoginForm.tsx nếu component khác không cần dùng nó.Kết luận
Một kiến trúc tốt là kiến trúc mà ở đó:
- Người mới vào dự án có thể tìm thấy file cần sửa trong < 30 giây.
- Việc thêm tính năng mới không làm hỏng tính năng cũ.
- Tách biệt rõ ràng giữa "UI Library" (src/components) và "Business App" (src/features).