まくろぐ

TypeScript コードを Prettier で自動整形する

更新:
作成:

Prettier とは?

/p/au8iu6u/img-001.png

Prettier は、TypeScript や JavaScript などのソースコードを自動フォーマットするためのツールです。 HTML や CSS など様々なファイルに対応していますが、主に TypeScript や JavaScript のフォーマッターとして使用されています。 実際にどのようにフォーマットされるかは、Playground のページ で試すことができます。

特徴と思想

Prettier の一番の特徴は、Opinionated(独断的な) コードフォーマッターであることを標榜していることです。 これは、ユーザーに自由なカスタマイズを許さず、「Prettier 自身が定義しているスタイルに強制的にフォーマットするよ」ということです(セミコロンの有無など最低限の設定はできます)。 これにより、コーディングスタイルに関する 不毛な議論を避ける ことができ、プロジェクト内のコーディングスタイルを簡単に統一することができます。

もちろん、自分がベストだと思っているスタイルでフォーマットすることはできなくなるかもしれませんが、そんな些細なことよりも、アプリケーション(成果物)を作り上げることに集中すべきだという考え方です。

Prettier がやらないこと

Prettier はあくまでコードのフォーマットのみを行います。 コードの意味を解析して危険な部分(潜在的バグ)を検出してくれたりはしないので、そういったことを行いたい場合は、他の静的解析ツール(ESLint など)を使う必要があります。 ESLint にもコードフォーマット機能がありますが、フォーマッターとしては Prettier が優れており、「Prettier による整形 + ESLint による静的解析」という形で組み合わせて使うのが一般的です。

あと、import 文のソートなど、一見やってくれてもよさそうなフォーマットもしてくれなかったりします。 これは、その import 順序がロジック的に意味を持っていたりする場合に、Prettier が判断できないからです。 このように、いろいろと想像と異なるフォーマット結果になることがありますが、そこにはちゃんと理由があります(参考: Rationale)。 あまり気にせずにそんなものだと考えるのがよいです。 ちなみに、ESLint の方には import 文のソートを行うプラグイン (eslint-plugin-import) があります。

Prettier をインストールする

Prettier は npm で簡単にインストールすることができます。 TypeScript のプロジェクトは作成済み で、package.json がすでに存在すると想定します。

### yarn の場合
$ yarn add prettier --dev --exact

### npm の場合
$ npm install prettier --save-dev --save-exact

Prettier は、パッチバージョンが上がるだけで、出力結果に微妙な差分が生まれる可能性があります。 そのため、インストール時のオプションとして --save-exact を指定することで、明確なバージョンを package.json の依存情報として保存することが推奨されています。 これにより、チームメンバー全員のフォーマット結果を確実に一致させることができます。

package.json(抜粋)
"devDependencies": {
  "prettier": "^2.3.0"  // こうではなく、
  "prettier": "2.3.0"   // こう書き込まれます。
}

あと、他のツール(VS Code など)に、このプロジェクトが Prettier を使用していることを知らせるために、設定ファイル(.prettierrc.json.prettierrc.yml)を作成しておきます。 拡張子を省略して .prettierrc というファイル名にすると、JSON 形式と YAML 形式のどちらでも記述できますが、エディタの補完機能などを有効にするために、.prettierrc.yml のように拡張子は明示しておいた方がよいでしょう。 特別な設定をしないのであれば、設定内容は空っぽで構いません(JSON 形式であれば {}、YAML 形式であれば本当に何も書かないでで OK)。

.prettierrc(JSON形式)の作成
$ echo {}> .prettierrc

行末セミコロンの省略や、引用符をシングルクォートにする、といった設定はしたいかもしれません。 カスタマイズに関しては後述しますが、こんな感じで設定できます(コメントを入れるために YAML 形式で記述しています)。

.prettierrc.yml(YAML形式)
semi: false # 行末のセミコロンは省略する
singleQuote: true # 引用符にはシングルクォートを使う

次に、Prettier に無視させたいファイル群を .prettierignore ファイルで指定しておきます。 フォーマットは、.gitignore と同様です。 Markdown ファイル (md) なども自動整形したいところですけど、Prettier は日本語の処理が弱いようなので無視無視。

.prettierignore
.next/
build/
*.html
*.md

正しく .prettierignore ファイルを記述できていれば、prettier --write . コマンド(後述)で、プロジェクト内のファイルをすべて整形できます。 作成した .prettierrc.prettierignore は、忘れずに Git リポジトリにコミットしてください。

Prettier を実行する

prettier コマンドの使い方

prettier コマンドにソースコードを食わせると、Perttier のスタイルに従ってフォーマットし直した結果を標準出力に出力してくれます。

$ npx prettier main.ts

-w (--write) オプションを付けて実行すると、フォーマット結果をそのファイルに書き戻します。 ディレクトリ名や グロブパターン で複数ファイルをまとめて処理できます。

# カレントディレクトリ以下のファイルを整形
$ npx prettier --write .

# src ディレクトリ以下のファイルを整形
$ npx prettier --write src

# src ディレクトリ以下の .ts、.tsx ファイルを整形
$ npx prettier --write src/**/*.{ts,tsx}

