はじめに
この記事ではLaravel5.8
にESLint
とPrettier
を導入します。
Laravel
のMVCモデルでは、Viewの部分は *.blade.php
ファイルによって書くことが一般的です。
しかし最近では、JavaScriptの描画技術の幅やページの描画スピードの速さなどを理由として、bladeは完全に捨ててVue.jsにフロントエンドの全てを任せる構成をとるプロジェクトが多いと感じています。
今回、ESLintを導入する対象となったLaravel5.8
のプロジェクトは僕がPMをしているプロジェクトです。
このプロジェクトでも、Laravel
のbladeはほとんど使用しておらず、画面描画は resourses/js/
に置かれているVue.js
によって行っています。
今回の記事の対象者は、LaravelでVue.jsを使っているor使いたい方全てです。
なぜESLintとPrettierを使うべきなのか
**「なぜESLint
とPrettier
を併用して使うべきなのか」**ということについては、Laravel
に限らず、広く議論されていることですので、ここでは触れません。
この議論の結論を言えば、「ESLint
だけ導入」あるいは「Prettier
だけ導入」というのは諸事情があって微妙だからどちらも使おうね、ということです。
以下ではESLint
とPrettier
を導入するにあたり、僕が感じている利点について触れておきます。
集団開発でコードフォーマットが統一されていないのはかなりしんどい
「何を綺麗と感じるか」は人それぞれです。
しかし、一方で個々の感性が異なるために、しばしば地獄をみることになります。
- 「あれ?末尾のセミコロンは前全部消したはずなのにまたAさんが足し直してる、、、」
- 「キャメル?パスカル?命名規則が混在している、、、」
- 「シングルクォーテーションとダブルクォーテーションが混在している、、、」
これを十人十色などと言ってはいけません。阿鼻叫喚です。
コードのフォーマットや変数の命名規則が理由で議論が始まったりプルリクエストが通らないとしたら、せっかくLaravel
を使っているのにあなたの開発スピードは早いとは言えなくなりませんか?
- フォーマットや変数の命名規則は開発者間で統一する
- 開発者ごとのフォーマット調整による余計な差分はなくし、コードレビューの可読性をあげる
この重要性を理解しましょう。コードレビューは常にロジックにのみ集中するべきです。
1人で開発するからといってフォーマットが煩雑なのは許されない
僕の価値観では、コードというものは**「誰が見ても美しくあるべき」**です。あなたがフォーマッターを使わずに書いたコードは、他人が見ても必ず美しいと思えるでしょうか。また、開発者が感じる「美しさ」は誰が保証してくれるのでしょうか?
「ソースコードは1人で扱うから」とは言っても、いつかもう1人のメンバーが加わる場合もあります。
そう言った際に無駄なコストを払わないように、1人だとしてもフォーマットには基準を設けて整形しておくのがマナーだと僕は考えています。
ESlint
とPrettier
は非常に優秀なフォーマッターなので、**「ESLintとPrettierが共通のルールによって整形してくれたのだから信じよう」**と開発者は思うのです。
いつESLintとPrettierを導入するのか
上記で「ESLint
とPrettier
を導入しなさい」と布教したのですが、僕も最近になってようやくこれらのフォーマッターを導入したのです。
実は、ESLint
とPrettier
を導入するまでにGitHubでのcommitは500を超えており、そこそこの規模のプロジェクトになっていました。ですから、かなりの数の *.js
*.vue
ファイルが存在していました。
導入パターン
ESLint
を全てのファイルにかける(=現存する*.js
ファイルや*.vue
ファイルを一気に整形する)場合、非常にコンフリクトが発生しやすくなります。
対象の全てのファイルの全体に対して改行ポイントやスペース、コンマや命名規則、変数宣言や比較演算子などありとあらゆるコードを修正することを想像すれば「コンフリクトが発生しやすい」というのは火を見るより明らかです。そして、そのコンフリクトは激しくなりがちであることも理解できるでしょう。
ESLint
を導入するタイミングはおおよそ次のパターンに分類できます。
-
今からLaravelをセットアップするあなた
→後悔はさせないので、いますぐ導入しましょう。最もEasyです。このタイミングで気づいたあなたは偉い! -
すでにそこそこの規模になっているあなた
→プロジェクト全体で大きな変更がないタイミングを伺いましょう。そこそこの努力と忍耐が必要です。 -
かなりの規模になっていて集団開発が盛んになっているあなた
→この時点で何かしらのフォーマッターを入れていないのはまずい状況ですが、導入のタイミングも難しいです。大量のコンフリクトを覚悟して慎重にタイミングを見計らいます。開発者全体で打ち合わせなどをする必要があるかもしれません。
僕は2番に該当していたつもりですが、それでも一気にESLint
を全てのファイルにかけて本当に血の海を見ました。全ファイルが血を流して倒れました。
それでもなんとかコンフリクトが少なくなるようなタイミングを見計って行えば、ギリギリ耐えます。
あなたのフォーマッターへの想いだけを信じてください。
ESLintとPrettierを導入する
やっと本題です。しかしやることはそんなに多くありません。
今回は、プロジェクトの途中からESLint
とPrettier
を導入します。(上記での2or3番を想定しています。1番でももちろん全く問題なし!)
ここから先はLaravel
がどうこうというより、ESLint
とPrettier
自体をよく理解していることが重要です。
パッケージをインストールする
今回必要なパッケージは以下になります。たくさんあります。
以下のパッケージは開発時にしか必要ありませんので --save-dev
オプションをつけてインストールしてあげます。
$ npm install babel-eslint eslint eslint-config-prettier eslint-config-standard eslint-friendly-formatter eslint-loader eslint-plugin-html eslint-plugin-import eslint-plugin-jsx-a11y eslint-plugin-node eslint-plugin-prettier eslint-plugin-promise eslint-plugin-standard eslint-plugin-vue laravel-mix-eslint --save-dev
ESLintの設定ファイルを作成する
続いて、.eslintrc.js
ファイルを新しく作成します。
このファイルではESLintとPrettierの整形ルールを定めます。
$ cd yourLaravelProject
$ vim .eslintrc.js
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint',
},
env: {
browser: true,
},
extends: [
'standard',
'plugin:vue/recommended',
'plugin:prettier/recommended',
'prettier/vue',
],
plugins: [
'vue',
'prettier', // prettierをESLintと併用します
],
rules: {
// ESLintが使用する整形ルールのうち、自分がoffにしたいルールなどを指定する
'vue/no-v-html': 'off', // v-htmlの使用について
'vue/prop-name-casing': 'off', // Propsの変数の命名規則について
'no-console': 'off', // console.log()の使用について
'no-unused-vars': 'off', // 使われていない変数について
'camelcase': 'off', // camelcaseについて
// この先はPrettierのルール
"prettier/prettier": [
"error",
{
printWidth: 120,
tabWidth: 2,
useTabs: false,
singleQuote: true,
trailingComma: 'all',
bracketSpacing: true,
arrowParens: 'avoid',
semi: false,
},
]
}
}
この設定ファイルは結構厳しめにルールを設けているつもりです。
そもそもせっかくコードフォーマッターを導入するのにルールを緩くしておく必要はないからです。
しかし、もしプロジェクトの途中での導入に際してあまりルールを厳しく入れたくないという場合は、extends:[]
の部分を見直すと良いと思います。
このあたりは下記サイトが参考になりました。
(参考)Vue.jsスタイルガイドとeslint-plugin-vue検証ルールのマッピング
またPrettier
のルールもあなたの好みです。
Prettier
のルールは公式ドキュメントを参考に変更すると良さそうです。
(参考)Options - Prettier
ファイル変更時にESLintを使用する
webpack
が上記の整形ルールを使用してファイル変更をwatch
してくれるようにwebpack.mix.js
を編集します。
const mix = require('laravel-mix')
/*
|--------------------------------------------------------------------------
| Mix Asset Management
|--------------------------------------------------------------------------
|
| Mix provides a clean, fluent API for defining some Webpack build steps
| for your Laravel application. By default, we are compiling the Sass
| file for the application as well as bundling up all the JS files.
|
*/
// ESLintに関する設定(この部分を丸ごと追記するイメージです)
if (!mix.inProduction()) { // 本番環境ではESLintは使用しない
mix.webpackConfig({
module: {
rules: [
{
enforce: 'pre',
exclude: /node_modules/,
loader: 'eslint-loader',
test: /\.(js|vue)?$/,
},
],
},
})
}
// watchするファイルやポート番号などに関する設定(今回の内容とは関係ありません)
mix
.js('resources/js/app.js', 'public/js')
.sass('resources/sass/app.scss', 'public/css')
.browserSync({ // browserSyncの設定
files: ['resources/js/**/*', 'resources/sass/**/*', 'resources/views/**/*', 'public/css/**/*'],
port: 3000,
ui: {
port: 3001,
},
proxy: 'localhost:8000', //php artisan serveで立ち上げた8000番をProxyする
})
// 本番環境ではバージョン付けによるキャッシュ対策を施す(今回の内容とは関係ありません)
if (mix.inProduction()) {
mix.version()
}
これで基本的なセットアップは全て終了です。
$ npm run watch
を唱えることによっていつも通り開発を開始しましょう。コンソールでESLintとPrettierが大量のエラーを吐いてくれるはずです。
実際に動作を確認する
あなたのコンソールを見てください。
例えば次のようになっている場合、
/Users/yourName/Laravel/resources/js/pages/A/B.js
350:1 error Delete `····`
prettier/prettier
これはPrettier
が怒っている様子です。
このエラーが指し示すところは、
「/js/pages/A/
にあるファイルB.js
の350行目の1列目から無駄な空白があるから消せ」
ということです。
これらのエラーは地道に解消しても良いですが、あなたの見ているエラーの量を見てください。地獄ですよね。
でも安心してください、自動でこれらのエラーをほとんど解消してくれるESLint
のコマンドがあります。
エラーを吐いているファイル名とそのディレクトリを確認して、コンソールで
// ESLintとPrettierの両方を実行する
$ eslint resources/js/pages/*/*.js --fix
を実行しましょう。
ファイル名はresources/js/pages/*/*.js
のようにワイルドカードを使用して指定できます。
これによってresources/js/pages/*/*.js
に該当するファイルのエラーが自動で解消されていきます。
eslint ファイル名 --fix
コマンドによってESLintとPrettierの両方が実行されることに注意してください。
これはすでに上記で導入した eslint-config-prettier
の恩恵を受けています。
ESLintとPrettierの併用に関する詳しい説明は以下の記事などがわかりやすいと思います。
(参考)ESLint - Prettier連携のやり方と仕組み
これでLaravelの*.js
ファイルや*.vue
ファイルに対してESlintとPrettierを導入することができました。
どのようなエラーを吐いているかはあなたのプロジェクト次第です。
コンソールでのエラーを見ながら .eslintrc.js
ファイルで整形方法を調整しましょう。特定の整形ルールをoff
にすることもできますから、あなたの開発チームメンバーにとって最良の設定を記述し、幸せな開発サイクルを目指しましょう。
最後に
この設定を行ったことで、あなたのLaravelの*.js
ファイルや*.vue
ファイルは全ての開発者間でフォーマットが統一されました。
今後の展望としては
- git commitのときにESLintを自動で強制する
-
*.php
ファイルに対しても何かしらのLint
を施す
本記事ではこれらの設定はオーバーワークになりますので、別記事で紹介しようと思います。
長くなりましたが、ありがとうございました。