見出し画像

Biome が Prettier + ESLint の時代に終わりを告げる

多くの開発者は、Prettier + ESLint を長年使用してきたと思います。その歴史に終止符を打ち、時代を変えようとしているのが「Biome」です。

Biome は、フォーマッタ、リンター、インポート整理を備えた 1 つのツールチェーンであり、Rust で構築されているためとても高速です。

最新の Next.js AI Chatbot Template でも Biome が導入されました。これから多くのプロジェクトで導入が加速していく予感です。

私もずっと気になっていたこの Biome をついに導入しました。設定や使い方についてまとめましたので、興味のある方は是非ご一読ください。


VS Code 拡張機能のインストール

拡張機能の導入により、ファイル保存時のフォーマット・修正を有効にすることが可能になります。Biome を最大限に活用するためには必須です。

VS Code / Cursor の拡張機能検索で、Biome を検索してインストールします。

ユーザー設定ファイルの編集

Cmd/Ctrl + Shift + P でコマンドパレットを開いて、「Open User Settings (JSON)」を選択します。開いた settings.json ファイルを直接編集します。

デフォルトフォーマッタ

現在のバージョン(Biome 1.9.4)の言語サポートは次の通り:

Biome 1.9.4 Supported Languages: JavaScript, TypeScript, JSX, TSX, JSON, JSONC, CSS, GraphQL

これに基づいて、次のように設定します:

{
  "editor.defaultFormatter": "biomejs.biome",
  "[html]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[yaml]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[markdown]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[graphql]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[tailwindcss]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  }
}

サポートしていない言語は Prettier に任せます。

GraphQL は Biome v1.9 からサポート言語として扱われるようになりました。が、なぜか GraphQL ファイルのフォーマットが機能しません。なので Prettier を指定しています。

CSS も同様に v1.9 からデフォルトで有効になりました。通常の CSS ファイルは機能しますが、Tailwind CSS ファイルはフォーマットが効きません。上記のようにするか、"[css]" を追加して CSS は Prettier で統一するものありです。

逆に、Prettier をメインに据えて、特定の言語のみ Biome を指定する方法でも良いと思います:

{
  "editor.defaultFormatter": "esbenp.prettier-vscode",
  "[javascript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[javascriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[typescriptreact]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[json]": {
    "editor.defaultFormatter": "biomejs.biome"
  },
  "[jsonc]": {
    "editor.defaultFormatter": "biomejs.biome"
  }
}

現状ではこの方が安定感あるかも。

保存時にフォーマットする

Prettier を使用している方の多くはすでに設定しているかもしれません。次の設定を有効にします:

{
  "editor.formatOnSave": true
}

保存時に修正する

リンターエラーがある場合に、自動で修正してくれます。次の設定を追加します:

{
  "editor.codeActionsOnSave": {
    "quickfix.biome": "explicit"
  }
}

自動で修正してほしくない場合は、上記の設定を削除するか、"never" を指定して無効にできます:

{
  "editor.codeActionsOnSave": {
    "quickfix.biome": "never"
  }
}

インポートをソートする(実験的)

まだ実験的機能ですが、それなりに機能します。有効にするには、次の設定を追加します:

{
  "editor.codeActionsOnSave":{
    "source.organizeImports.biome": "explicit"
  }
}

ユーザーから遠いモジュールは上、近いモジュールは下に配置されます。詳細はドキュメントの「Imports Sorting」をご確認ください。

例えば:

import Link from 'next/link';
import { Input } from '../ui/input';
import SubmitButton from './submit-button';
import { initialFormState } from '@/lib/initial-form-state';
import {
  useState,
  useEffect,
  useCallback,
  useMemo,
  useRef,
  useContext,
} from "react";

これがこうなる↓

