JSXクォートの悩み解決!Prettierで一貫性のあるコードを手に入れる方法

2025-06-06

JSXはReactなどでUIを記述する際に使われるJavaScriptの拡張構文ですが、その属性値はHTMLの属性と同様に文字列として扱われます。この文字列を囲む際に、シングルクォート(')を使うか、ダブルクォート(")を使うかをPrettierで設定できます。

Prettierのデフォルト設定では、JSXの属性値にはダブルクォートが使用されます。これは、JSXがHTMLにルーツを持つことや、ブラウザの開発者ツールがHTMLを常にダブルクォートで表示するという慣習に基づいています。

しかし、JavaScriptの文字列リテラルではシングルクォートを使うことが多い(singleQuote オプションで設定可能)ため、JSXの属性値だけダブルクォートになることに違和感を感じる開発者もいます。

そこで、Prettierには以下のオプションが用意されています。

  • jsxSingleQuote: このオプションを true に設定すると、JSXの属性値がシングルクォートでフォーマットされます。デフォルトは false (ダブルクォート) です。


  • jsxSingleQuote: true

    <div className='app'>Hello, React!</div>
    
  • <div className="app">Hello, React!</div>
    

この jsxSingleQuote オプションを使うことで、JSXの属性値における引用符のスタイルをプロジェクト全体で統一し、コードの一貫性を保つことができます。これにより、開発者間でのスタイルに関する議論を減らし、コードレビューの効率化にも貢献します。

この設定は、通常 .prettierrc などのPrettier設定ファイルに記述します。

{
  "singleQuote": true,  // JavaScriptの文字列リテラルをシングルクォートにする
  "jsxSingleQuote": true // JSXの属性値をシングルクォートにする
}


Prettierの「JSX Quotes」に関する一般的なエラーとトラブルシューティング

Prettierの「JSX Quotes」は、JSX属性値の引用符スタイル(シングルクォートまたはダブルクォート)を制御する設定ですが、これに関連していくつかの一般的な問題が発生することがあります。

設定が意図通りに適用されない

問題
.prettierrc などで jsxSingleQuote: true (または false) と設定しているにもかかわらず、Prettierが期待通りの引用符スタイルでフォーマットしてくれない。

原因

  • キャッシュの問題
    エディタやPrettierが古い設定をキャッシュしている可能性があります。
  • Prettierが実行されていない
    ファイル保存時にPrettierが自動実行されていない、または手動でPrettierを実行していない。
  • Prettierのバージョンが古い
    古いバージョンのPrettierでは、特定のオプションがまだサポートされていない、または挙動が異なる場合があります。
  • 設定ファイルの読み込み順序や競合
    複数のPrettier設定ファイルが存在する場合(例: プロジェクトルートの .prettierrc とサブディレクトリのそれ)、またはVS CodeなどのエディタのPrettier拡張機能の設定がプロジェクト設定を上書きしている場合。

トラブルシューティング

  • キャッシュのクリア
    • VS Codeの場合、Ctrl+Shift+P (または Cmd+Shift+P) でコマンドパレットを開き、「Prettier: Clear editor cache」を実行してみます。
  • Prettierの手動実行
    • ターミナルで npx prettier --write . (または対象ファイル)を実行し、手動でフォーマットされるか確認します。これにより、エディタの自動フォーマット設定とは別に問題があるかを切り分けられます。
  • Prettierのバージョン確認
    • npm view prettier version または yarn why prettier で、現在使用しているPrettierのバージョンを確認し、最新版に近いか確認します。
  • Prettierの再起動/再インストール
    • VS Codeなどのエディタを使用している場合、エディタを再起動してみます。
    • プロジェクトの node_modules を削除し、npm install または yarn install でPrettierを再インストールしてみます。
  • 設定ファイルの確認
    • プロジェクトルートに .prettierrcprettier.config.jspackage.jsonprettier フィールドなど、Prettierの設定ファイルが正しく存在するか確認します。
    • 他の場所にPrettierの設定ファイルが隠れていないか確認します(例: ~/.prettierrc など)。
    • エディタのPrettier拡張機能の設定を確認し、プロジェクト設定を上書きするような設定がないか確認します。

ESLintとの競合

問題
PrettierはJSX属性値をシングルクォートにしようとするが、ESLintがダブルクォートを要求し、修正するたびに無限ループに陥る。または、ESLintが警告/エラーを出す。

原因
ESLintにも文字列の引用符スタイルを制御するルール(例: quotesjsx-quotes)があり、Prettierの設定と競合しているためです。

トラブルシューティング

  • ESLintルールの手動設定
    • 特定のESLintルール(quotes@typescript-eslint/quotes など)を off にするか、Prettierの設定に合わせて変更します。
    • 例えば、Prettierで jsxSingleQuote: true にしている場合、ESLintの react/jsx-quotes'off' にするか、["error", "prefer-single"] に設定します。
    • しかし、これは手動での管理が煩雑になるため、eslint-config-prettier を使う方が良いです。

部分的にスタイルが適用されない

問題
一部のJSX属性値は設定通りにフォーマットされるが、別の属性値はそうならない。

原因

  • Prettierが認識しない構文
    カスタムのJSXライブラリや特殊な構文を使用している場合、PrettierがそれをJSXとして正しく認識できない可能性があります。
  • 構文エラーや解析エラー
    コードに構文エラーがある場合、Prettierがその部分を正しく解析できず、フォーマットをスキップすることがあります。
  • Prettierのignore設定
    .prettierignore ファイルに該当ファイルやディレクトリが記載されている場合、Prettierはそのファイルを無視します。

トラブルシューティング

  • Prettierのプラグイン
    • もし特殊な構文を使用している場合、Prettierがその構文をサポートするためのプラグインを提供している可能性があります。関連するPrettierプラグインのドキュメントを確認します。
  • 構文エラーの修正
    • フォーマットされないコードブロックに構文エラーがないか確認し、修正します。エディタのLinterや構文ハイライトが役立ちます。
  • .prettierignore の確認
    • .prettierignore ファイルを開き、フォーマットされないファイルやディレクトリが記載されていないか確認します。

CI/CDパイプラインでのエラー

問題
ローカルでは問題なくフォーマットされるが、CI/CDパイプライン(例: GitHub Actions)でフォーマットエラーが発生する。

原因

  • 依存関係の欠如
    CI/CD環境でPrettierが正しくインストールされていないか、必要な依存関係が不足している。
  • 環境の違い
    ローカル環境とCI/CD環境でPrettierのバージョンや設定ファイルが異なる、またはNode.jsのバージョンが異なる。

トラブルシューティング

  • ログの詳細確認
    • CI/CDパイプラインのログを詳細に確認し、エラーメッセージから具体的な原因を探ります。
  • インストールコマンドの確認
    • CI/CDスクリプトで npm install または yarn install が正しく実行され、Prettierがインストールされていることを確認します。
  • バージョンの一致
    • package.jsondependencies または devDependencies でPrettierのバージョンを固定し、CI/CD環境でも同じバージョンがインストールされるようにします。

これらのトラブルシューティング手順は、Prettierの「JSX Quotes」に限らず、Prettier全般の問題解決に役立ちます。問題が発生した際は、これらの点を確認してみてください。 Prettierの「JSX Quotes(JSX クォート)」に関する一般的なエラーやトラブルシューティングについてご説明します。主な問題は、Prettierの設定と他のツール(特にESLint)の設定との競合から生じることが多いです。

JSXの引用符が期待通りにならない

問題
jsxSingleQuote: true を設定しているのに、JSXの属性値がダブルクォートのままになる、または逆に false なのにシングルクォートになってしまう。

原因とトラブルシューティング

  • Prettierが実行されていない

    • ファイルを保存してもフォーマットが適用されない場合、Prettierが実行されていない可能性があります。
    • VS Codeの場合、Ctrl + Shift + P (または Cmd + Shift + P) でコマンドパレットを開き、「Format Document With...」を選択し、Prettierが選択されていることを確認してください。
    • package.json のスクリプトで prettier --write . などを使って手動でフォーマットを試してみてください。
  • 古いPrettierのバージョン

    • 非常に古いPrettierのバージョンでは、jsxSingleQuote オプションが存在しないか、期待通りに動作しない可能性があります。Prettierを最新バージョンに更新してみてください。
  • singleQuote オプションとの混同

    • PrettierにはJavaScriptの通常の文字列リテラルを制御する singleQuote オプションと、JSXの属性値を制御する jsxSingleQuote オプションの2つがあります。
    • 「JavaScriptの文字列はシングルクォートにしたいが、JSXの属性はダブルクォートにしたい」といったように、両方を設定する場合、それぞれのオプションを適切に設定する必要があります。
    • 例:
      // .prettierrc
      {
        "singleQuote": true,  // JavaScriptの文字列はシングルクォート
        "jsxSingleQuote": false // JSXの属性はダブルクォート
      }
      
    • .prettierrc.prettierrc.json.prettierrc.js などの設定ファイルがプロジェクトのルートディレクトリに存在するか確認してください。
    • VS Codeなどのエディタを使用している場合、Prettier拡張機能が正しく有効になっているか、またワークスペース設定でPrettierをデフォルトのフォーマッターとして設定しているか確認してください。
    • まれに、.editorconfig ファイルが存在する場合、Prettierがその設定を優先することがあります。.editorconfig に引用符に関する設定(quote_type など)が含まれていないか確認し、もしあればPrettierの設定と一致させるか、削除を検討してください。

問題
Prettierで特定の引用符スタイルにフォーマットしても、ESLintが別の引用符スタイルを要求し、エラー(または警告)が発生する。

原因とトラブルシューティング

  • ESLintの quotes または jsx-quotes ルールとの競合
    • ESLintには、JavaScriptの文字列リテラルに適用される quotes ルールと、JSXの属性に適用される jsx-quotes ルールがあります。これらのルールがPrettierの設定と異なる場合、競合が発生します。

解決策

  1. ESLintの jsx-quotes ルールを手動で設定する
    eslint-config-prettier を使わない場合や、特定の理由で手動で制御したい場合は、ESLintの jsx-quotes ルールをPrettierの jsxSingleQuote 設定に合わせて調整します。

    • jsxSingleQuote: true の場合(シングルクォートを使いたい)

      // .eslintrc.json
      {
        "rules": {
          "jsx-quotes": ["error", "prefer-single"]
        }
      }
      
    • jsxSingleQuote: false の場合(ダブルクォートを使いたい、Prettierのデフォルト)

      // .eslintrc.json
      {
        "rules": {
          "jsx-quotes": ["error", "prefer-double"]
        }
      }
      
    • 注意点
      jsx-quotes はESLint v8.53.0で非推奨となり、@stylistic/eslint-plugin-js に移行されています。最新のESLint環境では、該当するプラグインのルールを確認してください。

  2. VS Codeの「Format on Save」設定を確認する
    PrettierとESLintの拡張機能が両方インストールされている場合、どちらが保存時にフォーマットを実行するか競合することがあります。VS Codeの設定で、デフォルトのフォーマッターがPrettierになっているか確認し、ESLintの「Format on Save」関連の設定を無効にするか、PrettierのフォーマットにESLintを統合する設定 (eslint.format.enable) を使用します。

    • settings.json の例:
      {
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "editor.formatOnSave": true,
        "eslint.enable": true,
        "eslint.format.enable": true // ESLint経由でPrettierのフォーマットを適用する場合
      }
      
      通常は editor.defaultFormattereditor.formatOnSave を設定し、eslint-config-prettier を使うのが最もシンプルで推奨される方法です。

問題
JSXの属性値内で、引用符(シングルクォートやダブルクォート)自体を含む文字列を使うと、Prettierが期待通りにフォーマットしない、またはエラーになる。

原因とトラブルシューティング

  • JSXの属性値内では、通常の文字列リテラルとは異なり、属性値に含める引用符をエスケープできません。別の引用符タイプを使用する必要があります。


    • // シングルクォートを使いたいが、文字列内にシングルクォートがある場合
      <div data-value="It's a test" /> // このようにダブルクォートにする必要がある
      // または
      <div data-value={`It's a test`} /> // テンプレートリテラルを使用する
      
    • Prettierは、このルールに従って、文字列内の引用符の数を考慮して最適な引用符スタイルを自動で選択します。開発者が手動でエスケープする必要がある場面はほとんどありません。

  • Prettierは、文字列内のエスケープ文字の数を最小限に抑えるように引用符を選択する傾向があります。

    • 例: 'It\'s a "test"' のような文字列は、"It's a \"test\"" よりもシングルクォートが少ないため、シングルクォートが優先される可能性があります。


Prettierの設定例

Prettierの設定は、通常、プロジェクトのルートディレクトリにある .prettierrc または .prettierrc.json ファイルに記述します。

ここでは、jsxSingleQuote オプションに焦点を当てて説明します。

jsxSingleQuote: false の場合 (デフォルト設定)

この設定は、JSXの属性値にダブルクォート (") を使用するようにPrettierに指示します。これはPrettierのデフォルトの挙動です。

.prettierrc ファイル

{
  "singleQuote": false,  // JavaScriptの文字列リテラルはダブルクォート (デフォルト)
  "jsxSingleQuote": false // JSXの属性値はダブルクォート (デフォルト)
}

フォーマット前のコード (index.jsx)

import React from 'react';

function App() {
  return (
    <div className='app-container' data-id='123'>
      <h1 title="Welcome to My App">Hello, World!</h1>
      <button onClick={() => console.log('Button clicked!')}>Click me</button>
      <input type="text" placeholder='Enter your name' />
    </div>
  );
}

export default App;

Prettierでフォーマット後のコード (index.jsx)

import React from 'react';

function App() {
  return (
    <div className="app-container" data-id="123">
      <h1 title="Welcome to My App">Hello, World!</h1>
      <button onClick={() => console.log('Button clicked!')}>Click me</button>
      <input type="text" placeholder="Enter your name" />
    </div>
  );
}

export default App;

解説

  • title="Welcome to My App" のように元々ダブルクォートだった部分は変更されません。
  • className='app-container'placeholder='Enter your name' のようにシングルクォートで記述されていた部分が、フォーマット後に className="app-container"placeholder="Enter your name" のようにダブルクォートに統一されています。

jsxSingleQuote: true の場合

この設定は、JSXの属性値にシングルクォート (') を使用するようにPrettierに指示します。

.prettierrc ファイル

{
  "singleQuote": true,  // JavaScriptの文字列リテラルはシングルクォート
  "jsxSingleQuote": true // JSXの属性値はシングルクォート
}

注意
通常、singleQuote: truejsxSingleQuote: true は一緒に設定されることが多いです。これにより、JavaScriptコード全体でシングルクォートが統一されます。

フォーマット前のコード (index.jsx)

import React from "react";

function App() {
  return (
    <div className="app-container" data-id="123">
      <h1 title='Welcome to My App'>Hello, World!</h1>
      <button onClick={() => console.log("Button clicked!")}>Click me</button>
      <input type="text" placeholder="Enter your name" />
    </div>
  );
}

export default App;

Prettierでフォーマット後のコード (index.jsx)

import React from 'react';

function App() {
  return (
    <div className='app-container' data-id='123'>
      <h1 title='Welcome to My App'>Hello, World!</h1>
      <button onClick={() => console.log('Button clicked!')}>Click me</button>
    <input type='text' placeholder='Enter your name' />
    </div>
  );
}

export default App;

解説

  • import React from "react"; の部分も、singleQuote: true の影響で import React from 'react'; に変更されています。
  • title='Welcome to My App' のように元々シングルクォートだった部分は変更されません。
  • className="app-container"placeholder="Enter your name" のようにダブルクォートで記述されていた部分が、フォーマット後に className='app-container'placeholder='Enter your name' のようにシングルクォートに統一されています。

JSXの属性値でJavaScriptの式を埋め込む場合、テンプレートリテラル (``) を使用することがあります。この場合、引用符のスタイルはjsxSingleQuote オプションの影響を受けません。


import React from 'react';

function App() {
  const className = 'dynamic-class';
  const dataId = 456;

  return (
    <div className={`app-container ${className}`} data-id={`${dataId}`}>
      <p>This is a paragraph.</p>
    </div>
  );
}

export default App;

このコードは、jsxSingleQuote の設定が true でも false でも変更されません。なぜなら、属性値全体が引用符で囲まれた文字列ではなく、JavaScriptの式(テンプレートリテラル)として扱われているためです。



Prettierの「JSX Quotes(JSX クォート)」に関する設定は、コードのフォーマットを統一するためのものです。したがって、代替手段というよりは、Prettierの機能を補完・連携させる方法や、Prettierを使用しない場合にどのように引用符スタイルを管理するかという視点での説明になります。

PrettierとESLintの連携 (推奨される代替手段/補完)

これは「代替手段」というよりは、Prettierを使用する際に最も推奨される運用方法です。Prettierはフォーマットに特化しているのに対し、ESLintはコード品質と潜在的なエラーの検出に特化しています。しかし、両者にはフォーマットに関するルールで重複が生じることがあり、競合すると問題が発生します。

競合を解消し、PrettierのJSX引用符設定を効果的に利用する方法

  • ESLintの jsx-quotes ルールをPrettierの設定に合わせる (非推奨だが可能)

    • 目的
      eslint-config-prettier を使用しない場合や、特定の理由でESLintのフォーマットルールも手動で管理したい場合に、JSXの引用符ルールをPrettierの設定と一致させます。
    • 設定例
      • Prettierで jsxSingleQuote: true の場合:
        // .eslintrc.json
        {
          "rules": {
            "jsx-quotes": ["error", "prefer-single"]
          }
        }
        
      • Prettierで jsxSingleQuote: false の場合:
        // .eslintrc.json
        {
          "rules": {
            "jsx-quotes": ["error", "prefer-double"]
          }
        }
        
    • 欠点
      PrettierとESLintの両方で同様のフォーマットルールを管理する必要があり、設定ミスや将来的なバージョンアップでの競合のリスクが高まります。eslint-config-prettier を使う方がはるかにシンプルで安全です。
    • 目的
      ESLintのフォーマット関連ルール(引用符に関するルールを含む)を無効にし、Prettierにフォーマットの全権限を委ねます。
    • 設定
      1. eslint-config-prettier をインストールします。
        npm install --save-dev eslint-config-prettier
        # または
        yarn add --dev eslint-config-prettier
        
      2. .eslintrc ファイルの extends 配列の末尾に 'prettier' を追加します。
        // .eslintrc.json
        {
          "extends": [
            // ... 他の設定 (例: "eslint:recommended", "plugin:react/recommended")
            "prettier" // これを最後に追加!
          ],
          "rules": {
            // Prettierと競合しない独自のESLintルールはここに記述
          }
        }
        
    • 利点
      Prettierの jsxSingleQuote 設定がESLintによって邪魔されることなく、一貫したJSX引用符スタイルが保証されます。ESLintは構文エラーや潜在的なバグのチェックに集中できます。これが最もクリーンな統合方法です。

エディタの自動フォーマット機能 (Prettierが統合されている場合)

多くのモダンなエディタ(VS Codeなど)には、ファイルを保存する際に自動でコードをフォーマットする機能があります。Prettierをエディタに統合している場合、この機能がPrettierの設定に従ってJSXの引用符を自動調整します。

  • VS Codeの場合
    1. Prettier拡張機能をインストールします。
    2. settings.json で以下を設定します。
      {
        "editor.defaultFormatter": "esbenp.prettier-vscode",
        "editor.formatOnSave": true
      }
      
    • 利点
      開発者が明示的にフォーマットコマンドを実行しなくても、常にPrettierの設定通りのJSX引用符スタイルが維持されます。

Git Hook の使用 (Prettierが統合されている場合)

コミット前にPrettierを自動的に実行するようにGitフックを設定することで、リポジトリにコミットされるすべてのコードがPrettierのルール(JSX引用符ルールを含む)に従うことを保証できます。

  • husky と lint-staged の使用
    1. huskylint-staged をインストールします。
      npm install --save-dev husky lint-staged
      # または
      yarn add --dev husky lint-staged
      
    2. package.json に設定を追加します。
      // package.json
      {
        "private": true,
        "scripts": {
          "prepare": "husky"
        },
        "lint-staged": {
          "*.{js,jsx,ts,tsx,json,css,scss,md}": "prettier --write"
        }
      }
      
    3. .husky/pre-commit ファイルを作成し、以下を記述します。
      #!/usr/bin/env sh
      . "$(dirname -- "$0")/_/husky.sh"
      
      npx lint-staged
      
    • 利点
      チームメンバー全員がPrettierをローカルで実行し忘れても、コミット時に必ずPrettierが適用され、JSX引用符スタイルの一貫性が強制されます。CI/CDパイプラインでのチェックも組み合わせることで、さらに堅牢になります。

Prettierを使用しない、あるいは導入が難しいプロジェクトの場合、JSX引用符のスタイルは以下の方法で管理できます。

  • コーディング規約と手動レビュー

    • チーム内で厳密なコーディング規約を定め、コードレビューでその規約が守られているかを確認します。
    • 利点
      ツールに依存せず、柔軟性があります。
    • 欠点
      人間の手作業に依存するため、間違いや見落としが発生しやすく、一貫性の維持が困難です。大規模なプロジェクトや大人数のチームでは非現実的です。
  • ESLintの jsx-quotes ルールのみを使用

    • Prettierのような総合的なフォーマッターがない場合、ESLintの jsx-quotes ルールを使って引用符スタイルを強制します。
    • 設定
      // .eslintrc.json
      {
        "rules": {
          "jsx-quotes": ["error", "prefer-single"] // または "prefer-double"
        }
      }
      
    • 利点
      フォーマッターなしで特定のスタイルを強制できます。
    • 欠点
      引用符スタイル以外のフォーマットはESLintでは制御できません。インデント、行の長さ、スペースなど、より広範なコードスタイルの一貫性を保つには不十分です。

Prettierの「JSX Quotes」自体に直接的な「代替メソッド」があるわけではなく、その目的はコードのスタイルを自動で統一することにあります。したがって、代替手段を考える場合、それは通常、**Prettierをより効果的に活用する方法(ESLintとの連携、エディタ統合、Git Hook)を意味するか、あるいはPrettierを使用しない場合にどのように引用符スタイルを管理するか(ESLint単独、手動レビュー)**を意味します。