この記事の概要
JavaScript や TypeScript を扱う中で lint と format を考える際、ESLint と Prettier を組み合わせるのが鉄板1かと思います。
ですが、Biome というツールが最近2出てきました。
どうやら Biome 単体で lint も format も担えるようです。
私は面倒くさがりなので使うツールや設定はできるだけ減らしておきたく、ESLint と Prettier を Biome に置き換えてみようと思いました。
試してみた際の備忘録の記事です。
前提
- 既存プロジェクトの ESLint と Prettier を Biome に置き換える
- できるだけ設定が複雑にならないことが優先
- 既存のルールから変わっても良しとする
- 置き換える対象のプロジェクトでは Astro を使っている
-
.js
と.ts
だけでなく.astro
ファイルの設定もする
-
-
biome migrate
は使わない- 自分の勉強がてらの取り組みなので、せっかくだから大変な思いをしておく
環境
置き換える前の状態はこのようになっていました。
既存の依存関係 | バージョン |
---|---|
astro | 3.6.4 |
@typescript-eslint/eslint-plugin | 6.21.0 |
eslint | 8.57.0 |
eslint-config-prettier | 9.1.0 |
eslint-plugin-astro | 0.31.4 |
eslint-plugin-jsx-a11y | 6.8.0 |
prettier | 3.2.5 |
prettier-plugin-astro | 0.13.0 |
置き換えた後はこうなっています。
新しい依存関係 | バージョン |
---|---|
astro | 3.6.4 |
@biomejs/biome | 1.8.1 |
lint, format 関連で 7 つあった依存関係が 1 つにまとまるのは嬉しいです。
既存の ESLint, Prettier の設定
module.exports = {
env: {
browser: true,
es2021: true,
node: true,
},
extends: [
"eslint:recommended",
"plugin:@typescript-eslint/recommended",
"plugin:astro/recommended",
"plugin:astro/jsx-a11y-recommended",
"prettier",
],
overrides: [
{
files: ["*.astro"],
parser: "astro-eslint-parser",
parserOptions: {
parser: "@typescript-eslint/parser",
extraFileExtensions: [".astro"],
},
},
],
parserOptions: {
ecmaVersion: "latest",
sourceType: "module",
},
};
module.exports = {
plugins: [
require.resolve("prettier-plugin-astro"),
],
overrides: [
{
files: "*.astro",
options: {
parser: "astro",
},
},
],
};
ご覧の通り、デフォルト設定や推奨設定を適用する以外のことはしていません。
Biome でもこういった具合で、推奨設定を適用して終わりとするつもりでいます。
インストール
ターミナルで次のコマンドを叩きます。
npm install --save-dev --save-exact @biomejs/biome
lint や format の修正によりスクリプトが通らなくなるかもしれないとのことで、--save-exact
をつけてのインストールが推奨されています。3
設定ファイルの初期化
次のコマンドを叩くことでbiome.jsonc
が作成されます。
npx @biomejs/biome init --jsonc
なお--jsonc
はオプションで、無しだとbiome.json
が生成されます。
なんだかんだとコメントを書きたいことは多いので、今回は--jsonc
を適用しました。
作成されたbiome.jsonc
の中身はこのようになっています。4
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
}
}
format 関連の設定は記載されていませんが、デフォルトでオン5になっているようです。
とは言えドキュメントをしっかり読んでいないと分かりづらいので、記載しておいても良いのかなと思いました。
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
+ "formatter": {
+ "enabled": true
+ }
}
Astro の設定の追加
Biome は v1.6 にて Astro を部分的にサポートしました。6
そのうち不要になるのかもしれませんが、7現状は次のような設定を追加する必要があります。
{
"$schema": "https://biomejs.dev/schemas/1.8.1/schema.json",
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"formatter": {
"enabled": true
},
+ "javascript": {
+ "globals": ["Astro"]
+ }
}
package.json のスクリプト変更
勝手に書き換えるのがあまり好きではなかったので、もともとチェックだけにしていました。
Biome には lint と format を両方実行するcheck
というコマンドがもともと用意されているので、そちらに置き換えます。
"scripts": {
- "lint": "eslint ./src && prettier --check ./src"
+ "check": "biome check ./src"
}
変更した後には一度実行しました。
一番大きく変わったのはインデントのスタイルです。
Prettier ではデフォルトがスペースですが、Biome ではタブです8。
そのため、インデント変更の差分はかなりたくさん出ました。
スペースかタブかの好みは人によって結構分かれると思うのですが、私は正直あまり気にしていません。
プロジェクトで統一されていて、設定ファイルがシンプルであればどちらでも良いです。
というわけで Biome のデフォルトであるタブのインデントに置き換えました。
ESLint と Prettier のアンインストール
ESLint と Prettier、そしてそれらのプラグインなどをアンインストールして完了です。
最後に
私がもともと設定ファイルにこだわっておらず、導入後のコード変更も許容したので作業自体はすぐに終わりました。
導入して lint や format した後のコードが一切変わらないようにすると多少大変かもしれませんが、 migration 用のコマンドも用意されている9ので、ある程度は自動で済ませられるだろうと思っています。
また、2024 年 6 月 16 日 は v1.8 のブログ記事が出ていないのですが、X のポストによれば v1.8 から CSS の lint, format ができるようになったとのことです。
今後も対応する範囲が広がっていきそうなので、取り入れていきたいと思っています。
-
少なくともこの記事を書いている 2024 年 6 月現在はシェア 1 位の組み合わせのはずです。 ↩
-
2023 年 8 月 29 日に v1 がリリースされたようです。 https://biomejs.dev/blog/biome-v1/ ↩
-
かなりどうでも良い話ですが、2024 年 6 月 16 日現在は init コマンドを適用した時点で
organizeImports
が"enabled": true
になっているものの、ドキュメントに記載されているデフォルト設定は"enabled": false
です。 https://biomejs.dev/guides/getting-started/#configuration ↩ -
https://biomejs.dev/reference/configuration/#formatterenabled ↩
-
いくつかの lint ルールと競合するためこういった記載が必要になるそうで、完全なパーサーが提供されれば不要になるかもしれない、と予想しているだけです。 https://biomejs.dev/internals/language-support/#html-super-languages-support ↩
-
アクセシビリティ的な観点でタブの方が優れているという話もあり、それが理由でデフォルトがタブなんだろうか、と予想しています。ただしあくまで予想です。 https://alexandersandberg.com/articles/default-to-tabs-instead-of-spaces-for-an-accessible-first-environment/ ↩