📝

PrettierからBiomeへ移行してみる

2024/10/09に公開

はじめに

社内の雑談チャンネルを通して、ESLintのv8系が2024/10/5にEOLになることを知りました。
https://eslint.org/version-support/

v9系のFlatConfigの設定が大変そうというイメージもあり、
せっかくなので気になっていたBiomeへ移行してみました。

ただ、欲しいlintルールがまだBiomeになかったため、
ひとまずPrettierからBiomeへの移行のみを行いました。

PrettierからBiomeへの移行手順

1. Biomeのインストール

ドキュメントに沿って、Biomeをインストールします。

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

https://biomejs.dev/guides/getting-started/

VSCodeを使用している場合は、
拡張機能もインストールしておきます。

https://biomejs.dev/reference/vscode/

必要に応じて .vscode/settings.jsonなども書き換えておきます。

.vscode/settings.json
- "[typescript]": {
-    "editor.defaultFormatter": "esbenp.prettier-vscode"
-  },
+ "[typescript]": {
+    "editor.defaultFormatter": "biomejs.biome"
+  },

2. Biomeの初期化

下記のコマンドを実行し、Biomeの設定ファイルを作成します。

npx @biomejs/biome init

実行すると、biome.jsonが作成されます。

biome.json
{
  "$schema": "https://biomejs.dev/schemas/1.9.3/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" } }
}

https://biomejs.dev/guides/getting-started/

3. Prettierからの移行

Prettierの設定ファイルを元に、Biomeの設定ファイルを書き換えます。

npx @biomejs/biome migrate prettier --write

例えばPrettierの設定ファイルが

{
  "useTabs": false,
  "singleQuote": true,
  "overrides": [
    {
          "files": ["*.json"],
          "options": { "tabWidth": 2 }
      }
  ]
}

のような内容だった場合、
Biomeの設定ファイルは下記のようになります。

biome.json
{
  "formatter": {
    "enabled": true,
    "formatWithErrors": false,
    "indentStyle": "space",
    "indentWidth": 2,
    "lineEnding": "lf",
    "lineWidth": 80,
    "attributePosition": "auto"
  },
  "organizeImports": { "enabled": true },
  "linter": { "enabled": false, "rules": { "recommended": true } },
  "javascript": {
    "formatter": {
      "jsxQuoteStyle": "double",
      "quoteProperties": "asNeeded",
      "trailingCommas": "all",
      "semicolons": "asNeeded",
      "arrowParentheses": "always",
      "bracketSpacing": true,
      "bracketSameLine": false,
      "quoteStyle": "single",
      "attributePosition": "auto"
    }
  },
  "overrides": [
    {
      "include": ["*.json"],
      "formatter": {
        "indentWidth": 2
      }
    }
  ]
}

https://biomejs.dev/guides/migrate-eslint-prettier/#migrate-from-prettier
https://prettier.io/docs/en/options.html

CI時やGitフックなどでフォーマットを行っている場合、
package.jsonも書き換えておきます。

package.json
- "format": "prettier . --write",
+ "format": "biome format . --write",

動作確認をし、問題なければPrettierをアンインストールします。

npm uninstall --save-dev prettier

良かったこと

移行自体は非常に簡単だった

migrate用のコマンドが用意されているため、特段詰まらずに移行することができました。
設定のオプションについてもPrettierのプロパティとほぼ同じのため、移行がスムーズでした。

実行速度が約1/5になった

厳密に同じ条件で比較をしたわけではありませんが、
私が担当しているプロジェクトではCI時に実行する全ファイルのフォーマットが

  • Prettier: (5.436s)
  • Biome(0.998s)

となり、約1/5になりました。

気になったこと

Prettierとの差分が出た

私の設定内容の問題かもしれませんが、ドキュメントにもある通り
100%Prettierと同じフォーマットにはなりませんでした。

特に、括弧の位置や、型引数末尾の,などでPrettierとの差分が出ました。

// Prettierの場合
return (Object.keys(obj) as K[]).reduce((acc, cur) => {
    return keys.includes(cur) ? { ...acc, [cur]: obj?.[cur] } : acc;
}, {} as { [P in Extract<keyof T, K>]: T[P] });


// Biomeの場合
return (Object.keys(obj) as K[]).reduce(
    (acc, cur) => {
        return keys.includes(cur) ? { ...acc, [cur]: obj?.[cur] } : acc;
    },
    {} as { [P in Extract<keyof T, K>]: T[P] }
);

差分は出たものの、機能に影響するものではなかったため、
エイヤで許容することにしました。

https://biomejs.dev/formatter/differences-with-prettier/

GraphQLのフォーマットができなかった

移行時(2024/09/27)の時点では、GraphQLのフォーマットがサポートされておらず、
フォーマット時に

processing panicked: byte index 2 is out of bounds of ``

というエラーが出てしまいました。

ただ、執筆時点(2024/10/08)で改めてドキュメントを確認したところ
GraphQLのサポートが追加されており、かつ下記のPRにてエラーが修正されていたため、問題なくフォーマットを行うことができました。
https://github.com/biomejs/biome/pull/3993
https://biomejs.dev/internals/language-support/

まとめ

思ったよりも簡単にPrettierからBiomeへの移行ができました。
設定のオプションもほぼ同じであったため、移行にあたってのハードルは低かったです。

Linterのルールが追加され次第、ESLint側の移行も行いたいと思います。

Aidemy Tech Blog

Discussion