本記事の目的
- Biomeとは何か、何が嬉しいのかを知る
- Vite + React のアプリケーションにBiomeを導入できる
- フォーマッターとリンターのルールをそれぞれ追加できる
Biome とは
Biome (バイオーム)とは、JavaScript・TypeScript などのコードに対して、リンターとフォーマッターを兼ね備えたツールです。
以前は「Rome」と呼ばれていたプロジェクトで、Biome はそれの後継にあたります。
Biome は何が嬉しいのか
リンターとフォーマッターを兼ねている
アプリケーションを作り始める際には、フォーマット(コード整形)とリント(コード品質担保)を担うツールを導入します。最近では、フォーマッターとして Prettier、リンターとして ESLint を使うのが一般的です。
Biome はフォーマッターとリンターを兼ねている為、Biome だけで Prettier と ESLint でやっていたことが実現可能です。
高速
Biome は Rust で実装されていることもあり、高速であることも特徴の1つです。
導入手順
Viteを使用して、Reactのアプリケーションが起動されていることを前提とします。
npm create vite@latest
アプリケーションに Biome をインストールします。
npm i -D -E @biomejs/biome
インストールが完了したら、以下のコマンドを実行して設定ファイルを作成します。
npx @biomejs/biome init
biome.json というファイルが作成されます。ここでフォーマッターやリンターの設定などを記述します。
Prettier と ESLint を使用している場合と異なり、全ての設定を1つのファイルで行えることも Biome の使用メリットです。
{
"$schema": "https://biomejs.dev/schemas/2.2.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": false
},
"files": {
"ignoreUnknown": false
},
"formatter": {
"enabled": true,
"indentStyle": "tab"
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
},
"assist": {
"enabled": true,
"actions": {
"source": {
"organizeImports": "on"
}
}
}
}
これで Biome を利用する準備が整いました。
フォーマットを実行する
以下コマンドで、biome.json で設定されたルールに基づいたフォーマットが実行されます。
$ npx @biomejs/biome format --write # 全てのファイルに対してフォーマットを実行する
$ npx @biomejs/biome format --write <files> # 特定のファイルに対してフォーマットを実行する
フォーマッターのルールは、biome.json 内の formatter
配下 または javascript.formatter
配下 に記述します。
-
formatter
:言語に依存しない共通ルール(インデント幅、行の長さなど) -
javascript.formatter
:JavaScript/TypeScript/JSX に特有のルール(クォート、セミコロンなど)
試しに、lineWidth
(一行の最大文字数のルール)を 120 に設定してみて、フォーマットを実行してみます。
{
// ...
"formatter": {
"enabled": true,
"indentStyle": "tab",
+ "lineWidth": 120 // 一行に含めることができる文字数の制限
}
// ...
}
フォーマットが実行されてコードが整形されていることが確認できます。
// npx @biomejs/biome format --write 実行前
function App() {
// ...
return (
<>
{/* ... */}
<p className="read-the-docs">
Click on the Vite and React logos to learn more
</p>
</>
);
}
// ...
// npx @biomejs/biome format --write 実行後
function App() {
// ...
return (
<>
{/* ... */}
<p className="read-the-docs">Click on the Vite and React logos to learn more</p>
</>
);
}
// ...
以下が、よく使われそうなフォーマットのルールです。必要に応じて formatter
または javascript.formatter
配下に追加してください。
ルール名 | 指定箇所 | 説明 | 指定可能な値 |
---|---|---|---|
indentStyle |
formatter | インデントをスペースかタブで指定 |
"space" / "tab"
|
indentWidth |
formatter | インデント幅(スペース数) | 数値 |
lineWidth |
formatter | 1行の最大文字数 | 数値 |
bracketSpacing |
formatter | オブジェクトリテラルの波括弧内のスペース |
true / false
|
attributePosition |
formatter | JSX/HTML 属性の改行位置 |
"auto" / "multiline"
|
quoteStyle |
javascript.formatter | 文字列リテラルのクォート |
"single" / "double"
|
quoteProperties |
javascript.formatter | オブジェクトのキーのクォート方法 |
"asNeeded" / "preserve"
|
trailingCommas |
javascript.formatter | 配列やオブジェクトの末尾カンマ |
"all" / "es5" / "none"
|
semicolons |
javascript.formatter | ステートメント末尾のセミコロン有無 |
"always" / "asNeeded"
|
arrowParentheses |
javascript.formatter | アロー関数の引数の括弧 |
"always" / "asNeeded"
|
jsxQuoteStyle |
javascript.formatter | JSX 内のクォート |
"double" / "single"
|
リントを実行する
以下コマンドで、biome.json で設定されたルールに基づいたリントが実行されます。
$ npx @biomejs/biome lint --write # 全てのファイルに対してリントを実行する
$ npx @biomejs/biome lint --write <files> # 特定のファイルに対してリントを実行する
リンターのルールは、biome.json 内の linter.rules
配下に追加することで適用されます。
rules
内は、適用するルールのカテゴリ毎に、以下のように分かれています。適用したいルールのカテゴリに基づいて、記述する場所を調整してください。
-
correctness
:未使用の変数やimportなど、バグにつながるコードを防ぐためのルール -
style
:const
の強制など、コードスタイルに関するルール -
suspicious
:==
の禁止など、明らかなバグではないがバグの温床になりそうな書き方を防ぐルール -
complexity
:複雑な条件式など、コードが複雑になることを防ぐルール -
performance
:不要な配列操作や無駄なループなど、パフォーマンスに悪影響を及ぼす書き方を防ぐルール -
security
:危険な API 呼び出しなど、セキュリティ上の問題を避けるためのルール -
a11y
:画像 alt 属性の必須化など、アクセシビリティ向上に関するルール
デフォルトで recommended
が有効になっています。
これにより推奨されているリントルールが適用されます。これを true
に設定しておくだけで推奨ルールのみで多くのケースはカバーできるので、有効化しておくことをおすすめします。
本記事の以下の挙動確認では 説明のために recommended
が無効となっていることを前提としています。
試しに、チェック対象となっているファイル内で未使用の変数を定義してリンターを実行してください。エラーは検出されないことが確認できます。
// ...
function App() {
const unusedVariable = "unused"; // 未使用の変数を定義
return {/* ... */};
}
// ...
$ npx @biomejs/biome lint --write
> Checked 11 files in 2ms. No fixes applied.
未使用の変数を禁止する noUnusedVariables
をルールに追加して再度リンターを実行してみると、正常にエラーと修正例が出力されていることが確認できます。
{
// ...
"linter": {
"enabled": true,
"rules": {
"recommended": false,
+ "correctness": {
+ "noUnusedVariables": "error" // 未使用の変数を禁止
+ }
}
}
// ...
}
$ npx @biomejs/biome lint --write
>
src/App.tsx:4:8 lint/correctness/noUnusedVariables FIXABLE ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ This variable unusedVariable is unused.
3 │ function App() {
> 4 │ const unusedVariable = "unused";
│ ^^^^^^^^^^^^^^
5 │
6 │ return (
ℹ Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.
ℹ Unsafe fix: If this is intentional, prepend unusedVariable with an underscore.
2 2 │
3 3 │ function App() {
4 │ - → const·unusedVariable·=·"unused";
4 │ + → const·_unusedVariable·=·"unused";
5 5 │
6 6 │ return (
Checked 11 files in 10ms. No fixes applied.
Found 1 error.
lint ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
✖ Some errors were emitted while running checks.
ルールを追加する際には、エラーレベルを指定してください。エラーレベル毎にそれぞれ以下のような挙動を取ります。
-
off
:そのルールを無効化する。該当コードがあっても指摘しない -
warn
:「警告」として出力する。CI では処理は失敗しない(終了コード 0) -
error
:「エラー」として出力する。CI では処理が失敗する(終了コード 1)
{
// ...
"linter": {
"enabled": true,
"rules": {
"recommended": false,
"correctness": {
"noUnusedVariables": "off"
"noUnusedImports": "warn"
"noEmptyTypeParameters": "error"
}
}
}
// ...
}
以下が、よく使われそうなルールと、そのカテゴリです。
ルール名 | カテゴリ | 説明 |
---|---|---|
noUnusedVariables |
correctness | 未使用の変数を禁止 |
noUnusedImports |
correctness | 未使用の import を禁止 |
noEmptyTypeParameters |
complexity | 空の型パラメータを禁止 (TypeScript) |
noDuplicateObjectKeys |
suspicious | オブジェクトリテラル内での重複キーを禁止 |
noDuplicateParameters |
suspicious | 関数の引数名の重複を禁止 |
noDebugger |
suspicious |
debugger の使用を禁止 |
noConsole |
suspicious |
console.* の使用を禁止 |
noDoubleEquals |
suspicious |
== /!= を禁止 |
noVar |
suspicious |
var の使用を禁止 |
useConst |
style | 再代入されない変数は const で定義することを要求 |
useBlockStatements |
style | if/for/while などで常に {} を要求 |
useAltText |
a11y | 画像等に代替テキストを要求 |