カレントディレクトリ以下のファイルをまとめて整形する場合は、先にどのファイルが整形対象になっているかを調べておくと安心です。 -l (--list-different) オプション、あるいは -c (--check) オプションを付けて実行すると、Prettier のフォーマットに従っていないファイルを一覧表示できます。

# カレントディレクトリ以下のファイルで整形対象になるものを確認
$ npx prettier -l .

npm スクリプト化

毎回 npx prettier ... と入力するのは面倒なので、npm スクリプト化しておきます。

package.json(抜粋)
{
  // ...
  "scripts": {
    "lint:prettier": "prettier --check src",
    "fix:prettier": "prettier --write src",
    // ...

これで、次のように簡単に Prettier によるフォーマットをかけられるようになります。

$ npm run lint:prettier  # 違反のチェックだけしたいとき
$ npm run fix:prettier   # 自動で fix 実行

npm スクリプト名は lintfix のようなシンプルな名前にしてもよいのですが、ここでは ESLint も導入することを考えて、詳細な名前を付けるようにしています(ESLint 側のスクリプトには lint:eslintfix:eslint という名前を付ける想定)。

Prettier と一緒に ESLint を使う場合

プロジェクトに ESLint を導入 している場合、Prettier によるフォーマットと ESLint による解析ルールが競合するので、その部分を無効にしておく必要があります。 これを簡単に行ってくれるのが、eslint-config-prettier パッケージ(ESLint プラグイン)です。 このパッケージは Prettier チームが正式に提供している ものなので、誰かが適当に作ったパッケージではなく、これを使うことをお勧めします。

### yarn の場合
$ yarn add eslint-config-prettier --dev

### npm の場合
$ npm install eslint-config-prettier --save-dev

あとは、ESLint の設定ファイルの extends プロパティの最後に prettier というコンフィグを追加するだけで OK です。

.eslintrc.yml(抜粋)
extends:
  - eslint:recommended
  - plugin:react/recommended
  - plugin:react-hooks/recommended
  - plugin:@typescript-eslint/recommended
  - plugin:@typescript-eslint/recommended-requiring-type-checking
  - prettier
☝️ ワンポイント 古い情報では、prettier/react コンフィグも必要と記載されてものがありますが、現在のバージョン(v8.x.x 以降)では prettier の指定だけで大丈夫です。

Prettier のカスタマイズ

Prettier のフォーマット方法は、.prettier.{json,yml,js} ファイルである程度カスタマイズできますが、Prettier はフォーマット関連のオプションをほとんど用意しておらず、可能な限りデフォルト設定のまま使うべきとされています。 なぜなら、スタイル設定による不毛な議論を防ぐことを一番の目的としているからです(参考: Prettier のオプションに対する思想)。 過去の経緯で追加されてしまったオプションは、今さら消すことができないという理由で残っているものがあり、これらも通常使うべきではありません。

  • 使わない方がよいオプションの例
    • arrowParens
    • jsxSingleQuote
    • jsxBracketSameLine
    • noBracketSpacing

そして、Prettier のデフォルトスタイルは十分に成熟したとし、今後はフォーマット関連のオプションは追加しない としています。 そんな中でもいくつかのオプションは使われることがあるので、下記にいくつか紹介しておきます。

printWidth (default: 80)
一行あたりの文字数がどれくらいであるべきかを指定します。ESLint の max-len(最大文字数)とは若干概念が異なり、実際にはこの値よりも長い行が出力されることはあります。各種フォーマッターで、最大文字数の設定を 100 や 120 にしているプロジェクトは多くありますが、Prettier は printWidth はあくまでデフォルトの 80 を使うことを推奨しています。80 文字を超える文字列リテラルや、深いネストによって 80 文字を超える場合は、Prettier はそのまま出力します。
semi (default: true)
行末のセミコロンの有無を指定します。デフォルトではセミコロンが付加されますが、JavaScript Standard Style ではセミコロンを省略する提案がされていますし、Next.js の create-next-app コマンドで出力される雛形コードもセミコロンなしのコードになっていたりします。将来的にセミコロンなしが主流になる可能性は十分にあります。
singleQuote (default: false)
文字列リテラルはデフォルトでダブルクォートで囲まれます。シングルクォートで囲みたいときは singleQuote オプションを true に設定します。多くのスタイルではシングルクォートが優先されているので、この設定だけは true にして使う人が多いかもしれません。ちなみに、この設定を true にしても、JSX コード内の文字列リテラルはダブルクォートで囲まれます(jsxSingleQuote という別オプションになっています)。
tralingComma (default: “es5”)
デフォルトでは、配列などの末尾要素の後にカンマ (,) を付加されます。"none" にするとカンマが付かなくなります。
.prettierrc の記述例(YAML形式)
printWidth: 100
semi: false
singleQuote: true
trailingComma: none

Prettier フォーマットを無効にするコメント

ソースコードの中で、部分的に Prettier フォーマットを無効にしたいときは、対象オブジェクトの前に prettier-ignore コメントを入れます。

// prettier-ignore
matrix(
  1, 0, 0,
  0, 1, 0,
  0, 0, 1
)

参考

関連記事

まくろぐ
サイトマップまくへのメッセージ