【Next.js】eslint + pretteirをやめてBiomeにした話
はじめに
Next.js
などReact
のプロジェクトにはlinter
とformatter
が必須でeslint
とpretteir
を使うと思います。
しかし、導入するとなると考慮すべき点や面倒な点が結構あります。
以下は一例です。
-
eslint
とprettier
は設定が複数あり、プラグインのインストールが必要 -
eslint-plugin-prettier
を使えば、pretteir
がなくてもformatter
は実現できるため、そもそもprettier
いるのか問題 - 逆に
eslint
はlinter
としての役割のみにして、formatter
の機能は持たせたくない
そこででてくるのがBiome
です。
Biomeとは
一言でいうとeslint
とprettier
を一つにしたものです。
以下、公式の引用とページです。
Biome はWebプロジェクトのための高性能なツールチェーンであり、プロジェクトの健全性を維持するための開発者ツールの提供を目的としています。
Biome は JavaScript, TypeScript, JSX そして JSON 向けの高速なFormatterであり、Prettier との互換性は97% を達成しています。
Biome は JavaScript, TypeScript, JSX のための高性能なLinter であり、ESLint, TypeScript ESLint, その他のソースから 170以上のルールを提供しています。Biome は詳細で文脈に沿った結果を出力するため、コードを改善し、より良いプログラマになるための手助けをします!
Biome は最初からエディタ内で対話的に使用できるように設計されています。 あなたがコードを書いているときに、形の崩れたコードを format と lint することができます。
これはありがたいということで、早速、Next.jsのプロジェクトに導入してみました。
Biomeをプロジェクトに導入
それではBiome
をプロジェクトに導入していき、設定まで行っていきましょう。
Biomeをインストール
まず、公式ドキュメントに沿って、プロジェクトのディレクトリにBiome
をインストールします。
yarn add --dev --exact @biomejs/biome
次に、Biome
の設定ファイルであるbiome.json
を作成します。
以下のコマンドで作成します。
npx @biomejs/biome init
ファイルの内容はデフォルトで以下のようになっていると思います。
{
"$schema": "https://biomejs.dev/schemas/1.5.2/schema.json",
"organizeImports": {
"enabled": false
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}
デフォルトでは、linter
の推奨ルールとformatter
が有効になっている状態です。
(formatter.enabled: false
と明示的にformatter
を無効にしない限りはformatter
は有効化されているようです)
package.jsonの編集
Biome
のlinter
やformatter
をCLIからも使用できるようにします。
以下のようにpackage.json
のscripts
にコマンドを追加してください。
※ <files>
には任意のファイルやディレクトリを指定してください(例えば./src
など)
"lint": "biome lint -- apply <files>",
"format": "biome format <files> --write",
"check": "biome check --apply <files>"
各コマンドは以下のような動きをします。
-
format
:--write
オプションを指定することで、ファイルやディレクトリをフォーマットする -
lint
:--apply
オプションを指定することで、ファイルやディレクトリに対してLintを実行し、修正できる部分は修正する(eslintのfixと同じ) -
check
:format
・lint
・importの整理
を実行(全てを実行する)
エディタの設定
Biome
を使用する以前はエディタのdefaultFormatter
にはprettier
を使用していたので、それをBiome
に変更する必要があります。
まずは、VSCodeの拡張機能をインストールします。
次に、公式ドキュメントに沿って、settings.json
を編集します。
(VSCodeの「設定」(Macの場合、「command + ,」) > 上部にある「設定(JSON)を開く」から開く)
settings.json
を開いたら、以下の設定を追加します。
(元々、prettier
を使用していた場合は、"editor.defaultFormatter"
をbiomejs.biome
に書き換える必要があります。もちろん、言語ごとに設定も可能です。)
"editor.codeActionsOnSave": {
"quickfix.biome": true,
"source.organizeImports.biome": true
},
"editor.defaultFormatter": "biomejs.biome",
"[javascript]": {
"editor.defaultFormatter": "biomejs.biome"
},
"editor.codeActionsOnSave"
の"quickfix.biome"
で保存時にコードの修正がなされるようになり、"source.organizeImports.biome"
でインポートの並び替えが行われます。
Biomeの設定を編集
私の場合は、以下のような設定を使用することにしています。
考え方としては、まずfiles
のignore
でformatter
とlinter
を適用させたくないものを指定します。
formatter
は個人的な好みやチームによりけりなので、基本はデフォルトの設定を適用し、追加の設定や変更したい設定を記述するようにしています。
linter
はrecommended
でも良いとは思いますが、私は基本的に全て適用させたい派なので、そのようにし、外したい設定のみoff
にするようにしています。
override
では「このファイルだけ、この設定を付けたい・offにしたい」というものを記述しています。
今回の場合、プロジェクトがNext.js
のapp router
なので、export default
しないといけないファイルがあるなどします。
そのため、該当するファイルにのみnoDefaultExport
をoff
にするようにしています。
{
"$schema": "https://biomejs.dev/schemas/1.5.2/schema.json",
"files": {
"ignore": ["public"]
},
"organizeImports": {
"enabled": true
},
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "asNeeded"
}
},
"linter": {
"enabled": true,
"rules": {
"all": true,
"nursery": {
"noNodejsModules": "off"
}
}
},
"overrides": [
{
"include": [
"next.config.js",
"layout.tsx",
"page.tsx",
"loading.tsx",
"error.tsx",
"not-found.tsx"
],
"linter": {
"rules": {
"style": {
"noDefaultExport": "off"
}
}
}
}
]
}
それでは、Biome
の具体的な内部仕様について、概要を解説します。
Analyzer
まず、Analyser
ですが、これは"organizationImports"
の部分になります。
これはimport
のソートを行う・行わないの設定ができます。
import文をソートする場合、Biome
では距離によってソートされます。
具体的には、ユーザー(ファイル)から遠いモジュールほど上に配置されるようです。
例えば以下のimport文の場合は、
import './globals.css'
import { Inter } from 'next/font/google'
import type { ReactNode } from 'react'
import type { Metadata } from 'next'
次のようにソートされます。
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import type { ReactNode } from 'react'
import './globals.css'
グループソートは以下のようにすることで実現できます。
// group1
import './globals.css'
// group2
import type { Metadata } from 'next'
import { Inter } from 'next/font/google'
import type { ReactNode } from 'react'
このように改行を入れるとグループに分けてソートできるので、非常に使いやすいです。
Formatter
次にFormatter
ですが、これは"formatter"
の部分でprettier
の機能に該当します。
ただ、Biome
では"formatter": {}
と記述することなく、デフォルトで以下の設定が適用されています。
{
"formatter": {
"enabled": true,
"formatWithErrors": false,
"indentStyle": "tab",
"indentWidth": 2,
"lineWidth": 80,
"lineEnding": "lf",
"ignore": []
}
}
そのため、基本的にデフォルトのままで上書きしたいものを記述する方式で良いと思います。
もちろん、明示的に記述したい方は記述しても良いとは思います。(このあたりは好みの問題です)
言語ごとの設定も追加でき、例えば、JavaScript
では以下がデフォルトの設定となっています。
{
"javascript": {
"formatter": {
"arrowParentheses":"always",
"jsxQuoteStyle": "double",
"semicolons": "always",
"trailingComma": "all",
"quoteProperties": "asNeeded",
"bracketSpacing": true,
"bracketSameLine": false
}
}
}
私の設定ではデフォルトを上書きし、以下の記述をしています。
"javascript": {
"formatter": {
"quoteStyle": "single",
"semicolons": "asNeeded"
}
}
このようにすることでJavaScript
ではシングルクォートと文末のセミコロンをなしにするformat
ができます。
format
を無視したい場合、以下のコメントを該当行に記載します。
// biome-ignore format: <説明文>
Linter
続いてLinter
ですが、これは"linter"
の部分でeslint
の機能に該当します。
デフォルトではBiome
が推奨するルールが適用されます。
ルールを有効化するには、以下のように"rules"
にグループとルール名を指定し、"error"
か"warn"
を指定します。
逆に、無効化したい場合は、ルール名に対して"off"
を指定することで無効化することができます。
このように適用させたい(させたくない)ルールをカスタマイズすることができます。
{
"linter": {
"enabled": true,
"rules": {
"style": {
"useBlockStatements": "error",
"useShorthandArrayType": "warn",
"noShoutyConstants": "off"
}
}
}
}
linter
を無視したい場合、以下のコメントを該当行に記載します。
// biome-ignore lint: <explanation>
// biome-ignore lint/suspicious/noDebugger: <explanation>
linter
の場合は、それぞれ以下の意味があります。
-
biome-ignore
: 抑制コメントの開始を表す -
lint
:linter
を抑制することを表す -
/suspicious/noDebugger
: このコメントは任意で、抑制したいルールのグループと名前を表す -
<explantation>
: ルールが無効になっている理由を表す
overrides
最後にoverrides
では、特定のファイルに対するBiome
の動作を設定することができます。
例えば、私の設定のinclude
ではinclude
に指定したパターンにマッチするファイルにのみoverrides
で指定した設定を適用することができます。
この場合は、指定したファイルに対して、linter
のnoDefaultExport
ルールを無効にするような設定をしています。
"overrides": [
{
"include": [
"next.config.js",
"layout.tsx",
"page.tsx",
"loading.tsx",
"error.tsx",
"not-found.tsx"
],
"linter": {
"rules": {
"style": {
"noDefaultExport": "off"
}
}
}
}
]
他にも色々と設定があるので、詳しくはドキュメントを見てみてください。
ドキュメントは、日本語化されていない部分もありますが、大体は日本語化されているので読みやすいと思います。
おわりに
個人的には、今後はBiome
を使っていきたいですし、既存のプロジェクトもBiome
にしたいと思うくらい良かったです。
ぜひ使ってみてください。
参考文献
Discussion