🐶

Biomeについて調べたのでまとめる

2024/11/14に公開

Biomeについて軽く調査をしたので、その内容をまとめたいと思います。
Biome

Biomeとは?

  • Prettierと97%の互換性がある
  • Prettierに比べて35倍程度早い
  • JavaScript、TypeScript、JSX、CSS、 GraphQLのための200以上のルールが用意されたリンターでもある

Biomeとはリンターでもあり、フォーマッターでもあります。

概要

インストール

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

でインストールしたら、

npx @biomejs/biome init

でbiome.jsonファイルを新規作成できます。biome.jsonがBiomeの設定ファイルとなります。

新規作成されたbiome.jsonの中身
{
	"$schema": "https://biomejs.dev/schemas/1.9.4/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"
		}
	}
}

これだけで、recommendedのリントルールが有効になり、フォーマットもしてくれます。ESLint+Prettierを使う際はプラグインをインストールして設定して...などをする必要がありますが、Biomeの設定はとても簡単ですね!

コマンドの例

npx @biomejs/biome format --write <files> でフォーマット

npx @biomejs/biome lint --write <files> でリント

npx @biomejs/biome check --write <files> は複数のツールと一度に実行します

checkは現在は以下を実行します

  • ファイルのformat
  • ファイルのlint
  • インポートの整理

Formatterについて

Biomeは、スタイル関する議論に終止符を打つことを目的とした「opinionated」なformatterです。Prettierと近い哲学を持っており、いくつかのオプションのみをサポートしています。些細な議論を防ぐため、新しいオプションを意図的に追加しないようにしているそうです。

Prettierの哲学とは?

Option Philosophy

Prettier has a few options because of history. But we won’t add more of them.
By far the biggest reason for adopting Prettier is to stop all the ongoing debates over styles.

オプションを増やせば結局はPrettierのどのオプションを使えば良いのか?という議論を引き起こすことになってしまうため、Prettierはオプションはいくつか用意されているが、これ以上増やすことはないらしいです。

Biomeがサポートする、言語に依存しないオプションは以下の通りです。

  • インデントスタイル (デフォルト: tab): インデントにはスペースまたはタブを使用します。
  • タブ幅 (デフォルト: 2): インデントレベルごとのスペースの数です。
  • 行幅 (デフォルト: 80): Biomeがコードを折り返す列幅です。
フォーマットのデフォルト設定
{
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "ignore": [],
    "attributePosition": "auto",
    "indentStyle": "tab",
    "indentWidth": 2,
    "lineEnding": "lf",
    "lineWidth": 80
  },
  "javascript": {
    "formatter": {
      "arrowParentheses":"always",
      "bracketSameLine": false,
      "bracketSpacing": true,
      "jsxQuoteStyle": "double",
      "quoteProperties": "asNeeded",
      "semicolons": "always",
      "trailingCommas": "all"
    }
  },
  "json": {
    "formatter": {
      "trailingCommas": "none"
    }
  }
}

以下のコメントを入れることでフォーマットを無効にすることができます。

// biome-ignore format: <説明文>

Linterについて

check コマンド

biome check --write ./src

コマンドでコードの意味を変更しないことが保証されている安全な修正ができます。

biome check --write --unsafe ./src

コマンドでコードの意味を変更する可能性のある安全ではない修正ができます。

コメントを追加してコードを無視させる

以下のようにコメントをすることでコードを無視させることができます。

// biome-ignore lint: reason
debugger;
// biome-ignore lint/suspicious/noDebugger: reason
debugger;

ここで

  • biome-ignore:抑制コメントの開始を表します
  • lint:はlinterを抑制することを表します
  • /suspicious/noDebugger:任意 抑制したいルールのグループと名前を表します
  • <explanation>:ルールが無効になっている理由を表します

リントルールの有効化

recommendedのリントルールはデフォルトで有効になっていますが、もちろん設定で他のリントルールを有効化することもできます。

{
  "linter": {
    "enabled": true,
    "rules": {
      "style": {
        "useBlockStatements": "error",
        "useShorthandArrayType": "error",
        "noShoutyConstants": "warn"
      }
    }
  }
}

リントルールの無効化

"off"を設定することで、リントルールを無効化することもできます