import { initialFormState } from '@/lib/initial-form-state';
import Link from 'next/link';
import {
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';
import { Input } from '../ui/input';
import SubmitButton from './submit-button';

うーん、「@」を使用した相対パスのインポートが一番上に配置されてしまうのがちょっと気持ち悪い。エイリアスを使用する場合は、統一してグループ分けした方が良さそうです:

import Link from 'next/link';
import {
  useCallback,
  useContext,
  useEffect,
  useMemo,
  useRef,
  useState,
} from 'react';

import SubmitButton from '@/components/button/submit-button';
import { Input } from '@/components/ui/input';
import { initialFormState } from '@/lib/initial-form-state';

この方がスッキリして見えますね。このようにグループ分けすると、グループごとにソートが機能します。

自動ソートが思い通りにいかなくて気持ち悪い場合は、保存時の自動ソートを無効にして手動で実行すると良いかもしれません。Shift + Option/Alt + O もしくは、コマンドパレットの「Organize Imports」で実行できます。これでまず全体をソートして、あとは部分的に手直しして保存すれば完璧です。

プロジェクトでの設定

Biome をインストールする

Biome をプロジェクトにインストールします:

npm install --save-dev --save-exact @biomejs/biome

Biome は、正確なバージョンを固定することを推奨しているので、--save-exact が指定されています。

設定ファイルを作成する

Biome のデフォルト設定で問題ない場合は、設定ファイルを作成する必要はありません。動作をカスタマイズしたい場合、チームで同じ構成を使用したい場合に必要になります。

biome.json もしくは biome.jsonc で作成できます。コマンドは以下の通り:

npx @biomejs/biome init
npx @biomejs/biome init --jsonc

設定は好みやプロジェクトによって異なると思いますが、私が使用している設定をもとに、以下で簡単に説明します:

{
  "$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "files": {
    "ignoreUnknown": false,
    "ignore": []
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space"
  },
  "organizeImports": {
    "enabled": true
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true,
      "correctness": {
        "noUnusedImports": "warn"
      }
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single"
    }
  }
}

1 . vcs(バージョン コントロール システム)

enabled と useIgnoreFile を有効にすることで、Ignore ファイルにリストされているすべてのファイルとディレクトリを無視できるようになります。

2 . files.ignore

この配列内に指定したパターンに一致するファイルとフォルダを無視できます。ここでは指定していません。

3 . formatter.indentStyle

デフォルトは "tab" ですが、個人的には "space" 派です。

4 . organizeImports

インポートのソートです。デフォルトで有効になっています。

5-1 . linter.rules.recommended

リンターの全ての推奨ルールが有効になります。

5-2 . linter.rules.correctness.noUnusedImports

未使用のインポートをマークしてくれます。リンターのルールは "info"、"warn"、"error" から重大度を選択できます。未使用インポートは "warn" が妥当でしょう。VS Code / Cursor で保存時の自動修正を有効にしている場合は、未使用のインポートは自動で削除されます。

リンターのルールの詳細は、Biome ドキュメントの「Rules」をご覧ください。

6-1 . javascript

JavaScript / TypeScript 共通の設定です。

6-2 . javascript.formatter.quoteStyle

文字列に使用する引用符のタイプ。個人的には "single" が好きです。デフォルトは "double"。

設定ファイルの詳細は、Biome ドキュメントの「Configuration」をご覧ください。


以上で一通りの設定は完了です。Biome のフォーマットやリンティングが機能するか試してみてください。

CLI

Biome 公式 CLI が用意されています。よく使う 3 つを記載しておきます。

src ディレクトリ内のファイルに対してフォーマッタを実行する:

npx @biomejs/biome format --write ./src

src ディレクトリ内のファイルに対してリンターを実行する:

npx @biomejs/biome lint --write ./src

src ディレクトリ内のファイルに対してフォーマッタリンターインポートのソートを実行する:

npx @biomejs/biome check --write ./src

ここでの src ディレクトリは例です。また、フォルダではなく、特定のファイルを指定することもできます。

最後に

Biome いかがでしたでしょうか。

フォーマットに関しては、Biome と Prettier で大きな違いはありませんが、例えば、ネストされた条件(三項)演算子はこうなります:

// Prettier
const result = condition1
  ? condition2
    ? "result1"
    : "result2"
  : condition3
  ? "result3"
  : "result4";

// Biome
const result = condition1
  ? condition2
    ? 'result1'
    : 'result2'
  : condition3
    ? 'result3'
    : 'result4';

引用符は設定の問題なので別として、Biome の方が見やすいですよね。

リンター、インポート整理も完全ではありませんが十分に機能しているので、導入を検討しても良いと思います。ESLint とインポート整理用のプラグインが不要になるのはやはりポイント高いです。

1 年後にはほとんどのプロジェクトで Biome がデフォルトになるのではないでしょうか。頻繁にアップデートが行われているので、今後がさらに楽しみです。

最後までお読みいただき、ありがとうございました。この記事が役に立った場合は、🩷 をいただけると嬉しいです(アカウントをお持ちでない方もできます)。フォローも大歓迎です!ご質問やご意見がございましたら、X/Twitter (@komzweb) に気軽にメッセージをください。

いいなと思ったら応援しよう!