Tailwind CSSのクラスを自動整理! eslint plugin tailwindcss

投稿日
Tailwind CSSのクラスを自動整理! eslint plugin tailwindcss

以前 Tailwind CSS を自動してくれるフォーマットしてくれるPrettierのプラグイン prettier-plugin-tailwindcss について記載しました。


それに近い機能を持つESLintのプラグイン eslint-plugin-tailwindcss を発見したため備忘録も兼ねて記載していきます。





先に結論としましては

prettier-plugin-tailwindcss上位互換のような形で使用が可能です!



↑の動画のように prettier-plugin-tailwindcss のようにソートしてくれるのはもちろん

  • 重複した値( rounded )を自動削除
  • px-2 py-2 のようなまとめられるものを自動で p-2 にまとめる
  • mt-22 のような存在しない値に警告を表示

といったことが実現出来ます

検証した環境

1 eslint 8.57.0
2 eslint-plugin-tailwindcss 3.15.1
3 next 14.1.3

インストールと設定

npm i -D eslint-plugin-tailwindcss

.eslintrc.js
module.exports = {
  extends: ["plugin:tailwindcss/recommended"],
};

これだけで設定は完了していて、tailwind関連のルールが適用されます!





例えば

<div className="py-2 px-2 mt-22 rounded bg-blue-500 rounded">eslint plugin tailwindcss</div>

↑ のように記載してlintを実行すると

$ npm run lint
./src/components/Sample.tsx
11:12  Warning: Invalid Tailwind CSS classnames order  tailwindcss/classnames-order
11:12  Warning: Classnames 'py-2, px-2' could be replaced by the 'p-2' shorthand!  tailwindcss/enforces-shorthand
11:12  Warning: Classnames 'rounded, rounded' could be replaced by the 'rounded' shorthand!  tailwindcss/enforces-shorthand
11:12  Warning: Classname 'mt-22' is not a Tailwind CSS class!  tailwindcss/no-custom-classname

このように

  • tailwindの順番が正しくない
  • py-2 px-2p-2 にまとめられる
  • rounded roundedrounded にまとめられる(重複チェック)
  • mt-22 というクラス名はtailwindに存在しない

といった警告を表示してくれるようになっています





便利な点として eslint --fix を実行すると

npx eslint --fix .

並び順修正・重複チェック・短縮した書き方等を自動的に行ってくれます!

// --fix 実行前
<div className="py-2 px-2 mt-22 rounded bg-blue-500 rounded">eslint plugin tailwindcss</div>
 
// --fix 実行後
<div className="mt-22 rounded bg-blue-500 p-2">eslint plugin tailwindcss</div>

IDEの設定

保存した際に eslint --fix が実行されるようにしていきます、DX爆上がり設定です💪

VS Code

動作する事は確認したものの、

普段IntelliJ IDEAを使っているので自信が持てない部分ありです 🙏



VS Code用のプラグインを追加


ESLint

VS CodeのESLint用プラグイン


.setting.jsonの設定を更新

.setting.json
{
    "editor.codeActionsOnSave": {
        "source.fixAll.eslint": true
    },
    "editor.formatOnSave": true,
    "[typescript]": {
        "editor.formatOnSave": false
    }
}

参考にさせていただいたページ曰く

“editor.formatOnSave”をfalseに設定するとESLintのfixが対象でないファイルのフォーマットが行われないため、ESLintでfixを実行するファイルのみ”editor.formatOnSave”をfalseにしましょう。


【VSCode】ESLint(fixあり/fixなし)とPrettierを保存時に走らせる #VSCode - Qiitaより転記

とのことですmm



Jet Brains系

設定ページから行います



言語 & フレームワーク > JavaScript > コード品質ツール > ESLint

JetBrain系のESLintの設定
  • 自動 ESLint 構成を選択
  • 次のファイルに実行: 必要なファイルを指定
    • ex: **/*.{js,ts,jsx,tsx,vue}
  • 保存時に eslint —fix を実行に✓




ここまで設定すると

保存するだけでいい感じにtailwindのクラス名が整うようになりました!

eslint-plugin-tailwindcssのルール

内包しているルール

計8つのルールがワンパッケージになっています

ルール名説明
classnames-order一貫性のためにクラス名を順序付けし、マージコンフリクトを少し解決しやすくします。
enforces-negative-arbitrary-values負の任意の値のクラス名を使用する場合は、負のクラス名なしで使用してください。
例:-top-[5px]top-[-5px] になるべきです。
enforces-shorthand可能であれば、複数のクラス名を省略形にマージします。
例:mx-5 my-5m-5 になるべきです。
migration-from-tailwind-2Tailwind CSS v2 から v3 への簡単なアップグレードのためのものです。
警告:現時点では、migration-from-tailwind-2 からの警告を表示したい場合は、一時的に no-custom-classname ルールをオフにする必要があります。
no-arbitrary-valueクラス名で任意の値を使用することを禁止します(デフォルトではオフになっています)。
no-custom-classnameTailwind CSS からのクラス名と whitelist オプションからの値のみを許可します。
no-contradicting-classnamep-2 p-3 のように、同じバリアントに対して同じプロパティを複数回対象とする異なる Tailwind CSS クラス名を避けます。
no-unnecessary-arbitrary-valuem-[1.25rem] をその設定に基づくクラス名を m-5 に置き換えます。

plugin:tailwindcss/recommended の設定

extends: ["plugin:tailwindcss/recommended"], と指定した recommended のルール設定は以下のようになっています

rules: {
  'tailwindcss/classnames-order': 'warn',
  'tailwindcss/enforces-negative-arbitrary-values': 'warn',
  'tailwindcss/enforces-shorthand': 'warn',
  'tailwindcss/migration-from-tailwind-2': 'warn',
  'tailwindcss/no-arbitrary-value': 'off',
  'tailwindcss/no-custom-classname': 'warn',
  'tailwindcss/no-contradicting-classname': 'error',
  'tailwindcss/no-unnecessary-arbitrary-value': 'warn',
},

https://github.com/francoismassart/eslint-plugin-tailwindcss/blob/master/lib/index.js#L32-L41

プロフィール画像
Yuki Takara
都内でフリーランスのエンジニアをやってます。フロントとアプリ開発メインに幅広くやってます。