問題: VSCode保存時にClaude Codeのコードが勝手にフォーマットされる
tax-assistantプロジェクトの開発中、Claude Codeが書いたコードをVSCodeで保存するたびに、フォーマッターが走ってコードが書き換わる問題が発生した。
VSCodeの formatOnSave が有効で、デフォルトのPrettier設定が適用されていたことが原因。
具体的に起きたこと
1. インデントが2スペースから4スペースに変わる
Claude Codeは2スペースインデントでコードを生成するが、保存するとVSCodeのデフォルト設定で4スペースに変換される。
// Claude Codeが書いたコード(2スペース)
const calculate = (items: Item[]) => {
return items
.filter(item => item.active)
.reduce((sum, item) => sum + item.price, 0);
};
// 保存後(4スペースに変換される)
const calculate = (items: Item[]) => {
return items
.filter(item => item.active)
.reduce((sum, item) => sum + item.price, 0);
};
2. 1行で書いたコードが80文字で折り返される
Prettierのデフォルト printWidth は80文字。Claude Codeが1行で書いた読みやすいコードが、保存するだけで複数行に分割される。
// Claude Codeが書いたコード(1行で読みやすい)
const result = items.filter(item => item.category === 'active').map(item => item.name);
// 保存後(80文字で折り返される)
const result = items
.filter(
(item) =>
item.category === 'active'
)
.map((item) => item.name);
特にメソッドチェーンや条件式が無駄に分割されて、かえって読みにくくなるケースが多かった。
3. TypeScript型セパレータが , から ; に変わる
これがPrettier固有の仕様で、設定で変更できない。
// Claude Codeが書いたコード(カンマ区切り)
type LoanParams = {
principal: number,
annualRate: number,
years: number,
}
// 保存後(セミコロン区切りに変換される)
type LoanParams = {
principal: number;
annualRate: number;
years: number;
};
Prettierの公式見解として、TypeScriptの型定義におけるセパレータは ; に統一する方針で、この挙動を設定で変えることはできない。
Prettier enforces semicolons in TypeScript interfaces and type literals. This is not configurable.
git diffが確認しづらい
これらの自動フォーマットの結果、git diff がフォーマット変更のノイズだらけになる。
const calculate = (items: Item[]) => {
- return items
- .filter(item => item.active)
- .reduce((sum, item) => sum + item.price, 0);
+ return items
+ .filter((item) => item.active)
+ .reduce((sum, item) => sum + item.price, 0);
};
ロジック変更とフォーマット変更が混在して、コードレビューで実際に何が変わったのか判別しにくい。Claude Codeが意図的に書いた構造なのか、フォーマッターが勝手に変えたのかがわからなくなる。
解決: .prettierrc の作成
プロジェクトルートに .prettierrc を作成し、Claude Codeの出力スタイルに合わせた設定にした。
設定ファイル
// frontend/.prettierrc
{
"tabWidth": 2,
"useTabs": false,
"printWidth": 120,
"singleQuote": true,
"trailingComma": "all",
"semi": true,
"bracketSpacing": true
}
各設定の意図
| 設定 | 値 | 理由 |
|---|---|---|
tabWidth | 2 | Claude Codeの出力に合わせて2スペース |
useTabs | false | スペースインデント |
printWidth | 120 | 80文字だと過剰な折り返しが発生するため120に緩和 |
singleQuote | true | シングルクォート統一 |
trailingComma | "all" | trailing commaあり(diffが見やすい) |
semi | true | セミコロンあり |
bracketSpacing | true | { value } のようにスペースを入れる |
printWidthを120にした理由
80文字はターミナルの横幅を想定した伝統的な値だが、現代の開発環境では狭すぎる。
- モニタの解像度が上がり、エディタの横幅に余裕がある
- メソッドチェーンや型定義が1行に収まりやすくなる
- Claude Codeが生成するコードは1行の情報密度が適切で、120文字あれば不要な折り返しが減る
ただし120を超える行は折り返されるので、極端に長い行は書けない。ちょうどいいバランス。
TypeScript型セパレータの ; 問題について
前述の通り、Prettierでは型定義のセパレータを , にする設定がない。これはPrettierの設計思想(opinionated formatter)による制約。
対応方針として、これは受け入れることにした。理由は以下の通り。
- 型定義のセパレータが
,でも;でもTypeScriptの動作に影響はない - プロジェクト内で統一されていれば読みやすさは変わらない
- Prettierがセミコロンに揃えてくれるなら、Claude Codeが
,で書いても保存時に統一される - diffのノイズにはなるが、他のフォーマット変更(インデント、折り返し)に比べれば影響は小さい
git checkout で特定ファイルだけ戻す際の注意点
フォーマット変更だけを戻したい場合、git checkout で特定ファイルを元に戻す方法がある。
# 特定ファイルの変更を元に戻す
git checkout -- path/to/file.ts
ただし、ここに落とし穴がある。
ロジック変更とフォーマット変更が混在するファイル
Claude Codeがロジックを変更したファイルに対して、保存時にフォーマッターも走った場合、そのファイルには「ロジック変更」と「フォーマット変更」の両方が含まれる。
# ❌ 危険: ロジック変更ごと消える
git checkout -- src/components/LoanCalculator.vue
このコマンドを実行すると、フォーマット変更だけでなくロジック変更も一緒に消える。Claude Codeが実装したビジネスロジックが丸ごと失われる。
安全な手順
- まず
git diffでファイルの変更内容を確認する - フォーマット変更のみのファイルは
git checkoutで戻してOK - ロジック変更を含むファイルは
git checkoutしない - ロジック変更を含むファイルのフォーマットノイズは、
.prettierrc導入後にnpx prettier --writeで統一する
# 手順例
# 1. 変更ファイル一覧を確認
git diff --name-only
# 2. 各ファイルの変更内容を確認
git diff path/to/file.ts
# 3. フォーマット変更のみのファイルを戻す
git checkout -- src/utils/helpers.ts
git checkout -- src/types/index.ts
# 4. ロジック変更を含むファイルはPrettierで再フォーマット
npx prettier --write src/components/LoanCalculator.vue
もっと安全な方法: .prettierrc を先に入れる
ベストプラクティスとして、.prettierrc をプロジェクト初期に導入しておくのが一番良い。
# .prettierrcを作成してからPrettierで全ファイルをフォーマット
npx prettier --write "src/**/*.{ts,tsx,vue}"
# この時点でコミット(フォーマット統一コミット)
git add -A
git commit -m "style: Prettierフォーマット統一"
# 以後、Claude Codeの出力と保存時フォーマットが一致するので
# diffにフォーマットノイズが混じらない
まとめ
| 問題 | 原因 | 解決 |
|---|---|---|
| インデントが変わる | VSCodeデフォルトが4スペース | .prettierrc で tabWidth: 2 |
| 80文字で折り返される | Prettierデフォルトの printWidth | printWidth: 120 に変更 |
| 型セパレータが変わる | Prettierの仕様(設定変更不可) | 受け入れる |
| git diffが見にくい | フォーマット変更のノイズ | .prettierrc で統一 |
Claude Codeと人間が同じプロジェクトで作業する場合、フォーマッターの設定を明示的に揃えておくことが大事。設定ファイルがない状態だと、それぞれのデフォルト設定が衝突してdiffが荒れる。.prettierrc を1つ置くだけで解決できる。