Client-side hooks (husky + lint-staged): chạy nhanh, kiểm tra cơ bản (format, lint file đã sửa) — UX tốt vì fail trước khi commit.
Server-side CI gate: nguồn chân lý, không thể bypass — luôn phải có vì hook client có thể --no-verify. husky quản lý Git hooks trong package.json/.husky/: pre-commit chạy lint-staged, commit-msg validate conventional commits (commitlint), pre-push chạy test nhanh. lint-staged chạy lệnh chỉ trên file git add đã stage: ví dụ *.ts: eslint --fix, prettier --write — không lint toàn repo (chậm) mà chỉ file thay đổi. Defense in depth:
- Editor: ESLint extension highlight lỗi realtime;
- Pre-commit hook: lint + format file staged;
- Pre-push hook: test fast subset;
- CI: full lint + type check + test + build — bắt mọi thứ hook client bỏ qua. Conventional Commits:
feat: add login,fix(api): handle 401— chuẩn hóa commit message giúp tự generate changelog vớisemantic-release. Pitfall: hook client quá nặng (chạy full test) → dev frustrated, dùng--no-verify→ mất ý nghĩa
Giữ pre-commit < 5s. CI bypass: cấm push thẳng vào main ở branch protection, require PR + status check pass, require linear history nếu cần.