{
  "linter": {
    "enabled": true,
    "rules": {
      "suspicious": {
        "noCommentText": "off"
      },
      "style": {
        "noUnusedTemplateLiteral": "off"
      }
    }
  }
}

Biome では TypeScript の型情報を扱うことができないので、型情報が必要なルールについては基本的にサポートしていない。

Biomeではパフォーマンスなどの理由により、TypeScriptの型情報を扱うことができないです。そのため型情報が必要なルールを使いたければESLintなどを併用するなどの必要があります。
また現状ESLintのカスタムルールのような、自分のプロジェクトに合ったルールをカスタムすることもできないみたいです。

import文のソート

  • import文は、“距離” によってソートされます。ユーザーから “遠い” モジュールが上に配置され、ユーザーに “近い” モジュールが下に配置されます。
  • 改行を追加することでimport文をグループに区切ることができます。これによりBiomeは、ソートの対象をグループに属するimport文のみに制限できます。
インポートの例(ドキュメントのコピー)

例えば、次のコードが与えられた場合、

import uncle from "../uncle";
import sibling from "./sibling";
import express from "npm:express";
import imageUrl from "url:./image.png";
import assert from "node:assert";
import aunt from "../aunt";
import { VERSION } from "https://deno.land/std/version.ts";
import { mock, test } from "node:test";
import { expect } from "bun:test";
import { internal } from "#internal";
import { secret } from "/absolute/path";
import React from "react";

次のようにソートされます。

import { expect } from "bun:test";
import assert from "node:assert";
import { mock, test } from "node:test";
import express from "npm:express";
import { VERSION } from "https://deno.land/std/version.ts";
import React from "react";
import { secret } from "/absolute/path";
import { internal } from "#internal";
import aunt from "../aunt";
import uncle from "../uncle";
import sibling from "./sibling";
import imageUrl from "url:./image.png";

このように距離によってソートされます

大きなプロジェクトでのBiomeの使用方法

Biomeの機能をCLIやLSPで使用する場合、ツールは現在の作業ディレクトリから最も近い設定ファイルを参照します。設定ファイルが見つからない場合、Biomeは設定ファイルが見つかるまで、上へ上へとディレクトリを移動します。これにより、プロジェクトやディレクトリごとに異なるオプションを適用することができます。

ドキュメントの例

例えば、backendディレクトリとfrontendディレクトリを含むプロジェクトがあるとすると

app
├── backend
│   ├── biome.json
│   └── package.json
└── frontend
    ├── biome.json
    ├── legacy-app
    │   └── package.json
    └── new-app
        └── package.json

この場合、app/backend/package.jsonからスクリプトを実行すると、Biomeはapp/backend/biome.jsonを設定ファイルとして使用します。

app/frontend/legacy-app/package.jsonまたはapp/frontend/new-app/package.jsonからスクリプトを実行すると、Biomeはapp/frontend/biome.jsonを設定ファイルとして使用します。

また、extendsプロパティを使って、設定を継承することもできます。

biome.json
{
   "extends": ["../../biome.json"], // ここで継承を設定している
   "formatter": {
     "indentStyle": "space"
   }
}

エディタプラグインのインストール

VSCodeやIntelliJなどにプラグインが用意されています。
例えば、VSCodeでプラグインを使うと、以下のことができます。

  • ファイルの保存時やコマンドを実行したときに、formatを実行する。
  • ファイルの静的解析をし、コードの修正を適用する。

エディタプラグインをインストールすることを推奨されています。
詳しくはこちら

導入の事例

Ant Design、Astro、Sentry、daisyUI、Refine、Discord、Pulumi、Label Studio、Spicetify、Apify、Slint、Rspack、FluidFrameworkなど様々なプロジェクトで採用されているらしいです。自分の周りでも、プロジェクトにBiomeを導入したという話を聞いたことがあります。

まとめ

  • Rust製でパフォーマンスが良い
  • ESLint+Prettierに比べて、少ない設定で使える
  • 依存するパッケージが少なくなるので、メンテナンスコストが低い
  • Biomeに任せられるところは任せて、必要に応じてESLintなどを併用することもできる
  • 設定にあまり時間をかけたくないのであればおすすめ

気になった方は是非使ってみてください。

Discussion