🚀

Would you like to use ESLint?にNoと言いたい

2024/10/17に公開

はじめに

新規でNext.jsのアプリを作成するとき、 Would you like to use ESLint? という質問に何と答えていますか?

私はこれにいつも Yes と答えていました。ESLintとPrettierしか知らず、Huskyとlint-stagedの構成も「まあこれを使うものだろう」と思っていました。

しかし、新しいプロジェクトの環境整備を進める中で、BiomeとLefthookというツールの存在に気づきました。使用するツールが4つから2つになるのは嬉しいことですし、設定もシンプルで導入しやすそうだと感じたのです。

本記事では、これらのツールの概要と導入におけるポイントをご紹介します。

Biomeとは?

Biome(バイオーム) は、2023年8月29日にリリースが発表された、新しいリンター兼フォーマッターです。ESLintとPrettierの機能を統合し、シンプルな設定ですぐに導入ができるのが特徴です。

https://biomejs.dev/ja/

主な特徴

  • Prettierと97%の互換性を持ち、Prettierよりも35倍高速
  • Linterとして290以上のルールをサポート
  • 1つのコマンドでfomartとlintを実行可能

設定ファイル(biome.json)の例
formatterとlinterを1つのファイルで設定できるのは新鮮ですね

{
  "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
  "formatter": {
    "enabled": true,
    "indentStyle": "tab"
  },
  "javascript": {
    "formatter": { "quoteStyle": "double" }
  },
  "linter": {
    "enabled": true,
    "rules": { "recommended": true }
  },
  "organizeImports": { "enabled": true },
}

Lefthookとは?

Lefthookは、Gitのフックを管理するもので、開発プロセスの効率化に役立ちます。例えば、コミットやプッシュの前にステージングされたファイルに対してformatやlintを実行できるようになります。

https://github.com/evilmartians/lefthook

主な特徴

  • Goで書かれており高速で、コマンドを並列に実行可能
  • コマンドに渡すファイルや実行を制御可能
  • 依存性のない単一のバイナリで、どのような環境でも動作するシンプルさ

設定ファイル(lefthook.yml)の例
package.json をいじらなくて良いのは嬉しいですね

pre-commit:
  commands:
    frontend-linter:
      run: yarn eslint {staged_files}
    backend-linter:
      run: bundle exec rubocop --force-exclusion {all_files}
    frontend-style:
      files: git diff --name-only HEAD @{push}
      run: yarn stylelint {files}

Biome導入における注意点

Biomeの具体的な導入手順は公式サイトに詳しく書かれています。
https://biomejs.dev/ja/guides/getting-started/

以降では導入における注意点をご紹介します。

initコマンドで作成されるbiome.jsonのインデントスタイル

本記事執筆時点(2024年10月17日)では、 npx @biomejs/biome init によって作成される設定ファイルbiome.jsonの中身は下記の内容でした。

{
  "$schema": "https://biomejs.dev/schemas/1.9.3/schema.json",
  "vcs": {
    "enabled": false,
    "clientKind": "git",
    "useIgnoreFile": false
  },
  "files": {
    "ignoreUnknown": false,
    "ignore": []
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "tab"
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "double"
    }
  }
}

基本的には初期の設定ファイルで事足りることが多いと思いますが、1点注意したい箇所があります。
Biomeではフォーマッターとしてインデントスタイルのデフォルトがtabなのです。多くのプロジェクトではspaceを使うと思いますので、設定変更が必要でしょう。

コマンドオプションの --apply は非推奨に

Biomeに関する記事はすでにいくつかありますが、その多くでは biome format --appply <files> といったコマンド例を記載している記事が大半です。

しかし --apply オプションは非推奨になっているため気をつけましょう。現在は --write コマンドで修正の適用を行うことになっています。

useSortedClassesはフォーマッターではなくリンターとして実装されている

TailwindCSSを使っているプロジェクトではCSSクラスを一貫した順序で並べたいことがあります。

"linter": {
  "rules": {
    "nursery": {
      "useSortedClasses": {
        "level": "warn",
        "options": {
          "attributes": ["classList"],
          "functions": ["clsx", "cva", "tw"]
        }
      }
    }
  }
}

useSortedClassesはCSSクラスをソートするためのものですが、現在はNurseryグループという開発中の機能で、設定ファイルでも明示的なオプトインが必要です。

またuseSortedClassesはリンターのルールとして実装されています。そのためVSCodeなどのアクション(保存)の一部として自動的に適用されることはありません。

CLIコマンドで適用する際も、 biome lint --write --unsafe のように --unsafe オプションを付与する必要があります。

Lefthook導入における注意点

Lefthookの具体的な導入手順はGitHubリポジトリに詳しく書かれています。
https://github.com/evilmartians/lefthook?tab=readme-ov-file#install

筆者の場合は新規プロジェクトでの導入のため躓いた点はありませんでしたが、いくつかポイントをお伝えします。

pre-commitでbiomeを実行する設定例

pre-commit:
  commands:
    check:
      root: "frontend/"
      glob: "*.{js,ts,cjs,mjs,d.cts,d.mts,jsx,tsx,json,jsonc}"
      run: npx @biomejs/biome check --no-errors-on-unmatched --files-ignore-unknown=true {staged_files}

設定ファイルはプロジェクトルートに配置します。
rootオプションにパスを指定することで、実行ディレクトリを指定することができます。

{staged_files}はGitでステージングされたファイルのリストです。globによってマッチしたファイルが対象になります。

コミット前にglobでマッチしたファイルに対して、Biomeでformatとlintのチェックをしています。

pre-commitの部分をpre-pushにすることでプッシュ前に同様のチェックを行うことができます。

glob と --files-ignore-unknown=true は併用しなくても良い

先ほどの設定例では、 glob--files-ignore-unknown=true の両方を使っていますが、実際には併用する必要はありません。 --files-ignore-unknown=true を指定するだけで、Biomeが現在サポートしているファイルのみを対象にできます。 対象ファイルをさらにコントロールしたい場合に glob を使いましょう。

おわりに

いかがでしたでしょうか。Biomeがサポートしていない部分はESLintやPrettierの併用が必要かもしれませんが、プロジェクトによっては Would you like to use ESLint?No と言えるかもしれません。

脳死でESLintを選ぶのではなく、プロジェクトに合わせてリンターやフォーマッターを選定していきたいですね。

chot Inc. tech blog

Discussion