🌳

NuxtプロジェクトのLinter/FormatterにBiomeを導入する

に公開

Biome とは

Biome は JavaScript、TypeScript、CSS、GraphQL などの Web 開発で使われる言語向けの高速な formatter、linter です。
読み方は「バイオーム」です。

https://biomejs.dev

v2.3 より Biome で Vue のサポートが正式に導入されたので試してみたいと思い、今回は Nuxt.js のプロジェクトに Biome を導入してみようと思います。

https://biomejs.dev/ja/blog/biome-v2-3/

Biome のインストールとセットアップ

パッケージマネージャーにはyarnを用いているので、yarn addを使って Biome を導入します。

yarn add --dev --exact @biomejs/biome

インストール後に Biome の設定ファイルを吐き出します。

yarn exec biome init

プロジェクトルートに以下のようなbiome.jsonが生成されます。

{
  "$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "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 は linter、formatter 両方の機能を持っており、checkコマンドを使うことで両方を実行できます。
このあたりをpackage.json側にコマンドとして登録していきます。

{
  // 省略
  "scripts": {
    "build": "nuxt build",
    "dev": "nuxt dev",
    "generate": "nuxt generate",
    "preview": "nuxt preview",
    "postinstall": "nuxt prepare",
+    "lint": "biome check .",
+    "format": "biome check --write ."
  }
}

これでコマンドラインからは静的チェックとフォーマットを実行できます。

yarn lint

VSCode の設定

つづいて VSCode の設定をしていきます。
まず VSCode の Biome の拡張機能をインストールします。

https://marketplace.visualstudio.com/items?itemName=biomejs.biome

インストール後に VSCode の設定ファイルで、Biome を利用することを設定します。

{
  "[typescript]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.biome": "explicit"
    }
  },
  "[vue]": {
    "editor.defaultFormatter": "biomejs.biome",
    "editor.formatOnSave": true,
    "editor.codeActionsOnSave": {
      "source.fixAll.biome": "explicit"
    }
  }
}

これで.vueファイル保存時に Biome でのフォーマットが走るようになります。

Biome の設定をカスタマイズする

初期状態の Biome の設定のままだと足りない部分があるので設定していきます。

まず.vueファイルのtemplate部分のフォーマットを有効にするにはhtml.experimentalFullSupportEnabledtrueにする必要があります。
あとは個人的にはインデントはスペースで文字列はシングルクォート(')で囲うのが好みなので変更しています。

{
  "$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "files": {
    "ignoreUnknown": false
  },
  "formatter": {
    "enabled": true,
-    "indentStyle": "tab"
+    "indentStyle": "space"
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "javascript": {
    "formatter": {
-      "quoteStyle": "double"
+      "quoteStyle": "single"
    }
  },
+  "html": {
+    "experimentalFullSupportEnabled": true
+  },
  "assist": {
    "enabled": true,
    "actions": {
      "source": {
        "organizeImports": "on"
      }
    }
  }
}

また Biome では現在、.vueファイルのテンプレート内での変数参照が正しく反映されません。

例えば以下のような.vueファイルはエラーとなります。

<script setup lang="ts">
const a = 1;
</script>

<template>
  <div>{{ a }}</div>
</template>
$ biome check .
app/pages/sample.vue:2:7 lint/correctness/noUnusedVariables  FIXABLE  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━

  ⚠ This variable a is unused.

    1 │ <script setup lang="ts">
  > 2 │ const a = 1;
      │       ^
    3 │ </script>
    4 │

  ℹ Unused variables are often the result of an incomplete refactoring, typos, or other sources of bugs.

  ℹ Unsafe fix: If this is intentional, prepend a with an underscore.

    1 1 │
    2   │ - const·a·=·1;
      2 │ + const·_a·=·1;
    3 3 │


Checked 6 files in 3ms. No fixes applied.
Found 1 warning.
Done in 0.11s.

この部分は仕方がないのでoverridesでルールをオフにします。

{
  "$schema": "https://biomejs.dev/schemas/2.3.2/schema.json",
  "vcs": {
    "enabled": true,
    "clientKind": "git",
    "useIgnoreFile": true
  },
  "files": {
    "ignoreUnknown": false
  },
  "formatter": {
    "enabled": true,
    "indentStyle": "space"
  },
  "linter": {
    "enabled": true,
    "rules": {
      "recommended": true
    }
  },
  "javascript": {
    "formatter": {
      "quoteStyle": "single"
    }
  },
  "html": {
    "experimentalFullSupportEnabled": true
  },
  "assist": {
    "enabled": true,
    "actions": {
      "source": {
        "organizeImports": "on"
      }
    }
  },
+  "overrides": [
+    {
+      "includes": ["**/*.vue"],
+      "linter": {
+        "rules": {
+          "correctness": {
+            "noUnusedVariables": "off",
+            "noUnusedImports": "off"
+          }
+        }
+      }
+    }
+  ]
}

まとめ

Biome を Nuxt.js のプロジェクトで試してみましたが、感触としては悪くないと思います。
これまでの ESLint と Prettier の併用はバージョンアップへの追従もそこそこ労力が必要な上に毎回セットアップがしんどくて何が正しいのかわかりづらい部分が多くあったので、シンプルな設定ファイルで高速に動作する Biome は魅力的なツールだと思います。

対応ルールや Vue などのサポートはまだ未完成な部分がありますが、着実に進歩しているので、これからのアップデートに注目したいですね。

Discussion