2018/03/01

Prettierの手の届かないところはESLintでカバーして自動整形する(prettier-eslint)



コードから手書きによるぬくもりを排除して、精神的安定を手に入れたい!




唐突だが、先日行われた「メタプログラミング勉強会@さくらインターネット」に参加して以来、「コードの整形とか人間がやる仕事じゃない!」と思うようになった。
人間の手で書くコードのぬくもりは時として作業効率を下げてしまう。だから、ぬくもりを排除したほうが精神的安定を得られるのではないかと。

ということで、今回はPrettierとESLintを併用して、保存時またはコミット前に自動フォーマットする方法をまとめる。

PrettierとESLintの違いと得意・不得意なこと


Prettierとは、自動でコードをフォーマットしてくれるツール。
ESLintとは、静的にコードをチェックしてくれるツール。オプションで自動フォーマットしてくれる。

Prettierの「ユーザが自由に変更できるルール」は15個と少ないので、単体では痒いところに手が届かないことがある(例えば、オブジェクトプロパティの縦位置をコロンで整列させたいとか)

対してESLintは膨大なルールで自分好みにカスタマイズできるが、本業が静的コードチェックツールなのでフォーマットでは非力なところがある。(例えば、1行が長いときの改行とか)

また、この2つのツールには似ている部分もあり、そのまま導入すると競合してしまう。
Prettierで自動フォーマットしたコードに対して、ESLintが「ここおかしい!」と怒ったり。

ということで、今回はPrettierとESLintを併用し、保存時またはコミット前に自動フォーマットする方法をまとめる。



prettier-eslintを導入する


Prettier単体ではカスタマイズできる余地が少なく既存プロジェクトの秩序を乱してしまう辛みがあったので、prettier-eslintを使って併用する。(prettier -> eslint --fixを実行するイメージ)

# npmでもyarnでもOK(例はnpmを使った場合)

# Prettierのインストール
$ npm i -D prettier

# ESLintのインストール
$ npm i -D eslint

# PrettierとESLintを統合するため
$ npm i -D prettier-eslint

# npm scriptsから実行するため
$ npm i -D prettier-eslint-cli


次にprettier.config.js.eslintrc.jsをつくる。このあたりの設定は、Options - prettierRules - ESLintを参照しながらお好みで。
// prettier.config.js
module.exports = {
    printWidth    : 120,      // デフォルトは80だけど1920x1080のディスプレイを使うと短すぎる
    tabWidth      : 4,
    useTabs       : false,
    semi          : true,
    singleQuote   : true,
    trailingComma : 'es5',
    bracketSpacing: true,
    arrowParens   : 'avoid',
    // rangeStart: 0,
    // rangeEnd: Infinity,
    // parser: 'babylon',
    // requirePragma: false,    // /** @format */ がついていないファイルはフォーマットしない
    // insertPragma: true,      // 先頭に /** @format  */を挿入する
    // proseWrap: 'preserve'
};
// .eslintrc.js
module.exports = {
    extends: 'recommended',
    rules: {
        'key-spacing': ['error', { align: 'colon' }],
    },
};


ここまでできたら後は実行するだけなのだが、毎回prettier-eslint src/**/*.js --writeと書いて実行するのは面倒なのでnpm scriptsに登録しておく。(--writeがないとフォーマット後に保存されないので注意)
// package.json
{
    // 略
    "scripts": {
        "format": "prettier-eslint src/**/*.js --write"
    }
    // 略
}

あとはnpm run formatをすれば、srcディレクトリ配下での拡張子jsのファイルが自動フォーマットされる。



ファイル保存時に自動フォーマットしたい


このままでは毎回npm run formatをしないとフォーマットされない。
gitのpre-commit hookでやるならそれでも良いのだが、やっぱりリアルタイムにフォーマットされている姿を見たい!

ということでonchangeというライブラリを使ってファイルを監視し、変更されたらformatを実行させる。

# onchangeをインストール
$ npm i -D onchange

// package.json
{
    // 略
    "scripts": {
        "format": "...",
        "watch": "onchange src/**/*.js -- prettier-eslint --write {{changed}}"
    }
    // 略
}

{{changed}}は変更を検知したファイルのパスが入るので、変更したファイルだけがprettier-eslintによりフォーマットされる。

あとはnpm run watchを実行しておくことで、保存時に自動フォーマットされる。


コミット時に自動フォーマットしたい


リアルタイムにフォーマットするには重たすぎるという場合は、gitのpre-commit hookを使うことでコミット時に自動フォーマットできる。

ただpre-commit hookは.gitディレクトリで作成するためバージョン管理対象外になってしまう。そこでpackage.jsonとライブラリを使う。
# git hookを作成してくれるhuskyをインストール
$ npm i -D husky

# stagingされたファイルでLintを実行してくれるlint-stagedをインストール
$ npm i -D lint-staged
// package.json
{
  "scripts": {
    "precommit": "lint-staged"
  },
  "lint-staged": {
    "*.js": ["prettier-eslint --write", "git add"]
  }
}

これでターミナルからgit add -m "hogehoge"とか、VSCodeなどのエディタからコミットするとprettier-eslintが実行され自動フォーマットしてくれる。



参考サイト






以上

written by @bc_rikko

0 件のコメント :

コメントを投稿