1. Khởi tạo dự án
Đầu tiên, tạo project mới với Vite:
npm create vite@latest my-react-app -- --template react-ts
cd my-react-app
npm install
2. Cấu trúc thư mục
Tổ chức project theo cấu trúc sau để dễ bảo trì và mở rộng:
src/
├── assets/ # Static files (images, fonts, etc.)
├── components/ # Shared components
│ ├── common/ # Basic UI components
│ └── layouts/ # Layout components
├── config/ # Configuration files
├── hooks/ # Custom hooks
├── pages/ # Page components
├── services/ # API services
├── stores/ # State management
├── styles/ # Global styles
├── types/ # TypeScript type definitions
└── utils/ # Utility functions
3. Cài đặt và cấu hình các công cụ cần thiết
3.1. Dependencies cần thiết
# Development dependencies
npm install -D @typescript-eslint/eslint-plugin @typescript-eslint/parser
npm install -D eslint eslint-plugin-react eslint-plugin-react-hooks
npm install -D prettier eslint-config-prettier eslint-plugin-prettier
npm install -D husky lint-staged
# Production dependencies
npm install react-router-dom @tanstack/react-query axios
npm install clsx tailwindcss postcss autoprefixer
3.2. Cấu hình ESLint
Tạo file .eslintrc.json
{
"env": {
"browser": true,
"es2021": true
},
"extends": [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:react/recommended",
"plugin:react-hooks/recommended",
"plugin:prettier/recommended"
],
"parser": "@typescript-eslint/parser",
"parserOptions": {
"ecmaFeatures": {
"jsx": true
},
"ecmaVersion": "latest",
"sourceType": "module"
},
"plugins": ["react", "@typescript-eslint", "prettier"],
"rules": {
"react/react-in-jsx-scope": "off",
"react/prop-types": "off",
"@typescript-eslint/explicit-module-boundary-types": "off",
"@typescript-eslint/no-unused-vars": ["error"],
"prettier/prettier": ["error", {}, { "usePrettierrc": true }]
},
"settings": {
"react": {
"version": "detect"
}
}
}
3.3. Cấu hình Prettier
Tạo file .prettierrc
{
"semi": true,
"tabWidth": 2,
"printWidth": 100,
"singleQuote": true,
"trailingComma": "es5",
"jsxBracketSameLine": false
}
3.4. Cấu hình Husky và lint-staged
# Khởi tạo husky
npx husky install
npx husky add .husky/pre-commit "npx lint-staged"
Thêm cấu hình lint-staged vào package.json:
{
"lint-staged": {
"src/**/*.{js,jsx,ts,tsx}": [
"eslint --fix",
"prettier --write"
]
}
}
4. Thiết lập môi trường development
4.1. Cấu hình Vite
Tạo file vite.config.ts:
import { defineConfig } from 'vite';
import react from '@vitejs/plugin-react';
import path from 'path';
export default defineConfig({
plugins: [react()],
resolve: {
alias: {
'@': path.resolve(__dirname, './src'),
},
},
server: {
port: 3000,
open: true,
},
build: {
outDir: 'dist',
sourcemap: true,
chunkSizeWarningLimit: 1500,
},
});
4.2. Cấu hình TypeScript
Cập nhật tsconfig.json:
{
"compilerOptions": {
"target": "ESNext",
"useDefineForClassFields": true,
"lib": ["DOM", "DOM.Iterable", "ESNext"],
"allowJs": false,
"skipLibCheck": true,
"esModuleInterop": false,
"allowSyntheticDefaultImports": true,
"strict": true,
"forceConsistentCasingInFileNames": true,
"module": "ESNext",
"moduleResolution": "Node",
"resolveJsonModule": true,
"isolatedModules": true,
"noEmit": true,
"jsx": "react-jsx",
"baseUrl": ".",
"paths": {
"@/*": ["src/*"]
}
},
"include": ["src"],
"references": [{ "path": "./tsconfig.node.json" }]
}
5. Best Practices và các nguyên tắc phát triển
5.1. Component Organization
- Sử dụng functional components và hooks
- Tách logic phức tạp thành custom hooks
- Tổ chức components theo atomic design
- Sử dụng TypeScript interfaces cho props
Ví dụ về component structure:
// src/components/Button/Button.tsx
import { ButtonHTMLAttributes, FC } from 'react';
import clsx from 'clsx';
interface ButtonProps extends ButtonHTMLAttributes<HTMLButtonElement> {
variant?: 'primary' | 'secondary';
size?: 'sm' | 'md' | 'lg';
}
export const Button: FC<ButtonProps> = ({
children,
variant = 'primary',
size = 'md',
className,
...props
}) => {
return (
<button
className={clsx(
'rounded-md font-medium transition-colors',
{
'bg-blue-600 text-white hover:bg-blue-700': variant === 'primary',
'bg-gray-200 text-gray-800 hover:bg-gray-300': variant === 'secondary',
'px-3 py-1 text-sm': size === 'sm',
'px-4 py-2': size === 'md',
'px-6 py-3 text-lg': size === 'lg',
},
className
)}
{...props}
>
{children}
</button>
);
};
5.2. State Management
- Sử dụng React Query cho server state
- Sử dụng Context API cho global UI state
- Tránh prop drilling bằng composition
5.3. Performance Optimization
- Sử dụng React.memo cho component tốn nhiều tài nguyên
- Lazy loading cho routes và heavy components
- Optimistic updates với React Query
- Code splitting theo routes
6. Tối ưu hóa production build
6.1. Performance Checklist
- Compress images và assets
- Implement code splitting
- Enable tree shaking
- Lazy load components và routes
- Optimize bundle size
6.2. Cấu hình production build
// vite.config.ts cho production
export default defineConfig({
build: {
target: 'esnext',
minify: 'terser',
cssCodeSplit: true,
rollupOptions: {
output: {
manualChunks: {
vendor: ['react', 'react-dom'],
...splitVendorChunkPlugin(),
},
},
},
},
});
6.3. Docker setup (optional)
# Dockerfile
FROM node:18-alpine as builder
WORKDIR /app
COPY package*.json ./
RUN npm install
COPY . .
RUN npm run build
FROM nginx:alpine
COPY --from=builder /app/dist /usr/share/nginx/html
EXPOSE 80
CMD ["nginx", "-g", "daemon off;"]
Script Commands
Thêm các scripts sau vào package.json:
{
"scripts": {
"dev": "vite",
"build": "tsc && vite build",
"preview": "vite preview",
"lint": "eslint src --ext .ts,.tsx",
"lint:fix": "eslint src --ext .ts,.tsx --fix",
"format": "prettier --write \"src/**/*.{ts,tsx,css,md}\"",
"type-check": "tsc --noEmit",
"prepare": "husky install"
}
}
Tổng kết
Với setup này, bạn đã có một dự án React + Vite + TypeScript với đầy đủ các công cụ và cấu hình cần thiết để phát triển một ứng dụng production-ready. Cấu trúc project này giúp:
- Maintain code dễ dàng
- Tối ưu performance
- Type safety với TypeScript
- Code quality được đảm bảo với ESLint và Prettier
- Workflow development hiệu quả với Husky và lint-staged