PrettierのarrowParens設定徹底解説:JavaScriptコード整形術
「Arrow Function Parentheses」(矢印関数の括弧)とは、具体的には矢印関数の引数を囲む括弧 ()
のことです。Prettierには、この括弧の扱いに関するオプションがあります。
デフォルトでは、Prettierは、引数が一つで、かつ括弧が省略可能な場合に、その括弧を省略します。
例(Prettierデフォルトの挙動)
// Before Prettier
const func1 = (a) => a * 2; // 引数が一つなので括弧は省略可能
// After Prettier (デフォルト設定の場合)
const func1 = a => a * 2; // 括弧が省略される
しかし、Prettierには arrowParens
という設定オプションがあり、これを変更することで、このデフォルトの挙動を調整できます。
arrowParens
オプションには以下の2つの値があります。
-
- この設定にすると、Prettierは矢印関数の引数が一つであっても、常に括弧を付けます。
// Prettier設定: arrowParens: "always" の場合 const func1 = a => a * 2; // Prettier適用前 // After Prettier const func1 = (a) => a * 2; // 括弧が追加される const func2 = (a, b) => a + b; // 複数引数の場合はもともと括弧が必要なので変化なし
-
"avoid"
(避ける)- この設定はPrettierのデフォルトの挙動と同じです。引数が一つで括弧が省略可能な場合は、括弧を省略します。引数が複数ある場合や、引数がない場合は、通常通り括弧が付与されます。
// Prettier設定: arrowParens: "avoid" の場合 const func1 = (a) => a * 2; // Prettier適用前 // After Prettier const func1 = a => a * 2; // 括弧が省略される const func2 = (a, b) => a + b; // 複数引数の場合はもともと括弧が必要なので変化なし const func3 = () => console.log("Hello"); // 引数がない場合も変化なし
なぜこの設定があるのか?
この arrowParens
オプションは、主にチームや個人のコーディングスタイル、そしてコードの可読性に関する好みに応じて使い分けられます。
-
"always" の利点
- すべての矢印関数で引数の括弧の有無が統一されるため、一貫性がある。
- 引数の数が変わった時に、括弧の追加・削除の手間がなくなる。
- 慣れない人にとって、引数が一つでも括弧があった方が「これは引数である」と認識しやすい場合がある。
-
"avoid" の利点
- コードが少し簡潔になる。
- 引数が一つだけの単純な関数の場合、余分な文字が減り、すっきり見える。
Prettierは、コードの自動整形ツールとして非常に便利ですが、設定の不一致や他のツールとの連携によって、意図しない挙動やエラーが発生することがあります。特に矢印関数の括弧に関しては、好みが分かれる部分でもあるため、問題が発生しやすいポイントです。
よくあるエラーとその原因
a. 意図しない括弧の追加/削除
-
原因
- Prettierの arrowParens 設定が意図と異なる
これが最も一般的な原因です。プロジェクトの.prettierrc
やpackage.json
などでarrowParens
オプションが"always"
または"avoid"
に設定されており、それがあなたの期待する挙動と異なっています。 - Prettierの設定が適用されていない
エディタのPrettier拡張機能が正しく動作していない、またはプロジェクトのルートに設定ファイルがないため、Prettierのデフォルト設定が適用されている可能性があります。 - 複数のフォーマッタ/リンターが競合している
ESLintなどの他のリンターツールも、同様に矢印関数の括弧に関するルールを持っている場合があります。PrettierとESLintの両方が有効になっている場合、設定が競合して一方が他方を上書きしたり、エラーを引き起こしたりすることがあります。
- Prettierの arrowParens 設定が意図と異なる
-
- 引数が一つの矢印関数
a => a * 2
を書いたのに、保存すると(a) => a * 2
に勝手に変更される。 - またはその逆で、
(a) => a * 2
を書いたのにa => a * 2
に変更される。
- 引数が一つの矢印関数
b. ESLintの「prettier/prettier」エラー
-
原因
- ESLintのルールとPrettierの設定の不一致
ESLintが独自のルールで括弧の有無を強制しようとしているが、PrettierのarrowParens
設定がそれと異なっている場合に発生します。 - eslint-plugin-prettier や eslint-config-prettier の設定不備
ESLintとPrettierを連携させるためにこれらのプラグインや設定を利用している場合、それらの設定が正しく行われていないと、エラーや警告が発生します。例えば、PrettierのルールをESLintに適用する設定が不足していると、ESLintはPrettierのフォーマットを「エラー」と見なしてしまいます。
- ESLintのルールとPrettierの設定の不一致
-
エラーの状況
- ESLintがPrettierの整形ルールと異なる点を指摘し、
prettier/prettier
のようなエラーが表示される。 - 特に、
"Replace
awith
(a)prettier/prettier"
のようなメッセージが表示されることがあります。
- ESLintがPrettierの整形ルールと異なる点を指摘し、
a. Prettierの arrowParens
設定を確認・変更する
- 設定を変更
あなたが望む挙動に合わせてarrowParens
の値を変更します。- 常に括弧を付けたい場合:
"arrowParens": "always"
- 可能な限り括弧を省略したい場合:
"arrowParens": "avoid"
- 常に括弧を付けたい場合:
- arrowParens オプションを見つける
- もし
arrowParens
がない場合は、Prettierのデフォルト設定("avoid"
)が適用されています。 - もし
arrowParens: "always"
となっていれば、単一引数でも括弧が強制されます。 - もし
arrowParens: "avoid"
となっていれば、単一引数では括弧が省略されます。
- もし
- 設定ファイルを確認
プロジェクトのルートにある.prettierrc
(または.prettierrc.json
,.prettierrc.js
,prettier.config.js
、package.json
内のprettier
フィールド) を開きます。
例: .prettierrc
{
"semi": true,
"singleQuote": true,
"arrowParens": "always" // または "avoid"
}
b. エディタ(VS Codeなど)のPrettier拡張機能の確認
- フォーマットの競合を解決
複数のフォーマッタが有効になっている場合、VS Codeはどちらを使うか尋ねてくることがあります。Prettierをデフォルトのフォーマッタとして設定するか、他のフォーマッタを無効にすることを検討します。- VS Codeの場合:
Default Formatter
をesbenp.prettier-vscode
に設定します。 Editor: Format On Save
が有効になっているか確認します。
- VS Codeの場合:
- エディタの設定を確認
VS Codeの場合、「設定」(Settings)を開き、「Prettier」で検索します。Prettier: Arrow Parens
の項目があれば、ここで設定が上書きされていないか確認します。通常、プロジェクトの.prettierrc
を優先させるべきです。
c. ESLintとの連携を確認・調整する
-
ESLintの arrow-parens ルールの確認
ESLintのデフォルトルールにもarrow-parens
というルールが存在します。これがPrettierの設定と競合している場合、ESLint側でこのルールを無効にするか、Prettierの設定と合わせる必要があります。.eslintrc.js
でrules
を確認:module.exports = { // ... rules: { "arrow-parens": ["off"], // または ["error", "always"] / ["error", "as-needed"] // "prettier/prettier": "error", // eslint-plugin-prettier を使っている場合 }, };
"off"
にすると、ESLintはこのルールについて何も言わなくなります。"as-needed"
はPrettierの"avoid"
に、"always"
はPrettierの"always"
に対応します。
-
eslint-plugin-prettier の利用(オプション)
Prettierの整形ルールをESLintのエラーとして表示させたい場合に使います。- インストール:
npm install --save-dev eslint-plugin-prettier
.eslintrc.js
に追加:module.exports = { plugins: ["prettier"], rules: { "prettier/prettier": "error" // Prettierのルールに反したらエラーにする }, // ... };
- 注意点
eslint-plugin-prettier
とeslint-config-prettier
は一緒に使うのが一般的です。eslint-config-prettier
でPrettierと競合するESLintのルールを無効にし、eslint-plugin-prettier
でPrettierのルールをESLintのエラーとして可視化します。
- インストール:
-
eslint-config-prettier の導入
ESLintの整形ルールとPrettierの整形ルールが衝突しないように、eslint-config-prettier
を利用します。これは、ESLintの整形に関するルールをすべて無効にし、Prettierに任せるためのものです。- インストール:
npm install --save-dev eslint-config-prettier
.eslintrc.js
のextends
に追加(最後の要素にすることが重要です。他の設定を上書きするため):module.exports = { extends: [ // 他のESLint設定 "prettier" // これを追加 ], // ... };
- インストール:
d. キャッシュのクリアと再起動
- VS Codeの再起動
VS Codeの拡張機能に関する問題は、VS Codeを完全に終了して再起動することで解決することが多いです。 - Prettierのキャッシュ
環境によっては、Prettierのキャッシュが原因で古い設定が適用され続けることがあります。その場合、エディタやターミナルを再起動したり、node_modules/.cache
ディレクトリを削除したりすると解決することがあります。
e. バージョンの確認
- Prettierや関連ツールのバージョン
Prettier、ESLint、それらのプラグインや拡張機能のバージョンが古いと、互換性の問題が発生することがあります。最新の安定版にアップデートしてみることも有効なトラブルシューティングです。
このオプションには以下の2つの設定があります。
"avoid"
: 引数が1つで括弧を省略できる場合は、括弧を省略します。"always"
: 引数が1つであっても、常に括弧を付けます。
それでは、それぞれの設定がコードにどのように影響するか、例を挙げて見ていきましょう。
例1: Prettierのデフォルト設定(arrowParens: "avoid"
と同等)
Prettierのデフォルトでは、arrowParens
は "avoid"
と同じ挙動をします。つまり、引数が1つの場合は括弧を省略します。
Prettierの設定ファイル (.prettierrc) がない場合、または以下の設定の場合
{
"arrowParens": "avoid"
}
整形前のコード
// 引数が1つで括弧がある場合
const greet1 = (name) => `Hello, ${name}!`;
// 引数が1つで括弧がない場合
const greet2 = name => `Hello, ${name}!`;
// 引数が複数ある場合
const add = (a, b) => a + b;
// 引数がない場合
const sayHello = () => console.log('Hello!');
Prettier適用後のコード
// 引数が1つで括弧がある場合 -> 括弧が省略される
const greet1 = name => `Hello, ${name}!`;
// 引数が1つで括弧がない場合 -> 変更なし
const greet2 = name => `Hello, ${name}!`;
// 引数が複数ある場合 -> 変更なし(元々括弧が必要)
const add = (a, b) => a + b;
// 引数がない場合 -> 変更なし(元々括弧が必要)
const sayHello = () => console.log('Hello!');
解説
greet1
のように、引数が1つで括弧が付いている場合でも、arrowParens: "avoid"
の設定ではその括弧が取り除かれます。これは、Prettierがコードをより簡潔にしようとするためです。他のパターンは、元のコードが既にルールに合致しているため変更されません。
この設定では、引数が1つであっても、常に括弧を付けます。
Prettierの設定ファイル (.prettierrc) に以下の設定がある場合
{
"arrowParens": "always"
}
整形前のコード
// 引数が1つで括弧がある場合
const greet1 = (name) => `Hello, ${name}!`;
// 引数が1つで括弧がない場合
const greet2 = name => `Hello, ${name}!`;
// 引数が複数ある場合
const add = (a, b) => a + b;
// 引数がない場合
const sayHello = () => console.log('Hello!');
Prettier適用後のコード
// 引数が1つで括弧がある場合 -> 変更なし
const greet1 = (name) => `Hello, ${name}!`;
// 引数が1つで括弧がない場合 -> 括弧が追加される
const greet2 = (name) => `Hello, ${name}!`;
// 引数が複数ある場合 -> 変更なし
const add = (a, b) => a + b;
// 引数がない場合 -> 変更なし
const sayHello = () => console.log('Hello!');
解説
greet2
のように、引数が1つで括弧が付いていない場合でも、arrowParens: "always"
の設定ではその括弧が追加されます。これにより、すべての矢印関数で引数の括弧の有無が統一され、一貫性のあるスタイルになります。
- 通常、プロジェクトのルートディレクトリにある
.prettierrc
ファイルでこのオプションを設定します。 - チーム開発では、この設定を統一することがコードの可読性と保守性を高める上で非常に重要です。
arrowParens
オプションは、プロジェクト全体のコードスタイルに影響を与えます。
ESLintとの連携による制御
Prettierはフォーマッタですが、ESLintはコードの品質とスタイルを強制するリンターです。ESLintにも矢印関数の括弧に関するルールがあり、これをPrettierと連携させることで、間接的にPrettierのarrowParens
の挙動を「推奨」または「強制」することができます。
方法1.1: eslint-config-prettier
を使用してESLintの競合ルールを無効化する
これは代替方法というよりは、PrettierとESLintを共存させるための最も重要な方法です。
eslint-config-prettier
は、ESLintの整形に関するルール(Prettierと競合する可能性のあるルール)をすべて無効にします。これにより、Prettierが整形を行い、ESLintは整形以外のコード品質チェックに集中できるようになります。
-
実装例 (.eslintrc.js)
module.exports = { extends: [ // 他のESLint設定 (e.g., 'eslint:recommended', 'plugin:@typescript-eslint/recommended') 'prettier', // これを**最後に追加**することで、prettierと競合するルールを無効化 ], // ... };
-
- これを導入しないと、ESLintがPrettierの整形結果(特に
arrowParens
による括弧の有無)をエラーと見なす可能性があります。 - したがって、
arrowParens
のPrettier設定を有効に機能させるためには、この設定が不可欠です。
- これを導入しないと、ESLintがPrettierの整形結果(特に
方法1.2: eslint-plugin-prettier
を使用してPrettierのルールをESLintのエラーとして表示する
このプラグインは、Prettierのフォーマットルールに従っていないコードをESLintがエラーとして報告するようにします。これにより、開発者はPrettierを直接実行する前に、ESLintの段階でフォーマットの不一致を検知できます。
-
実装例 (.eslintrc.js)
module.exports = { extends: [ // ... 'prettier', // まず競合を無効化 ], plugins: [ 'prettier', // prettierプラグインを有効化 ], rules: { 'prettier/prettier': 'error', // Prettierのルールに反したらエラーにする // 他のESLintルール... }, // ... };
-
なぜ代替方法として関連するか?
- Prettierの
arrowParens
設定に従わないコードをESLintが警告/エラーとして報告するため、チームにPrettierのルール(arrowParens
を含む)を強制する効果があります。 - PrettierをCI/CDパイプラインやpre-commitフックで実行する前に、開発段階でフィードバックを得られます。
- Prettierの
方法1.3: ESLintの arrow-parens
ルールを直接使用する (非推奨/注意が必要)
ESLintには、arrow-parens
という組み込みルールがあります。これはPrettierのarrowParens
と似た機能を提供します。
-
実装例 (.eslintrc.js)
module.exports = { // ... rules: { 'arrow-parens': ['off'], // Prettierと併用する場合はこのように無効化するのが一般的 // または、Prettierを使わない場合にESLintだけで制御する場合 // 'arrow-parens': ['error', 'always'], // 常に括弧を強制 // 'arrow-parens': ['error', 'as-needed'], // 必要な場合にのみ括弧を強制 }, };
-
なぜ非推奨/注意が必要か?
- PrettierとESLintを併用する場合、このESLintルールは通常無効化すべきです。
- Prettierが整形を行い、ESLintは整形以外のコード品質チェックを担当するのが一般的です。もしPrettierとESLintの両方でこのルールが有効で、かつ設定が異なっている場合、互いに上書きし合い、無限ループのようなフォーマットの不一致(「フリッピング」現象)が発生する可能性があります。
- したがって、Prettierを使用している場合は、
eslint-config-prettier
がこのルールを無効にしていることを確認するか、手動で無効にしてください。
-
なぜ代替方法として関連するか?
- Prettierを使用せずに、ESLintだけで矢印関数の括弧のスタイルを制御したい場合に利用できます。
-
設定オプション
"always"
: 常に括弧を強制。"as-needed"
: 必要な場合にのみ括弧を強制(引数が1つの場合は省略可能)。
エディタ/IDEの設定による一時的な上書き (非推奨)
多くのコードエディタ(VS Codeなど)のPrettier拡張機能には、arrowParens
を含むPrettierの設定を上書きするオプションが用意されています。
-
VS Codeでの例
- VS Codeの「設定」を開き、「Prettier: Arrow Parens」を検索します。
- ここで「always」または「avoid」を選択できます。
- しかし、これはプロジェクトの
.prettierrc
の設定を上書きしてしまうため、通常は「Use Prettierrc」を維持すべきです。
-
なぜ非推奨か?
- チーム開発においては避けるべきです。 個人の設定がプロジェクトの統一された設定と異なるため、コードのフォーマットが個人間で異なり、Gitの差分が不必要に発生したり、CI/CDでフォーマットエラーが発生したりする原因となります。
- あくまでデバッグや個人的な試行のための一時的な手段として使用し、最終的にはプロジェクトの
.prettierrc
ファイルを更新することが推奨されます。
-
なぜ代替方法として関連するか?
- プロジェクトの
prettierrc
ファイルを変更せずに、個人的な環境で一時的にarrowParens
の挙動を変更できます。
- プロジェクトの
Pre-commitフックによる強制
これはPrettierの設定そのものに代わるものではありませんが、arrowParens
を含むPrettierのルールがコードベース全体で確実に適用されるようにする強力な方法です。
-
実装例 (package.json)
{ "name": "my-project", "version": "1.0.0", "scripts": { "format": "prettier --write .", "lint": "eslint ." }, "devDependencies": { "prettier": "^3.0.0", "eslint": "^8.0.0", "husky": "^9.0.0", "lint-staged": "^15.0.0" }, "husky": { "hooks": { "pre-commit": "lint-staged" } }, "lint-staged": { "*.{js,jsx,ts,tsx,json,css,scss,md}": [ "prettier --write", "eslint --fix" ] } }
上記設定の後、
npx husky install
を実行してフックを有効にします。 -
なぜ代替方法として関連するか?
- 開発者がコミットする前に自動的にPrettierを実行し、
arrowParens
のルールを含むすべてのフォーマットルールを強制できます。これにより、フォーマットが崩れたコードがリポジトリにコミットされるのを防ぎます。 - 結果的に、
arrowParens
の意図しない変更や不一致を防ぎ、プロジェクト全体のコードスタイルを統一できます。
- 開発者がコミットする前に自動的にPrettierを実行し、
-
husky と lint-staged の組み合わせ
husky
はGitフックを簡単に設定できるツールです。lint-staged
は、Gitのステージングエリアにあるファイルに対してのみスクリプトを実行できるツールです。
PrettierのarrowParens
設定は非常にシンプルですが、その挙動を効果的に管理し、チーム全体で統一されたスタイルを維持するためには、ESLintとの適切な連携や、pre-commitフックによる自動化が重要な代替・補完手段となります。
基本的には、arrowParens
はPrettierの設定ファイル(.prettierrc
)で管理し、ESLintはeslint-config-prettier
でPrettierとの競合を避け、さらにeslint-plugin-prettier
でPrettierのルールをESLintのエラーとして可視化するのが、最も推奨されるアプローチです。
Prettier の「Arrow Function Parentheses」(矢印関数の括弧)に関する代替方法についてですね。
まず、Prettier は意見のある(opinionated)フォーマッタであり、多くの設定項目を持たないことを哲学としています。これは、コードのスタイルに関する議論をなくし、チーム全体で一貫したフォーマットを強制することを目的としているためです。
そのため、「Arrow Function Parentheses」の arrowParens
オプション ("always"
または "avoid"
) 以外のPrettier 自身の代替設定は存在しません。Prettierが提供しているのは、この2つの選択肢のみです。
しかし、もしこれらのPrettierのオプションだけでは満足できない場合や、特定のプロジェクト要件がある場合に考慮できる「代替手段」や「アプローチ」はいくつかあります。これらは厳密にはPrettierの代替設定ではなく、Prettierを補完したり、Prettierを使わない場合に検討される方法です。
ESLint の arrow-parens ルールを使用する
Prettier はフォーマットに特化していますが、ESLint はコード品質や特定のコーディングスタイル(フォーマットを含む)を強制するためのリンターです。ESLint には、まさにこの「矢印関数の括弧」に関するルール arrow-parens
が存在します。
- ESLintの arrow-parens ルール設定
"always"
: 常に括弧を要求します。{ "rules": { "arrow-parens": ["error", "always"] } }
"as-needed"
: 必要な場合のみ括弧を要求します(引数が1つの場合は省略可)。これは Prettier の"avoid"
に似ています。{ "rules": { "arrow-parens": ["error", "as-needed"] } }
"as-needed", { "requireForBlockBody": true }
: 引数が1つで関数本体がブロック({}
)の場合は括弧を要求し、それ以外では省略可能です。
この{ "rules": { "arrow-parens": ["error", "as-needed", { "requireForBlockBody": true }] } }
requireForBlockBody
は、Prettierにはない、ESLint独自のより細かい制御です。
Prettier と ESLint を併用する場合の注意点
最も一般的なのは、Prettier でフォーマットを行い、ESLint でコード品質のチェックを行う方法です。この場合、ESLint のフォーマットに関するルールが Prettier のルールと競合しないように設定することが非常に重要です。
そのため、通常は eslint-config-prettier
を利用して、ESLint のフォーマット関連ルールを無効にし、Prettier のフォーマットに任せるようにします。そして、arrowParens
の設定は Prettier の .prettierrc
で行います。
もし、Prettier の arrowParens
オプションではなく、ESLint の arrow-parens
ルールで細かく制御したい場合は、Prettier の arrowParens
オプションを削除(またはデフォルトの "avoid"
に設定し、ESLintで上書き)し、ESLint のルールを優先させることになりますが、これは推奨されません。Prettierはフォーマットの「真実の源」として機能し、ESLintは静的解析を行うのがベストプラクティスです。
フォーマッタを使用しない(手動でのフォーマット)
究極の代替手段ですが、コードフォーマッタを一切使用せず、開発者自身が手動でコードを整形する方法です。
- 欠点
チームで開発する場合、スタイルの一貫性が失われ、コードレビューでの議論が増えたり、プロジェクト全体でのコードベースが不均一になったりします。大規模なプロジェクトでは現実的ではありません。 - 利点
完全に個人の好みに合わせて括弧の有無を決定できます。
Prettier 以外のフォーマッタやリンターツールを使用することも選択肢です。
- StandardJS
ESLint の設定をバンドルしたもので、設定不要で一貫したスタイルを強制します。standard --fix
コマンドでコードを自動整形できます。 - dprint
Rustで書かれた高速なフォーマッタ。Prettierと同様に意見のあるフォーマッタですが、一部の柔軟性も持ち合わせています。 - Biome (以前の Rome)
新しいコードツールチェインとして登場した Biome は、リンター、フォーマッタ、バンドラーなどを統合したツールです。Prettier や ESLint の代わりとして、独自のフォーマットルールを持っています。arrowParens
のような細かい設定があるかどうかは、Biome のドキュメントを確認する必要があります。 - ESLint のフォーマット機能に完全に依存する
ESLint には--fix
オプションがあり、一部のフォーマット問題を自動修正できます。ESLint のルールのみで矢印関数の括弧を制御し、Prettier を使用しないという選択も可能です。- 利点
ESLint のルールが非常に豊富で、Prettier よりも詳細なフォーマット設定が可能です。 - 欠点
ESLint のフォーマット機能は Prettier ほど強力ではなく、すべてを自動で解決できるわけではありません。また、設定が複雑になりがちです。
- 利点
Prettier の arrowParens
に関しては、Prettier 自身の代替設定は用意されていません。 これは Prettier の設計思想によるものです。
もし Prettier の提供する "always"
または "avoid"
のどちらかの挙動では満足できない場合、
- ESLint の
arrow-parens
ルールをより細かく設定し、Prettier と ESLint の連携を適切に行う(ESLint が Prettier のフォーマットルールと衝突しないように設定する)のが最も現実的な「代替アプローチ」です。 - Prettier の使用をやめ、ESLint のフォーマット機能や他のフォーマッタツールに移行するという、より根本的な選択肢もあります。