概要
- コードレビューの際、フォーマット崩れの指摘で摩耗しないためにJavaScript、SCSS、HTMLにフォーマッターを導入した際の備忘録です。
- 色々と右往左往してしまったので、今後の自分のためにも書き出してみました。
できたこと
- ESLintとPrettierを併用したJavaScriptの静的解析と自動フォーマット
- stylelintとPrettierを併用したSCSSの静的解析と自動フォーマット
- Prettierを使用したHTMLの自動フォーマット
できなかったこと
- HTMLの静的解析
- ESLintのようにローカル環境で実行できるプラグインを探していましたが当時は見当たらなかったため断念しました
- これいいよ!っていうプラグインがあったらぜひ教えてください
JavaScriptの静的解析とフォーマット
ESLint導入
JavaScriptの静的解析のためにESLintをインストールします。
$ npm install eslint --save-dev
.eslintrc
ファイルにルールを定義します。ゼロから独自のルールを定義するよりは、提供されているルールをカスタマイズする方が扱いやすいと思うので、今回は推奨設定を読み込んで一部だけカスタマイズしました。
-
env
: スクリプトが実行される環境を設定する -
extends
: 外部のルールを読み込む -
rules
: 一部ルールのカスタマイズ
{
"env": {
"browser": true,
"jquery": true,
"node" : true,
"es6": true
},
"extends": ["eslint:recommended"],
"rules": {
"eqeqeq": [
"error",
"always"
],
"no-multi-spaces": "error",
"no-labels": "error",
"yoda": [
"error",
"never",
{
"onlyEquality": true
}
]
}
}
ESLintとPrettierの連携
Prettierインストール
まずはPrettierをインストールします。
$ npm install prettier --save-dev
eslint-plugin-prettierインストール
ESLintで定義したルールを噛みつつ、Prettierでフォーマットできるように以下のプラグインをインストールします。
- eslint-plugin-prettier : ESLintとPrettierを連携させます
- eslint-config-prettier : Prettierと競合するESLintのルールを無効化します
$ npm install eslint-plugin-prettier eslint-config-prettier --save-dev
定義修正
Prettierと競合するESLintのルールは無効化されるため、フォーマット関係のルールはPrettierで定義します。
{
"env": {
"browser": true,
"jquery": true,
"node" : true,
"es6": true
},
"extends": ["eslint:recommended", "prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": ["error", {
"tabWidth": 4,
"singleQuote": true,
"semi": true,
"endOfLine": "lf"
}],
"eqeqeq": [
"error",
"always"
],
"no-multi-spaces": "error",
"no-labels": "error",
"yoda": [
"error",
"never",
{
"onlyEquality": true
}
]
}
}
これでeslint --fix
実行時にPrettierのフォーマットもしてくれるようになりました。
補足:prettier-eslintについて
上記のプラグイン以外に、prettier-eslintというプラグインもあります。こちらはPrettier定義のフォーマットをした後にESlintのfixを走らせるため、ESLintとPrettierで被るルールがある場合ESLintのルールが優先されます。
今回はこちらの記事を参考にeslint-plugin-prettierを採用しました。
個人的感触ですが、基本的には一元管理できるeslint-plugin-prettierが使いやすそう。どうしてもPrettierとESLintを別々に使いたいケースがあるのであればprettier-eslint、そうでなければeslint-plugin-prettierがいいかなと思いました。
SCSSの静的解析とフォーマット
stylelint導入
cssの静的解析のためstylelintをインストールします。
$ npm install stylelint --save-dev
.stylelintrc
ファイルにルールを定義します。ESLint同様、推奨ルールを読み込んで一部をカスタマイズしました。並び替え用のプラグインも追加しました。
$ npm install stylelint-scss stylelint-config-standard stylelint-config-idiomatic-order --save-dev
.stylelintrc
ファイルにルールを定義します。ESLint同様、推奨ルールを読み込んで一部をカスタマイズしました。並び替え用のプラグインも追加しました。
{
"pulugins": "stylelint-scss",
"extends": [
"stylelint-config-standard",
"stylelint-config-idiomatic-order"
],
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": ["extend", "include", "mixin"]
}
],
"string-quotes": "single",
"indentation": 4
}
}
補足:SCSS用の設定
stylelint-scssプラグインと、mixin
やextend
などのSCSS記法に対する警告を無視する設定が必要です。
はじめはこちらのissueを参考に以下の設定をしたのですが、scss/at-rule-no-unknown
の読込でエラーになってしまったため、今回はプロジェクトで使用していたSCSS記法を無視するように設定しました。
↓ やりたかったこと
{
"pulugins": "stylelint-scss",
"rules": {
"at-rule-no-unknown": null,
"scss/at-rule-no-unknown": true
}
}
↓ 今回の設定
{
"pulugins": "stylelint-scss",
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": ["extend", "include", "mixin"]
}
]
}
}
stylelintとPrettierの連携
stylelint-prettierインスト―ル
stylelintで定義したルールを噛みつつ、Prettierでフォーマットできるように以下のプラグインをインストールします。
- stylelint-prettier : stylelintとPrettierを連携させます
- stylelint-config-prettier : Prettierと競合するstylelintのルールを無効化します
$ npm install stylelint-prettier stylelint-config-prettier --save-dev
定義修正
-
extends
にstylelint-prettier/recommended
と追加すると連携が有効化されます。 - カスタマイズルールをstylelint側に定義したままだと無視されてしまうため、Prettier側の設定として記載を修正します。(
"prettier/prettier"
以下)
{
"pulugins": "stylelint-scss",
"extends": [
"stylelint-config-standard",
"stylelint-config-idiomatic-order",
"stylelint-prettier/recommended"
],
"rules": {
"at-rule-no-unknown": [
true,
{
"ignoreAtRules": ["extend", "include", "mixin"]
}
],
"prettier/prettier": [
true,
{
"singleQuote": true,
"tabWidth": 4
}
]
}
}
これでstylelint --fix
実行時にPrettierのフォーマットもしてくれるようになりました。
補足:prettier-stylelintについて
ESLintと同様に、stylelintにもprettier-stylelintというPrettier連携プラグインがあります。prettier-stylelintはprettier-eslintと似ていて、Prettier定義のフォーマットをした後にstylelintのfixを走らせるため、stylelintとPrettierで被るルールがある場合stylelintのルールが優先されます。
プロジェクトにはprettier-stylelintを導入していましたが、今回備忘録をまとめるにあたってstylelint-prettierの存在を知りました。stylelint-prettierはeslint-plugin-prettierと似た使用感なので、今後使うとしたらstylelint-prettierだなーと思って手順はそちらをまとめました。
HTMLのフォーマット
ほぼPrettierのデフォルト設定でフォーマットしました。変更した設定といえば1行の最大長を150にしたくらいです。
{
"printWidth": 150
}
今までに使用したプラグインの性質上、ここで定義した設定はJSやSCSSにも適用されてしまいます。各言語で異なる設定をしたい場合は、.eslintrc
や.stylelintrc
にそれぞれのPrettierルールを定義することで解決します。
自動フォーマット
VScodeで保存時にフォーマットさせる
プロジェクトではVSCodeを使っていたので、VSCodeにプラグインを導入します。保存時に自動修正できるようになるだけでなく、各linterの警告がエディタ上で可視化されるため開発しやすくなります。
上記のプラグインをインストールして、.vscode/.settings.json
に以下を追記すると、保存時の自動フォーマットが有効化されます。
{
"editor.formatOnSave": false, // 対象外のファイルを自動整形しないように
"editor.codeActionsOnSave": {
// For ESLint
"source.fixAll.eslint": true,
// For Stylelint
"source.fixAll.stylelint": true
},
"[html]": {
"editor.formatOnSave": true
}
}
コミット(ステージ)時に強制フォーマットさせる
Git上に必ずフォーマットされたコードがプッシュされるので、設定さえしてしまえばフォーマットに関する指摘はゼロになります。開発者によって使っているエディタが異なったり、フォーマッタの設定をしたつもりがうまく効いていなかったり…なんてケースに有効かも。
公式ドキュメント記載のPre-commit Hook導入方法をみると、オプション1のユースケースに当てはまるのでよさそうです。
Use Case: Useful for when you want to use other code quality tools along with Prettier (e.g. ESLint, Stylelint, etc.) or if you need support for partially staged files (git add --patch).
手順に従ってhuskyとlink-stagedをインストールして、package.json
に設定を追加しました。
{
"lint-staged": {
"*.html": [
"prettier --write",
"git add"
],
"*.js": [
"eslint --fix",
"git add"
],
"*.scss": [
"stylelint --fix",
"git add"
]
}
}
これでステージの際にhtml, js, scssファイルがフォーマットされるようになりました。