Prettier に再入門する

2017年に登場し、あっという間にJavaScriptコードフォーマッタのスタンダードになったPrettier。

github.com

非常に簡単に導入できるのだが、それゆえに、よく分かっていなくても使えてしまう。
導入時に設定ファイルをコピペするだけでどうにかなってしまうし、一度導入してしまえば、触ることはあまりない。

それではいかんということで、復習を兼ねて、導入方法や設定方法を調べた。

まずはPrettier単独での使い方を書き、次にESLintと組み合わせて使う方法を書く。

環境は以下。

  • node
    • 10.9.0
  • npm
    • 6.2.0
  • eslint
    • 5.5.0
  • prettier
    • 1.14.2
  • eslint-config-prettier
    • 3.0.1
  • eslint-plugin-prettier
    • 2.6.2

Prettier を単独で使う

まずはインストール。

npm i -D prettier

次に、例としてsrc/index.jsを作り、以下の内容にする。

function hoge() {
  console.log(1);
    console.log(2);
}



hoge() || hoge() || hoge() || hoge() || hoge() || hoge() || hoge() || hoge() || hoge() || hoge();

インデントがバラバラだし、ムダな改行もある。一行も長過ぎる。
このファイルに対してフォーマットをかける。

$ npx prettier src/だとエラーになるので、$ npx prettier src/*.jsを実行する

$ npx prettier src/*.js 
function hoge() {
  console.log(1);
  console.log(2);
}

hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge() ||
  hoge();

整形された結果が表示される。インデント、改行、一行の長さ、全部整理されている。
このように、特に何も設定しなくても適切な整形を行ってくれるのがPrettierの魅力。

先程のコマンドは修正結果を表示するだけなので、ファイルの上書き保存も行って欲しい場合は--writeオプションをつける。

$ npx prettier src/*.js --write
src/index.js 23ms

先程表示された内容で、実際に修正が行われる。

オプション

何も設定しなくても使えるPrettierだが、一部の設定は自分で変更することが出来る。

設定ファイルは.prettierrcJSONYAMLで書ける。
https://prettier.io/docs/en/configuration.html#docsNav

試しに、クォートの設定を変えてみる。

デフォルトだとダブルクォートを使うので、以下を対象に実行するとダブルクォートに変わる。

'hoge';
"fuga";
$ npx prettier src/*.js 
"hoge";
"fuga";

そこで、.prettierrcに以下のように記述して設定を変えてみる。

{
  singleQuote: true
}

こうすると、シングルクォートが使われる。

$ npx prettier src/*.js 
'hoge';
'fuga';

但し、JSXではこの設定は無視され、必ずダブルクォートが使われる。

Quotes in JSX will always be double and ignore this setting.

https://prettier.io/docs/en/options.html#quotes

オプションについての詳細はこのページで見れる。
https://prettier.io/docs/en/options.html

React

Reactのコンポーネントも、ちゃんと整形してくれる。

import React from 'react';

function myComponent() {
  return (
    <div>
    hoge
  </div>
  );
};
$ npx prettier src/component.js
import React from "react";

function myComponent() {
  return <div>hoge</div>;
}

もちろん--writeを使えば修正してくれる。

Vue

Vueファイルも対象になるが、templateの中身はあまりフォーマットしてくれなかった。

<template>
<div>
  {{greeting}}
<span>a</span></div></template>
<script>

export default {


data: function() {
    return {
  greeting: 'Hello'
    };
  }
}
</script>
$ npx prettier src/*.vue
<template>
<div>
  {{greeting}}
<span>a</span></div></template>
<script>
export default {
  data: function() {
    return {
      greeting: "Hello",
    };
  },
};
</script>

ESLint と組み合わせて使う

実際にはPrettierを単独で使うことは稀で、ESLintと組み合わせて使うのが一般的。
フォーマッタにはPrettierを使い、構文チェックやコーディングルールはESLintで行う。

ここでは、ESLintのなかでPrettierを使う方法を書く。

eslint-config-prettiereslint-plugin-prettierの2つを使うことでそれが可能になる。

eslint-config-prettier

github.com

eslint-config-で始まるコンフィグファイルを使うことで他人が書いた設定を取り入れることが出来るが、eslint-config-prettierは、Prettierと競合したりPrettierによって不要になるルールをオフにする設定。

Turns off all rules that are unnecessary or might conflict with Prettier.

これによって、ESLintとPrettierを共存させることが出来る。

$ npm i -D eslint-config-prettierした上で.eslintrcに次のように書く。

{
  "extends": ["prettier"]
}

この状態で$ npx eslint --print-config src/を実行すると、brace-stylecomma-styleなどの様々なルールが無効になっていることが分かる。

.eslintrcを以下のようにすると更に、"react/jsx-indent"などのReactに関するルールもオフになる。

{
  "extends": ["prettier", "prettier/react"]
}

eslint-plugin-prettier

github.com

ESLintでは、独自ルールの追加はプラグインで行う。

eslint-plugin-prettierを使うことで、ESLintでPrettierのルールが使えるようになる。

$ npm i -D eslint-plugin-prettierして.eslintrcを以下の内容にすると、Prettierのルールが有効になる。

{
  "plugins": [
    "prettier"
  ],
  "rules": {
    "prettier/prettier": "error"
  }
}
var obj = {
  hoge: 1,
  fuga: '2', // error  Replace `'2',` with `"2"`  prettier/prettier
};

オプションの設定も出来る。

{
  "plugins": [
    "prettier"
  ],
  "rules": {
    "prettier/prettier": ["error", {"singleQuote": true}]
  }
}
var obj = {
  hoge: 1,
  fuga: '2', // error  Delete `,`  prettier/prettier
};

prettier/recommended

プラグインでPrettierのルールを導入し、コンフィグファイルをextendsすることでESLint側の不要なルールをオフにしておく。
こうすることでESLintでPrettierを使えるようになるわけだが、実はこの設定は一行で書くことが出来る。

eslint-config-prettiereslint-plugin-prettierの両方をインストールした上で、.eslintrcを以下の内容にすればいい。

{
  "extends": ["plugin:prettier/recommended"]
}

これで、以下の効果がある。

This does three things:

  • Enables eslint-plugin-prettier.
  • Sets the prettier/prettier rule to "error".
  • Extends the eslint-config-prettier configuration.

https://github.com/prettier/eslint-plugin-prettier#recommended-configuration

余計なルールがオフになり、かつ、Prettierのルールがオンになる。

以下のように、オプションと組み合わせることも出来る。

{
  "extends": ["plugin:prettier/recommended"],
  "rules": {
    "prettier/prettier": ["error", {"singleQuote": true}]
  }
}

ESLint + Prettier で React をフォーマットする

Reactを対象にするためには、設定を加える必要がある。

{
  "extends": [
    "plugin:react/recommended",
    "plugin:prettier/recommended",
    "prettier/react"
  ],
  "rules": {
    "prettier/prettier": ["error", {"singleQuote": true}]
  },
  "parserOptions": {
    "sourceType": "module"
  }
}
  • "plugin:react/recommended"
    • React用のルールを追加する
  • "prettier/react"
    • その上で、Prettierと衝突するReact用のルールはオフにする
  • "sourceType": "module"
    • import/exportを使えるようにする

こうすると、Reactのコンポーネントに対してもESLintによるコーディングチェックとPrettierによるフォーマットを実行できるようになる。

import 'react';

function myComponent() {
  return (
    <div>
    hoge
  </div>
  );
};
4:10  error  Replace `(⏎····<div>⏎····hoge⏎··</div>⏎··)` with `<div>hoge</div>`  prettier/prettier
5:5   error  'React' must be in scope when using JSX                             react/react-in-jsx-scope
9:2   error  Delete `;`                                                          prettier/prettier