はじめに
- モダンなWeb開発において、コード品質の維持と開発効率の向上は重要な課題です。本記事では、Turborepoを使用したNext.jsプロジェクトに、高性能な開発ツールチェーンであるBiomeを導入する手順を解説します。
Turborepoとは
- Turborepoは、JavaScript/TypeScriptプロジェクトのためのハイパフォーマンスなビルドシステムです。
主な特徴
- フレームワークに依存しない柔軟性(Next.js, React等で利用可能)
- インテリジェントなタスク実行とキャッシング
- モノレポ(monorepo)に最適化された設計
Biomeとは
- Biomeは、Web開発のための次世代統合ツールチェーンです。JavaScript、TypeScript、JSX、JSON、CSS、GraphQLなどの幅広い言語をサポートし、コードの品質管理を効率化します。
主な特徴
1. 高速なフォーマッタ機能
- コードの自動フォーマットを高速に実行
- Prettierと比較して数十倍の処理速度
- Prettierとの高い互換性により、スムーズな移行が可能
2. 強力なリント機能
- 200以上の組み込みルール
- 詳細な診断結果の提供
- 豊富なルールセットによる包括的なコード分析
3. 統合機能
- フォーマットとリントの同時実行をサポート
- 単一のツールでの効率的なコード品質管理
- シンプルな設定と運用
導入手順
1. Turborepoプロジェクトの作成
- まずは、Turborepoプロジェクトを作成します。
ターミナル
npx create-turbo@latest [プロジェクト名]
パッケージマネージャーはpnpm
を選択しました。違うパッケージマネージャーを選択した場合は、コマンドを置き換えてから実行してください。
2. 既存の Linter/Formatter の削除
Biomeに移行するため、既存のPrettierとESLintの設定を削除します。
2.1. package.json の修正
- 各ディレクトリの
package.json
から、Prettier・ESLint関連の設定を削除します。
package.json(/)
"name": "tureborepo-next-biome-template",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
- "lint": "turbo run lint",
- "format": "prettier --write \"**/*.{ts,tsx,md}\"",
"check-types": "turbo run check-types"
},
"devDependencies": {
- "prettier": "^3.5.3",
"turbo": "^2.4.4",
"typescript": "5.8.2"
},
"packageManager": "pnpm@9.0.0",
"engines": {
"node": ">=18"
}
}
turbo.json(/)
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"]
},
- "lint": {
- "dependsOn": ["^lint"]
- },
"check-types": {
"dependsOn": ["^check-types"]
},
"dev": {
"cache": false,
"persistent": true
}
}
}
package.json(/apps/web)
{
"name": "web",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3000",
"build": "next build",
"start": "next start",
- "lint": "next lint --max-warnings 0",
"check-types": "tsc --noEmit"
},
"dependencies": {
"@repo/ui": "workspace:*",
"next": "^15.2.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
- "@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
- "eslint": "^9.22.0",
"typescript": "5.8.2"
}
}
package.json(/apps/docs)
{
"name": "docs",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3000",
"build": "next build",
"start": "next start",
- "lint": "next lint --max-warnings 0",
"check-types": "tsc --noEmit"
},
"dependencies": {
"@repo/ui": "workspace:*",
"next": "^15.2.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
- "@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
- "eslint": "^9.22.0",
"typescript": "5.8.2"
}
}
package.json(/packages/ui)
{
"name": "@repo/ui",
"version": "0.0.0",
"private": true,
"exports": {
"./*": "./src/*.tsx"
},
"scripts": {
- "lint": "eslint . --max-warnings 0",
"generate:component": "turbo gen react-component",
"check-types": "tsc --noEmit"
},
"devDependencies": {
- "@repo/eslint-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@turbo/gen": "^2.4.4",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
- "eslint": "^9.22.0",
"typescript": "5.8.2"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
2.2. 不要なファイルの削除
以下のファイルを削除します
-
packages/eslint-config/
(ディレクトリごと) apps/web/eslint.config.mjs
apps/docs/eslint.config.mjs
packages/ui/eslint.config.mjs
2.3. 依存関係の更新
ターミナル
pnpm install
3. VSCode の設定
- Biomeをエディタに統合するため、
.vscode/settings.json
を作成または修正します。
.vscode/settings.json
{
"editor.formatOnSave": true,
"editor.defaultFormatter": "biomejs.biome",
"editor.codeActionsOnSave": {
"quickfix.biome": "explicit",
"source.organizeImports.biome": "explicit"
}
}
4. Biome の設定
4.1. 設定パッケージの作成
- Biomeの設定を一元管理するための内部パッケージを作成します。
ターミナル
# 1. パッケージ作成
mkdir -p packages/biome-config
# 2. パッケージ移動
cd packages/biome-config
# 3. パッケージ初期化
pnpm init
4.2. Biome のインストールと初期化
ターミナル
# 1. インストール
pnpm add -D @biomejs/biome
# 2. 初期化
pnpm biome init
4.3. 設定ファイルの変更
package.json(/packages/biome-config)
{
"name": "@repo/biome-config",
"version": "1.0.0",
"type": "module",
"private": true,
"exports": {
"./biome": "./biome.json"
},
"devDependencies": {
"@biomejs/biome": "^1.9.4"
}
}
biome.json(/packages/biome-config)
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"vcs": {
"enabled": false,
"clientKind": "git",
"useIgnoreFile": true
},
"files": {
"ignoreUnknown": false,
"ignore": ["./tsconfig.json"]
},
"formatter": {
"enabled": true,
"indentStyle": "space",
"indentWidth": 2
},
"organizeImports": {
"enabled": true
},
"linter": {
"enabled": true,
"rules": {
"recommended": true
}
},
"javascript": {
"formatter": {
"quoteStyle": "double"
}
}
}
5. ワークスペース(apps)と内部パッケージ(packages)にbiomeを導入する
5.1 package.jsonの変更とbiome.jsonの追加
- 今回はプロジェクト作成時に生成される
apps/web
,apps/docs
,packages/ui
に導入します。
packages.json(apps/web)
{
"name": "web",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3000",
"build": "next build",
"start": "next start",
"check-types": "tsc --noEmit",
+ "biome:check": "biome check .",
+ "biome:fix": "biome check --fix ."
},
"dependencies": {
"@repo/ui": "workspace:*",
"next": "^15.2.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
+ "@biomejs/biome": "^1.9.4",
+ "@repo/biome-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"typescript": "5.8.2"
}
}
biome.json(apps/web)
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"extends": ["../../packages/biome-config/biome.json"]
}
packages.json(apps/docs)
{
"name": "docs",
"version": "0.1.0",
"type": "module",
"private": true,
"scripts": {
"dev": "next dev --turbopack --port 3000",
"build": "next build",
"start": "next start",
"check-types": "tsc --noEmit",
+ "biome:check": "biome check .",
+ "biome:fix": "biome check --fix ."
},
"dependencies": {
"@repo/ui": "workspace:*",
"next": "^15.2.1",
"react": "^19.0.0",
"react-dom": "^19.0.0"
},
"devDependencies": {
+ "@biomejs/biome": "^1.9.4",
+ "@repo/biome-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"typescript": "5.8.2"
}
}
biome.json(apps/docs)
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"extends": ["../../packages/biome-config/biome.json"]
}
packages.json(/packages/ui)
{
"name": "@repo/ui",
"version": "0.0.0",
"private": true,
"exports": {
"./*": "./src/*.tsx"
},
"scripts": {
"generate:component": "turbo gen react-component",
"check-types": "tsc --noEmit",
+ "biome:check": "biome check .",
+ "biome:fix": "biome check --fix ."
},
"devDependencies": {
+ "@biomejs/biome": "^1.9.4",
+ "@repo/biome-config": "workspace:*",
"@repo/typescript-config": "workspace:*",
"@turbo/gen": "^2.4.4",
"@types/node": "^22.13.10",
"@types/react": "19.0.10",
"@types/react-dom": "19.0.4",
"typescript": "5.8.2"
},
"dependencies": {
"react": "^19.0.0",
"react-dom": "^19.0.0"
}
}
biome.json(/packages/ui)
{
"$schema": "https://biomejs.dev/schemas/1.9.4/schema.json",
"extends": ["../biome-config/biome.json"]
}
注意
「extents」に関して、現状だと@repo/biome-config/biome.json
のような指定方法は対応されてないため、相対パスで指定しています。
なので、"@repo/biome-config": "workspace:*",
がなくてもbiomeは動作します。
(早く対応してほしいです…)
5.2 依存関係の更新
ターミナル(/)
# 1. ルートディレクトリに移動
cd ../..
# 2. インストール
pnpm install
6. turboの設定ファイル更新
- Biomeを使用している全ワークスペースおよび内部パッケージを一括で実行できるようにpakcage.jsonおよびturbo.jsonファイルを更新する。
package.json(/)
{
"name": "tureborepo-next-biome-template",
"private": true,
"scripts": {
"build": "turbo run build",
"dev": "turbo run dev",
"check-types": "turbo run check-types",
+ "biome:check": "turbo run biome:check",
+ "biome:fix": "turbo run biome:fix"
},
"devDependencies": {
"turbo": "^2.4.4",
"typescript": "5.8.2"
},
"packageManager": "pnpm@9.0.0",
"engines": {
"node": ">=18"
}
}
turbo.json(/)
{
"$schema": "https://turbo.build/schema.json",
"ui": "tui",
"tasks": {
"build": {
"dependsOn": ["^build"],
"inputs": ["$TURBO_DEFAULT$", ".env*"],
"outputs": [".next/**", "!.next/cache/**"]
},
"check-types": {
"dependsOn": ["^check-types"]
},
+ "biome:check": {
+ "dependsOn": ["^biome:check"]
+ },
+ "biome:fix": {
+ "dependsOn": ["^biome:fix"]
+ },
"dev": {
"cache": false,
"persistent": true
}
}
}
動作確認
1. ファイル保存時にフォーマット整形およびインポートの並び替えがされるか
page.tsx(apps/web/app/page.tsx)
+ import { Button } from "@repo/ui/button";
import Image, { type ImageProps } from "next/image";
- import { Button } from "@repo/ui/button";
import styles from "./page.module.css";
2. ルート配下で、pnpm biome:check
を実行したときに正しくチェックされるか
コマンド
pnpm biome:check
# プロジェクト作成で生成されたファイルのままだと、ここでチェックエラーになります。
# 次の 'pnpm biome:fix' コマンドで解消することができます。
3. ルート配下で、pnpm biome:fix
を実行したときに正しく修正されるか
コマンド
pnpm run biome:fix
注意
packages/ui//button.tsxで「Provide an explicit type prop for the button element.」というエラーが発生した場合は、buttonタグにtype属性を追加することでpnpm run biome:fix
が成功するようになります。