Site logo
Authors
  • avatar Nguyễn Đức Xinh
    Name
    Nguyễn Đức Xinh
    Twitter
Published on
Published on

Thiết lập Husky và lint-staged trong dự án Next/React của bạn

Các công cụ kiểm soát chất lượng code như ESLint và Prettier rất tuyệt vời để duy trì clean code và nhất quán. Tuy nhiên, chúng chỉ hiệu quả khi developers nhớ sử dụng chúng. Sẽ thế nào nếu bạn có thể đảm bảo code được tự động lint và format trước khi được commit vào repository? Đó chính là lúc Husky và lint-staged phát huy tác dụng.

Trong hướng dẫn này, tôi sẽ chỉ cho bạn cách thiết lập Husky và lint-staged trong dự án React/Next.js để tự động hóa việc kiểm tra chất lượng code và ngăn chặn code có vấn đề xâm nhập vào codebase của bạn.

Husky và lint-staged là gì?

Husky là công cụ giúp việc thiết lập Git hooks trở nên dễ dàng. Git hooks là các scripts chạy tự động khi các sự kiện Git cụ thể xảy ra, như commit hoặc push code. lint-staged là công cụ chạy linters cho các file đã được staged trong Git. Điều này có nghĩa là bạn có thể chạy linters và formatters chỉ trên các file bạn sắp commit, thay vì toàn bộ codebase, giúp quá trình nhanh hơn đáng kể.

Kết hợp với nhau, những công cụ này tạo ra một quy trình pre-commit mạnh mẽ đảm bảo code đáp ứng tiêu chuẩn của team trước khi được commit.

Lợi ích của việc sử dụng Husky và lint-staged

  • Tính nhất quán: Đảm bảo tất cả code được commit tuân theo hướng dẫn về phong cách code của team
  • Tự động hóa: Tự động chạy formatting và linting, nên developers không cần phải nhớ
  • Tốc độ: Chỉ kiểm tra các file đã được staged để commit, không phải toàn bộ codebase
  • Phòng ngừa: Ngăn chặn code có vấn đề xâm nhập vào repository ngay từ đầu
  • Hài hòa trong team: Giảm thiểu các tranh luận về phong cách code trong quá trình review

Cài đặt

Hãy bắt đầu bằng việc cài đặt các packages cần thiết:

npm install --save-dev husky lint-staged
  • husky: Manages Git hooks.
  • lint-staged: Filters staged files and runs tasks on them.

Thiết lập Husky

Đầu tiên, chúng ta cần khởi tạo Husky trong dự án của mình. Điều này sẽ tạo ra các scripts Git hook cần thiết:

npx husky init

Lệnh này:

  • Tạo thư mục .husky trong thư mục gốc của dự án.
  • Thêm file hook mẫu pre-commit (.husky/pre-commit).
  • Cập nhật package.json của bạn với script prepare như sau:
{
  "scripts": {
    "prepare": "husky install"
  }
}

Script prepare sẽ tự động chạy sau npm install, vì vậy Husky sẽ được thiết lập cho tất cả mọi người làm việc trên dự án.

Và thư mục .husky sẽ trông như thế này:

.husky
├── _
│   ├── applypatch-msg
│   ├── commit-msg
│   ├── h
│   ├── husky.sh
│   ├── post-applypatch
│   ├── post-checkout
│   ├── post-commit
│   ├── post-merge
│   ├── post-rewrite
│   ├── pre-applypatch
│   ├── pre-auto-gc
│   ├── pre-commit
│   ├── pre-merge-commit
│   ├── pre-push
│   ├── pre-rebase
│   └── prepare-commit-msg
└── pre-commit

Bước 3: Cấu hình Pre-Commit Hook

Chỉnh sửa file .husky/pre-commit để chạy lint-staged. Thay thế nội dung của nó bằng:

#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npx lint-staged

Điều này làm gì:

  • Shebang (#!/usr/bin/env sh) đảm bảo script chạy trong shell tuân thủ POSIX.
  • Dòng . "$(dirname ...)" nguồn script trợ giúp của Husky.
  • npx lint-staged kích hoạt lint-staged để xử lý các file đã được staged.

Bước 4: Cấu hình Lint-Staged

Thêm cấu hình lint-staged vào package.json của bạn:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": [
      "eslint --fix",
      "prettier --write"
    ]
  }
}

Ngoài ra, bạn có thể tạo file lint-staged.config.js riêng biệt:

module.exports = {
  "src/**/*.{js,jsx,ts,tsx}": [
    "eslint --fix",
    "git add"
  ]
};

