Tại sao dùng ESLint
Hiện tại không có bất cứ một đối thủ nào xứng tầm với ESLint, nó là dự án đã và đang được bảo trì bởi cộng đồng rất rộng lớn. Hầu hết các chương trình viết code đều hỗ trợ, chúng ta sẽ không gặp khó khăn trong việc sử dụng nó với VSCode, Vim, Emac, WebStorm, Sublime, Atom,…
Vì lẽ đó thì tại sao lại bỏ phí được gói ngon nghẻ thế nhỉ ^^
Cài đặt ESLint
Giống như bất kỳ package nào khác, ESLint có thể được cài đặt ở 2 mức:
- Một là global, cài luôn vào máy
npm -g
- Và hai là đi theo từng project
Việc cài đặt ESLint ở mức global khá là hợp lý vì chúng ta muốn dùng nó ở mọi project. Tuy nhiên cũng hợp lý nếu cài riêng trên từng project nếu bạn đang cần các yếu tố :
- Các phiên bản ESLint khác nhau trên từng dự án
- Công khai bạn phụ thuộc vào ESLint cho project đó
- Đồng nghiệp và các công cụ tự động (như mấy thằng CI) có thể cài đặt ESlint như những package khác.
Cài đặt ESLint trong thư mục project
1 2 | npm i eslint --save-dev |
Chạy ESLint trong project
1 2 | npx eslint |
Để tạo một shortcut cho câu lệnh chạy eslint. Bên trong file package.json
thêm dòng sau:
1 2 3 4 | <span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span><span class="token operator">:</span> <span class="token string">"eslint ."</span> <span class="token punctuation">}</span> |
Tham số . cho phép chạy ESLint bên trong thư mục hiện tại, chúng ta chạy lệnh thông qua shortcut
1 2 | npm run lint |
File cài đặt của ESLint
Có thể đặt file cài đặt ESLint ở nhiều vị trí. Nếu không có nhu cầu quá đặt biệt, 1 file duy nhất ở thư mục ngoài cùng ( root ) là đủ.
ESLint cho phép sử dụng nhiều kiểu file:
- Javascript
- JSON
- YAML
Xài YAML trong ví dụ này. Tạo file tên.eslintrc.yaml
, cái này nếu bạn chạy eslint init trong thư mục src/
của dự án nó sẽ hỏi bạn có muốn tạo không, nó tạo luôn cho.
1 2 | eslint <span class="token operator">--</span>init |
Nếu muốn thêm logic bằng code, bạn cần dùng kiểu javascript nhen
Điều cần quan tâm trước hết là thông báo cho ESLint chúng ta đang viết ngôn ngữ gì, phiên bản nào, môi trường mà code sẽ chạy. Nếu không có các thông tin, ESLint sẽ không chạy được.
1 2 3 4 5 | parserOptions<span class="token operator">:</span> ecmaVersion<span class="token operator">:</span> <span class="token number">6</span> env<span class="token operator">:</span> node<span class="token operator">:</span> <span class="token boolean">true</span> |
Javascript thuần
Với project là javascript thuần, toàn bộ file là .js, có thể tự định nghĩa từ đầu hết, nhưng như vậy khá mất thời gian, khó bảo trì, chưa chắc chuẩn vì nó phụ thuộc vào sự hiểu biết của bạn về javascript
Rất nhiều các công ty lớn như Google, Airbnb, Facebook bỏ ra cả tỉ tỉ thời gian để bảo trì và cập nhập mấy cài đặt này
Sử dụng cài đặt vạn người yêu thích, Airbnb
1 2 | npx install<span class="token operator">-</span>peerdeps <span class="token operator">--</span>dev eslint<span class="token operator">-</span>config<span class="token operator">-</span>airbnb<span class="token operator">-</span>base |
Các bài viết trên mạng sẽ kêu bạn cài eslint-config-airbnb
, nó có bao gồm luôn phần cài đặt cho React, React Hooks, … . Không cần thiết trong trường hợp project chỉ là javascript thông thường.
Để ý chúng ta KHÔNG dùng npm
để cài đặt, mà dùng npx install-peerdeps
. Nó sẽ cài luôn mấy package nào mà eslint-config-airbnb-base
phụ thuộc. Trường hợp sử dụng ESLint chúng ta sẽ gặp hoài, vì hầu như nó đều phụ thuộc một vài package khác.
Cài xong, khai báo sẽ kế thừa bộ cài đặt của Airbnb
1 2 3 | <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb<span class="token operator">-</span>base |
Những thiết đặt của airbnb có thể nói là rất phổ biến và được tin dùng bởi nhiều dự án lớn nhỏ khác nhau. Chúng ta có thể yên tâm sử dụng nó mà không cần thay đổi gì nhiều.
Tổng kết
1 2 3 4 5 6 | <span class="token string">"devDependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span><span class="token operator">:</span> <span class="token string">"^6.1.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-base"</span><span class="token operator">:</span> <span class="token string">"^14.0.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span><span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
1 2 3 4 5 6 7 8 9 10 | parserOptions<span class="token operator">:</span> ecmaVersion<span class="token operator">:</span> <span class="token number">6</span> env<span class="token operator">:</span> node<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> eslint<span class="token operator">:</span>recommended <span class="token operator">-</span> airbnb<span class="token operator">-</span>base |
Thiết đặt TypeScript
Vấn đề chính của TypeScript là ESLint không thể tự động mà parse được, chúng ta phải thêm một parser @typescript-eslint/parser
.
Cài đặt
1 2 | npm install @typescript-eslint/parser --save-dev |
Parse làm nhiệm vụ đọc cài file input và tạo ra một phiên bản mà ESLint hiểu được.
Khai báo dùng parser này
1 2 | parser<span class="token operator">:</span> <span class="token string">"@typescript-eslint/parser"</span> |
Đồng thời cập nhập luôn package.json
và báo với ESLint đừng kiểm tra file .js
mà kiểm tra file .ts
1 2 3 4 | <span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span><span class="token operator">:</span> <span class="token string">"eslint . --ext .ts"</span> <span class="token punctuation">}</span> |
Tương tự như javascript, chúng ta dùng bộ thiết đặt của Airbnb
1 2 3 | npx install<span class="token operator">-</span>peerdeps <span class="token operator">--</span>dev eslint<span class="token operator">-</span>config<span class="token operator">-</span>airbnb<span class="token operator">-</span>typescript npm i eslint<span class="token operator">-</span>plugin<span class="token operator">-</span><span class="token keyword">import</span> <span class="token operator">--</span>save<span class="token operator">-</span>dev |
eslint-plugin-import
phải được cài đặt riêng, thủ công, không rõ lý do tại sao luôn.
Cập nhập lại file config ESLint
1 2 3 4 | <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb<span class="token operator">-</span>typescript<span class="token operator">/</span>base <span class="token operator">-</span> plugin<span class="token operator">:</span>@typescript<span class="token operator">-</span>eslint<span class="token operator">/</span>recommended |
Bạn có thể thắc mắc, tại sao chưa cài @typescript-eslint
mà có thể sử dụng, thật ra lúc cài eslint-config-airbnb-typescript
chúng ta đã cài luôn nó bằng npx install-peerdeps
Có thể rule khác nữa có thể tham khảo trực tiếp từ tài liệu trên github
Cuối cùng, bạn sẽ thấy có rất nhiều bài viết trên mạng, chỉ bạn thiết đặt
1 2 3 | plugins<span class="token operator">:</span> <span class="token operator">-</span> <span class="token string">"@typescript-eslint"</span> |
Nếu không sử dụng các thiết ESLint được đề nghị, cái này không cần thiết. Lý do là Airbnb đã bật luôn các rule như vậy.
Tổng kết
package.json
1 2 3 4 5 6 7 8 | <span class="token string">"devDependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"@typescript-eslint/eslint-plugin"</span><span class="token operator">:</span> <span class="token string">"^2.17.0"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token string">"@typescript-eslint/parser"</span><span class="token operator">:</span> <span class="token string">"^2.17.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint"</span><span class="token operator">:</span> <span class="token string">"^6.8.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-typescript"</span><span class="token operator">:</span> <span class="token string">"^6.3.1"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span><span class="token operator">:</span> <span class="token string">"^2.20.0"</span> <span class="token punctuation">}</span> |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 | parserOptions<span class="token operator">:</span> ecmaVersion<span class="token operator">:</span> <span class="token number">6</span> env<span class="token operator">:</span> node<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb<span class="token operator">-</span>typescript<span class="token operator">/</span>base <span class="token operator">-</span> plugin<span class="token operator">:</span>@typescript<span class="token operator">-</span>eslint<span class="token operator">/</span>recommended |
Thiết đặt cho React
Thêm các thiết đặt ESLint cho React vô cùng đơn giản, mọi thứ đã có Airbnb
lo.
Một trong những sai lầm phổ biến là cho rằng viết như bên dưới sẽ bật hỗ trợ React
.eslintrc.yaml
1 2 3 4 | parserOptions<span class="token operator">:</span> ecmaFeatures<span class="token operator">:</span> jsx<span class="token operator">:</span> <span class="token boolean">true</span> |
React sử dụng JSX, nhưng theo cách mà ESLint không thể hiểu nổi. Để React và ESLint nói chuyện được với nhau, chúng ta phải sử dụng eslint-plugin-react
React Javascript
Cài đặt package
1 2 | npx install-peerdeps --dev eslint-config-airbnb |
.eslintrc.yaml
1 2 3 4 5 | <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb env<span class="token operator">:</span> browser<span class="token operator">:</span> <span class="token boolean">true</span> |
package.json
1 2 3 4 | <span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span><span class="token operator">:</span> <span class="token string">"eslint . --ext .js,.jsx"</span> <span class="token punctuation">}</span> |
Nếu có sử dụng React Hook, bạn nên thêm phần cài đặt sau (có bỏ qua việc kiểm tra accessibility)
.eslintrc.yaml
1 2 3 4 5 | <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb<span class="token operator">-</span>base <span class="token operator">-</span> airbnb<span class="token operator">/</span>rules<span class="token operator">/</span>react <span class="token operator">-</span> airbnb<span class="token operator">/</span>hooks |
Tổng kết
package.json
1 2 3 4 5 6 7 8 9 | <span class="token string">"devDependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span><span class="token operator">:</span> <span class="token string">"^6.1.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb"</span><span class="token operator">:</span> <span class="token string">"^18.0.1"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span><span class="token operator">:</span> <span class="token string">"^2.20.0"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token string">"eslint-plugin-jsx-a11y"</span><span class="token operator">:</span> <span class="token string">"^6.2.3"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token string">"eslint-plugin-react"</span><span class="token operator">:</span> <span class="token string">"^7.18.0"</span><span class="token punctuation">,</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token string">"eslint-plugin-react-hooks"</span><span class="token operator">:</span> <span class="token string">"^1.7.0"</span> <span class="token punctuation">(</span>peer dependency<span class="token punctuation">)</span> <span class="token punctuation">}</span> |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 | parserOptions<span class="token operator">:</span> ecmaVersion<span class="token operator">:</span> <span class="token number">6</span> env<span class="token operator">:</span> browser<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb <span class="token operator">-</span> airbnb<span class="token operator">/</span>hooks rules<span class="token operator">:</span> react<span class="token operator">/</span>react<span class="token operator">-</span><span class="token keyword">in</span><span class="token operator">-</span>jsx<span class="token operator">-</span>scope<span class="token operator">:</span> off |
Rảnh ngồi xem toàn bộ này nha
React TypeScript
Nếu dùng TypeScript, chúng ta không thể cài theo kiểu npx install-peerdeps
, mà phải cài độc lập
1 2 3 4 5 6 7 8 | npm install eslint<span class="token operator">-</span>config<span class="token operator">-</span>airbnb<span class="token operator">-</span>typescript eslint<span class="token operator">-</span>plugin<span class="token operator">-</span><span class="token keyword">import</span> eslint<span class="token operator">-</span>plugin<span class="token operator">-</span>jsx<span class="token operator">-</span>a11y eslint<span class="token operator">-</span>plugin<span class="token operator">-</span>react eslint<span class="token operator">-</span>plugin<span class="token operator">-</span>react<span class="token operator">-</span>hooks @typescript<span class="token operator">-</span>eslint<span class="token operator">/</span>eslint<span class="token operator">-</span>plugin <span class="token operator">--</span>save<span class="token operator">-</span>dev |
.eslintrc.yaml
1 2 3 4 5 6 7 8 9 10 11 12 13 14 | parserOptions<span class="token operator">:</span> ecmaVersion<span class="token operator">:</span> <span class="token number">6</span> env<span class="token operator">:</span> browser<span class="token operator">:</span> <span class="token boolean">true</span> <span class="token keyword">extends</span><span class="token operator">:</span> <span class="token operator">-</span> airbnb<span class="token operator">-</span>typescript <span class="token operator">-</span> airbnb<span class="token operator">/</span>hooks <span class="token operator">-</span> plugin<span class="token operator">:</span>@typescript<span class="token operator">-</span>eslint<span class="token operator">/</span>recommended rules<span class="token operator">:</span> react<span class="token operator">/</span>react<span class="token operator">-</span><span class="token keyword">in</span><span class="token operator">-</span>jsx<span class="token operator">-</span>scope<span class="token operator">:</span> off |
package.json
1 2 3 4 5 6 7 8 9 10 11 12 13 | <span class="token string">"devDependencies"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"eslint"</span><span class="token operator">:</span> <span class="token string">"^6.8.0"</span><span class="token punctuation">,</span> <span class="token string">"@typescript-eslint/eslint-plugin"</span><span class="token operator">:</span> <span class="token string">"^2.17.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-config-airbnb-typescript"</span><span class="token operator">:</span> <span class="token string">"^6.3.1"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-import"</span><span class="token operator">:</span> <span class="token string">"^2.20.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-jsx-a11y"</span><span class="token operator">:</span> <span class="token string">"^6.2.3"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-react"</span><span class="token operator">:</span> <span class="token string">"^7.18.0"</span><span class="token punctuation">,</span> <span class="token string">"eslint-plugin-react-hooks"</span><span class="token operator">:</span> <span class="token string">"^2.3.0"</span> <span class="token punctuation">}</span><span class="token punctuation">,</span> <span class="token string">"scripts"</span><span class="token operator">:</span> <span class="token punctuation">{</span> <span class="token string">"lint"</span><span class="token operator">:</span> <span class="token string">"eslint . --ext .ts,.tsx"</span> <span class="token punctuation">}</span> |
Cài đặt cho VSCode
VSCode đã có plugin khá thần thánh để hỗ trợ ESLint. Các thiết đặt yêu thích của mình
Tự động chạy lint khi save
1 2 | <span class="token string">"eslint.run"</span><span class="token operator">:</span> <span class="token string">"onSave"</span> |
VSCode sẽ kiểm tra trên JS, JSX, TS, TSX
1 2 3 4 5 6 7 | <span class="token string">"eslint.validate"</span><span class="token operator">:</span> <span class="token punctuation">[</span> <span class="token string">"javascript"</span><span class="token punctuation">,</span> <span class="token string">"javascriptreact"</span><span class="token punctuation">,</span> <span class="token string">"typescript"</span><span class="token punctuation">,</span> <span class="token string">"typescriptreact"</span> <span class="token punctuation">]</span> |
Chọn kiểu nháy đơn
1 2 3 | <span class="token string">"javascript.preferences.quoteStyle"</span><span class="token operator">:</span> <span class="token string">"single"</span><span class="token punctuation">,</span> <span class="token string">"typescript.preferences.quoteStyle"</span><span class="token operator">:</span> <span class="token string">"single"</span><span class="token punctuation">,</span> |
Tự động cập nhập vị trí file
1 2 3 | <span class="token string">"javascript.updateImportsOnFileMove.enabled"</span><span class="token operator">:</span> <span class="token string">"always"</span><span class="token punctuation">,</span> <span class="token string">"typescript.updateImportsOnFileMove.enabled"</span><span class="token operator">:</span> <span class="token string">"always"</span><span class="token punctuation">,</span> |
Source nè: https://blog.geographer.fr/eslint-guide