Prettier、はじめました。
最初に
JavaScriptの整形ツール"Prettier"を使い始めてみたので、試してみた内容を備忘録的にこちらに書き残していこうと思います。ま、今更感ありますがね。。。
基本的に情報は公式ドキュメントを参照しています。
Prettierをそのままで使い始めてみる
eslintなどと組み合わせるパターンもありますが、まずはそのままで使ってみようと思います。
対象のプロジェクトルートで下記のコマンドを入力して、Prettier
をインストールします。
yarn add prettier --dev --exact
あとは"fmt": "prettier --write src/**/*.js"
というように、package.json
内のscripts
にコマンドを定義して実行すれば、完璧です。
(--write
オプションで整形したコードで上書きます)
"scripts": {
"fmt": "prettier --write src/**/*.js"
},
追記: 複数の拡張子を対象にする
ちなみに下記のように設定することで、複数の拡張子に対応することができます。
これはかなり便利で、自分自身はよくこのように設定することが多いです。
"scripts": {
"fmt": "prettier --write **/*.{js,json,md,html}"
},
指定した階層以下すべてのファイルをprettierの対象とする
ちなみに下記のような書き方でprettierを実行した場合、階層の深さ自体も指定していることになります。
例えば、
prettier --write src/**/*.{js,json,md,html}
このような書き方をしている場合、下記のように格納されているファイルはprettier対象となりますが、
src/hoge/hoge.js
src/fuga/fuga.js
下記のファイルは対象になりません。
src/hoge.js
src/hoge/fuga/hoge.js
階層の深さは関係なく、src
配下の全ディレクトリ内にあるすべてのjsファイルをprettier対象としたい場合は下記のように指定する必要があります。
prettier --write 'src/**/*.js'
# または
prettier --write "src/**/*.js"
package.json
内に記述する場合は下記のようになります。
"scripts": {
"fmt": "prettier --write 'src/**/*.js'"
}
または、
"scripts": {
"fmt": "prettier --write \"src/**/*.js\""
}
もしカレント以下の全てのファイルのjs, json, md, html
ファイルをprettier
対象としたい場合は下記のようにpackage.json
内で設定すると良いと思います。
"scripts": {
"fmt": "prettier --write '**/*.{js,json,md,html}'"
}
package.json内でPrettierのオプションを設定する
package.json
内にPrettierのオプションを指定することもできるようなので、私は下記のようにオプションを指定しました。
"prettier": {
"singleQuote": true,
"semi": false
},
- セミコロンはいらない
- 文字列はシングルクォートにする
という二つの指定です。
今回の場合だと、あとはyarn run fmt
とコマンド叩くことで整形してくれます。
簡単ですね。
公式見てみるとCLI上でのオプションもたくさんありそうなので、色々と試してみるのも面白いかもしれません。
Prettier with Eslint
Eslint
と組み合わせて使う方法。
公式ドキュメントを意訳してみた。
ESLintを使用している場合、ワークフローにPrettierを統合するのは簡単です。 PrettierをESLintに統合するには、2つの異なる方法がありますが どちらか一方、またはその両方を有効にすることができます。
2つ方法があるらしいので、その2つとも試してみることにします。
Use ESLint to run Prettier
プロジェクトで既にESLintを導入していて、一回のコマンドで全てのスタイルチェックを実行するような場合、ESLintに対してPrettierの実行を依頼することができるようです。
eslint-plugin-prettier
を使ってESLintルールを適用したPrettierを追加するだけのようです。
試してみます。
yarn add --dev prettier eslint-plugin-prettier
公式を見ると、.eslintrc.json
に下記の記述を追記していました。
{
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error"
}
}
実際に自身の方で試してみたプロジェクトではjs形式の.eslint.js
でしたが、記述にあまり変わりはないので割愛します。一応こんな感じで足してみました。
diff --git a/.eslintrc.js b/.eslintrc.js
index 1256756..15dafce 100644
--- a/.eslintrc.js
+++ b/.eslintrc.js
@@ -11,6 +11,7 @@ module.exports = {
"parserOptions": {
"sourceType": "module"
},
+ "plugins": ["prettier"],
"rules": {
"indent": [
"error",
@@ -23,6 +24,12 @@ module.exports = {
"quotes": [
"error",
"single"
+ ],
+ "prettier/prettier": [
+ "error", {
+ "singleQuote": true,
+ "semi": false
+ },
]
}
};
実際に足してみたソース(shinshin86/Try-TodoList-At-Vue)
↑のコードの14行目と、28行目から33行目までの箇所が足した箇所となります。
これで普段通りeslint
を走らせると、prettierによるチェックが走ります。
prettierのデフォルトのルールだと、このプロジェクトでのeslintとのルールに差があるので、prettier側でめちゃくちゃエラーが出ました。
上のdiffにもある通り、ルールを変更しています。
--fix
オプションを付けたESLint
を走らせると、コード整形を行ってくれます。
Turn off ESLint's formatting rules
ESLintを使ってPrettierを実行する場合でも、別々に両方のツールを実行する場合でも、2つのフォーマット間で矛盾するルールというのが出てくると思います。
それを無効にする方法として(Prettierが気にしない他のルールを守りながら)、eslint-config-prettier
を使う方法が提示されています。
これが二つ目。
要は、ESLintとPrettierの処理で重複する部分を無効化してくれるツールということみたい。
導入は下記の手順。
yarn add --dev eslint-config-prettier
.eslintrc.json
に下記の記述を追加
{
"extends": ["prettier"]
}
公式ドキュメントによると、これによって無効になるルールが幾つかあるけど、
Prettierと矛盾する特定のオプションでそれらを使用しない限りはこちらのドキュメントを参考にそれらを戻すことができるそう。
ココらへんの細かいことについては、ちょっと実際に使ってみないとよくわからないので、後日機会見つけて試してみようと思います。
2つを有効にする
eslint-plugin-prettier
は、eslint-plugin-prettier
とeslint-config-prettier
の両方を有効にする「推奨」設定を公開しているようです。
下記の記述を.eslint.json
に記述します。
{
"extends": ["plugin:prettier/recommended"]
}
自身の場合は最終的に.eslint.js
がこんな感じになりました。
(先程のソースに上記設定を追加したもの)
"extends": [
"eslint:recommended",
- "plugin:vue/recommended"
+ "plugin:vue/recommended",
+ "plugin:prettier/recommended"
],
"parserOptions": {
"sourceType": "module"
},
- "plugins": ["prettier"],
"rules": {
"indent": [
"error",
こちらの設定を使うときは上記2つのプラグインが入っている必要があるので、最初から2つを有効にするのなら下記のコマンドでインストールすればOKです。
yarn add --dev eslint-plugin-prettier eslint-config-prettier
prettier-eslintを使ったやり方(追記)
eslintと併せて使う方法としては、下記のような方法もあるみたい
prettier-eslintを使うことでprettierで整形した結果をeslint --fixに渡すことができるようになります。
prettierの使い方 - Qiita (eslintと合わせて使う)
インストールするものは下記。
yarn add -D eslint prettier-eslint prettier-eslint-cli
precommitフック
precommitフックを利用すると、prettierを実行して整形したものだけをコミットすることができるようです。
公式ページのPrettier - Pre-commit Hookを見てみると、何種類かの方法を提案してくれていますが、今回は一番上のlint-staged
、husky
を使う方法を最小構成で試してみようと思います。
まずは必要なパッケージのインストール
yarn add prettier lint-staged husky --dev
package.json
にscripts
とlint-staged
を追加するので、package.json
は下記のようになります。
{
"scripts": {
"precommit": "lint-staged"
},
"lint-staged": {
"*.{js,json,css,md}": ["prettier --write", "git add"]
},
"devDependencies": {
"husky": "^0.14.3",
"lint-staged": "^7.0.4",
"prettier": "^1.11.1"
}
}
実際にサンプルコード書いて試してみます。
const sample = () => {
return 'hello prettier'
}
console.log(sample())
このような、なんの面白みもないサンプルコードを書いて、
git add sample.js
とした後、
yarn run precommit
すると、addされたファイルに対してのみprettier
を通してくれます。
あとは整形されたコードをcommitすればOKです。
const sample = () => {
return "hello prettier";
};
console.log(sample());
↑が整形後のコード。
ただ、こちらの方の記事を見てみると([prettierの使い方 - precommitフックを使う] (https://qiita.com/kiida/items/405bb07c4b52bfee0219#precommit%E3%83%95%E3%83%83%E3%82%AF%E3%82%92%E4%BD%BF%E3%81%86))、commit時に勝手に整形してくれているようですね。。。
Prettierの公式ドキュメント(Pre-commit Hook)を読んでみると、use caseのところに
Prettierの上にESLintなど、他のツールと共に使用する必要がある時などに便利です
と書かれているので、ここらへんは他のツールと連携ありきで使うものなのかもしれません。
(ここらへんの理解はまだ浅いので、もしかしたら解釈がおかしいかもしれませんが)
試しに参照させていただいた方の記事を参考に、eslintを組み合わせたやり方で実行してみたところ、コミット時に自動的に整形がされました。
追記
precommitフックの自動実行について、 @sounisi5011 さんよりコメントにて補足説明をいただきました!
こちらのコメント を読むと、どのようにコミット時に自動整形が行われているかが理解ができます。
(非常にわかりやすく説明していただいているのでgitフック
やhusky
、lint-staged
の理解が浅いと思われている方は一読をオススメします。→私はこのコメント読んでとても勉強になりました。)
エディターとの連携(Vim編)
私はVim
ユーザなので、Vimとの連携を試してみます。
sbdchd/neoformat, w0rp/ale, prettier/vim-prettierなど、複数種類があるようですが、私はsbdchd/neoformatを使った方法で設定します。
私の現在のメインVim環境がNeoVim&dein.vim
なのでplugin.toml
に下記のように記載します。
[[plugins]]
repo = 'sbdchd/neoformat'
プロジェクト内でprettier
がインストールされているケースでのみ使用したいと考えているので、下記のような記述をinit.vim
に記述します。。。
が、これ、めちゃくちゃスマートじゃないね💦
一応、下記を参考にしながら書いてみていますが、自身の未熟さを呪う、そんな春の昼下がり🌸
sbdchd/neoformat - Config [Optional]
"----------------------------------------------------
" JavaScript - Prettier
"----------------------------------------------------
let g:neoformat_javascript_prettier = {
\ 'exe': getcwd() .'/node_modules/.bin/prettier',
\ 'args': ['--stdin', '--no-semi', '--single-quote'],
\ 'stdin': 1,
\ }
可能であれば、プロジェクト単位で設定しているprettier
を反映させた形でformatしたいのだけど、パッと良い考えが浮かんでいないので、一旦はこちらで。
良い案浮かんだら更新します。
(これだとプロジェクトルート and prettierがプロジェクトにインストールされていないと動きません😱)
エディターとの連携(Atom編)
色々とやり方はありそうですが、私は公式が提供しているprettier-atom(Github)を導入することにしました。
下記のようにapmコマンドからinstallすることもできますが、
apm install prettier-atom
私は普通にGUI上からインストールしてしまいます。
インストールすると、依存関係上他にも必要なものがあるよとメッセージが出てくるので、諸々幾つかのパッケージもインストールしました。
インストール完了すると、GUI上からPrettierの設定が確認できるので、わかりやすいですね。
デフォルトだと、ctrl + alt + f
でprettierのformatを実行するようですが、保存時に自動で実行させたり実行するkey bindingを変えたりなどは設定からできるようなので、導入もしやすそうです。
というわけで、少しずつ使っていこうと思います。
参照
Prettier
prettierの使い方
sbdchd/neoformat
prettier/prettier-atom