Giải thích cấu hình:

  • "*.{js,jsx,ts,tsx}": Nhắm vào các file JavaScript, JSX, TypeScript và TSX đã được staged để commit.
  • "eslint --fix": Chạy ESLint với tự động sửa lỗi trên các file đó.
  • "prettier --write": Định dạng các file với Prettier.

Các tasks chạy tuần tự, vì vậy việc định dạng Prettier diễn ra sau khi ESLint sửa lỗi. Nếu bất kỳ task nào thất bại (ví dụ: lỗi linting không thể sửa), commit sẽ bị hủy bỏ.

Bước 5: Kiểm tra thiết lập

  1. Thực hiện một số thay đổi đối với file .js hoặc .tsx (ví dụ: thêm định dạng không nhất quán hoặc lỗi linting).
// src/app/about/page.tsx
export default function About() {
      let x = 10
  console.log(x)

  return (
    <div className="">
      <h1 className="">About</h1>
    </div>
  )
}
  1. Stage các thay đổi:
    git add .
    
  2. Thử commit:
    git commit -m "Test Husky and lint-staged"
    

Husky sẽ kích hoạt lint-staged, cái mà:

  • Chạy ESLint để sửa lỗi linting.
  • Chạy Prettier để định dạng code.
  • Cập nhật các file đã được staged với các sửa lỗi.
  • Cho phép commit tiếp tục nếu mọi thứ đều qua, hoặc hủy bỏ nếu có lỗi không thể sửa.

Thực hiện kiểm tra cho trường hợp failed linting và commit bị huỷ bỏ:

// src/app/about/page.tsx
export default function About() {
    let x = 10

  return (
    <div className="">
      <h1 className="">About</h1>
    </div>
  )
}
  • 'x' is declared but its value is never read

Bạn sẽ thấy lỗi:

error  'x' is assigned a value but never used  @typescript-eslint/no-unused-vars

husky - pre-commit script failed (code 1)

và commit sẽ bị hủy bỏ.

Bước 6: Nâng cao quy trình làm việc của bạn (Tùy chọn)

Thêm nhiều loại file hơn

Nếu dự án của bạn bao gồm các file CSS, Markdown hoặc JSON, hãy mở rộng cấu hình lint-staged:

{
  "lint-staged": {
    "*.{js,jsx,ts,tsx}": ["eslint --fix", "prettier --write"],
    "*.{css,md,json}": ["prettier --write"]
  }
}

Tích hợp với các scripts hiện có

Nếu bạn có các npm scripts như lintformat (ví dụ: eslint . hoặc prettier --write "**/*"), bạn có thể đồng bộ lint-staged với chúng. Tuy nhiên, lint-staged đã giới hạn phạm vi cho các file đã được staged, vì vậy hãy giữ cho nó đơn giản và có mục tiêu.

Bỏ qua Hooks khi cần thiết

Để bỏ qua pre-commit hook tạm thời:

git commit --no-verify -m "Quick commit"

Sử dụng điều này một cách tiết kiệm, vì nó bỏ qua tất cả các kiểm tra!

Khắc phục sự cố

  • Husky không chạy: Đảm bảo repository Git của bạn đã được khởi tạo (git init) và script prepare có trong package.json. Chạy npm run prepare thủ công để cài đặt lại hooks nếu cần.
  • Vấn đề về quyền: Nếu hook không thể thực thi, chạy:
    chmod +x .husky/pre-commit
    
  • Lint-Staged thất bại một cách im lặng: Kiểm tra cấu hình ESLint/Prettier của bạn để tìm lỗi và đảm bảo các phần mở rộng file trong lint-staged khớp với dự án của bạn.

Lợi ích của thiết lập này

  • Hiệu quả: Chỉ xử lý các file đã được staged, không phải toàn bộ codebase.
  • Nhất quán: Áp dụng các quy tắc linting và formatting trước khi code đến repository.
  • Team work: Hoạt động ngay lập tức cho tất cả developers sau npm install.
  • Tích hợp CI/CD: Giảm bớt gánh nặng cho tích hợp liên tục bằng cách bắt lỗi cục bộ.

Kết luận

Với Husky và lint-staged, dự án NextJS/React của bạn giờ đây có một người gác cổng mạnh mẽ cho chất lượng code. Kết hợp điều này với một thiết lập ESLint và Prettier vững chắc sẽ giúp bạn tiết kiệm thời gian trong các vấn đề linting, formatting và tạo ra một quy trình làm việc mạnh mẽ giúp tăng cường chất lượng và tính nhất quán của mã.

Hãy thử nó, điều chỉnh cấu hình lint-staged để phù hợp với nhu cầu của bạn và tận hưởng các commit sạch hơn!