1. akisx

    Posted

    akisx
Changes in title
+TypeScriptプロジェクトにコードフォーマッタPrettierを導入する
Changes in tags
Changes in body
Source | HTML | Preview
@@ -0,0 +1,181 @@
+TypeScriptのプロジェクトへのPrettierの導入紹介です。
+
+## Prettierとは
+
+https://github.com/prettier/prettier
+
+Prettierはコードフォーマッタです。JavaScript(ES2017含む)、JSX、Vue、Flow、TypeScript、CSS(Less,SCSS)、JSON、GraphQL、Markdownとフロントエンド開発で使われる言語/仕様に多く対応しています。適用することでコードに一貫したスタイルをもたらします。
+
+一貫したスタイルは読みやすさ、ひいては保守性につながる大正義です。
+
+また、後述するように保存時に実行するように設定すれば、整形を自動化できるので見た目の調整に煩わされることなくコードが書けます。途中見た目を多少雑に書いても平気なので本当に快適です。一度導入するとなしには戻れないです。
+
+GitHubスターはリリースから一年ちょっとで2万近く(2018/01現在)、React本体やBabel、Redux、Material-UI等のメジャーどころでも採用されていることから、しばらくは廃れる心配もないでしょう。[^1]
+
+デメリットなんてPrettierのスタイルが気に入らない場合がある、くらいのもので現状導入しない理由はないと思います。
+
+
+### Linterじゃだめなの?
+
+同じようにコードを静的解析するツールとしてLinterがありますが、Linterがカバーできないものもあります。例えばコードの行の最大長です。`max-len`で検出は可能ですが整形までは行えません。
+
+例を出すとTSでReduxを書いていると、次のようなコードが出てきます。1行が長くなりがちで、またどこで改行するかは人によってブレやすいやつです。
+
+```ts
+type FooAction = Foo1Action | Foo2Action | Foo3Action | Foo4Action | Foo5Action | Foo6Action | Action;
+```
+
+これをスパッと下のように整形し、スタイルを統一してくれます。
+
+```ts
+type FooAction =
+ | Foo1Action
+ | Foo2Action
+ | Foo3Action
+ | Foo4Action
+ | Foo5Action
+ | Foo6Action
+ | Action;
+```
+
+一方でPrettierの守備範囲はあくまでフォーマットとそのルール(最大長`max-len`や空白`keyword-spacing`といったもの)です。未使用変数の宣言(`no-unused-vars`)などのバグの温床の検出はLinterに任せましょう。
+
+## 導入
+
+Prettierをインストールします。
+
+```sh
+yarn add prettier --dev --exact
+# or
+npm install --save-dev --save-exact prettier
+```
+
+## Option設定
+
+Prettierは"Opinionated Code Formatter"を謳っているのであまりあれこれ設定するものではないと思いますが、個人やチームの方針もあるので必要があればOption設定しましょう。
+
+Prettierの設定方法は以下の3通り。
+
+- `.prettierrc`ファイルを用意しYAMLまたはJSONで記述する
+- `prettier.config.js`ファイルを用意し設定オブジェクトをexportする
+- `package.json`に`"prettier"`キーを用意し記述する
+
+`.prettierrc`であれば、こんな感じで書いてプロジェクトのルートディレクトリに置いてあげればOK。設定できる項目についてはhttps://prettier.io/docs/en/options.html を。
+
+```json:.prettierrc
+{
+ "singleQuote": true
+}
+```
+
+## TSLintと統合
+
+そのままではTSLintの設定と競合してフォーマットをかけた側からTSLintに怒られることになるので同居できるようにします。方針は、フォーマットに関するものはPrettierに一任しそれ以外をTSLintに任せる、です。
+
+`tslint-config-prettier`と`tslint-plugin-prettier`を利用します。
+
+### tslint-config-prettier
+
+https://github.com/alexjoverm/tslint-config-prettier
+
+`tslint-config-prettier`はTSLintの設定のうちPrettierと競合するものを無効化してくれるパッケージ。
+
+```sh
+yarn add prettier --dev tslint-config-prettier
+# or
+npm install --save-dev tslint-config-prettier
+```
+
+インストールしたら`tslint.json`の`extends`のケツに以下のように追加します。
+
+```json:tslint.json
+{
+ "extends": [
+ "tslint-react",
+ "tslint-config-prettier"
+ ]
+}
+```
+
+これでフォーマットに関係するルールが無効化されます。
+
+#### 衝突している設定を調べる
+
+`tslint-config-prettier`はPrettierとTSLintで衝突している設定があるかチェックするツールも提供しています。`package.json`に以下のように追加し、`yarn tslint-check`を実行すればOK。
+
+```json:package.json
+{
+ "scripts": {
+ "tslint-check": "tslint-config-prettier-check ./tslint.json"
+ }
+}
+```
+
+### tslint-plugin-prettier
+
+競合を解決する`tslint-config-prettier`に対し、`tslint-plugin-prettier`はTSLintのチェックをかけるときに一緒にPrettierのチェックもかけてリポートしてくれるプラグイン。
+
+```sh
+yarn add prettier --dev tslint-plugin-prettier
+# or
+npm install --save-dev tslint-plugin-prettier
+```
+
+インストールしたら`tslint.json`に以下のように追記します。
+
+```json:tslint.json
+{
+ "rulesDirectory": ["tslint-plugin-prettier"],
+ "rules": {
+ "prettier": true
+ }
+}
+```
+
+これでPrettierのスタイルに沿ってなければTSLintの警告がでるようになります。
+
+## VSCode連携
+
+僕のメインエディタがVSCodeなので。VimやEmacs、Atomなどメジャーなエディタであればプラグインがあるのでそれら利用の人は別途調べてください。
+
+まずはPrettierプラグイン https://marketplace.visualstudio.com/items?itemName=esbenp.prettier-vscode をインストールします。
+
+これで対象ファイルを開いた状態で`⌥+⇧+F(windows: alt+shift+F)`でフォーマットを走らせることができます。ただ毎回ショートカットうつのも面倒なので、保存時に自動的に走るようにするといい感じです。
+
+ユーザー設定`settings.json`に下の設定を入れてあげます。これで保存時に自動的にフォーマットされます。
+
+```json:settings.json
+{
+ "editor.formatOnSave": true
+}
+```
+
+どのファイルでも走るのが嫌であれば特定のファイルだけ対応させることもできます。
+
+```json:settings.json
+{
+ //*.ts
+ "[typescript]": {
+ "editor.formatOnSave": true
+ },
+ //*.tsx
+ "[typescriptreact]": {
+ "editor.formatOnSave": true
+ }
+}
+```
+
+僕の今のチームでは、保存時フォーマットの設定をルール付けして運用していますが、十分だと感じています。
+
+公式では他に`git commit`をフックしてコミット時にフォーマットする方法 (https://prettier.io/docs/en/precommit.html) が紹介されています。プロジェクトの体制に応じて運用方法を決めればよいでしょう。
+
+## 最後に
+
+コードスタイルには個人差がでますが、それらをチームで擦り合せルール運用しても労力に見合いません。だったらいっそPrettierのスタイルに寄せて自動化してしまいましょう。
+
+細々したスタイルをレビューで指摘し手作業で整形するのは終わりにしましょう!
+
+
+
+[^1]: むしろv1.10でPlugin機能が導入されPython/PHP/Swiftのプラグインが開発中など、さらに発展しそう。
+