Nuxt.js2.xでESLintの設定を読み解きつつ、airbnbのルールを追加設定してみた
はじめに
SSR をやりたいが、Vue.js2.x 系や Vuetify を利用した開発をしたいと思い、Nuxt.js を使った開発をやってみる事にした。開発の前には開発環境を整えるのがやっぱり重要なので、今回は CLI で Nuxt.js のプロジェクトを作成した後の ESLint の設定を確認しつつ、追加で airbnb のルールもチェックできるようにする設定をやってみたいと思う。
※公式にある "yarn create nuxt-app {project-name}" でアプリケーションを構築した際の設定は以下。
create-nuxt-app v5.0.0
✨ Generating Nuxt.js project in nuxt-test
? Project name: nuxt-test
? Programming language: JavaScript
? Package manager: Yarn
? UI framework: Vuetify.js
? Template engine: HTML
? Nuxt.js modules: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Linting tools: ESLint, Prettier, Lint staged files, Commitlint
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: jsconfig.json (Recommended for VS Code if you're not using typescript)
? Continuous integration: GitHub Actions (GitHub only)
? What is your GitHub username? yuta-katayama-23
? Version control system: Git
ESLint の設定
はじめにのような初期設定を行うと、ESLint の設定は以下のようになっている。
module.exports = {
root: true,
env: {
browser: true,
node: true,
},
parserOptions: {
parser: "@babel/eslint-parser",
requireConfigFile: false,
},
extends: ["@nuxtjs", "plugin:nuxt/recommended", "prettier"],
plugins: [],
// add your custom rules here
rules: {},
};
上記の ESLint の設定は 3 つを継承したルールになっている(その他の ESLint の設定項目についてはNode.js(ES6 で実装)における ESLint・Prettier の設定を 1 からやってみたなどを参照)。それぞれを少し整理すると、以下のようにまとめられるだろう。
@nuxtjs:@nuxtjs/eslint-config
Nuxt で ESLint を動かすための設定をしてくれるライブラリ
中身はindex.jsであり、eslint-plugin-vueなどを継承している。
plugin:nuxt/recommended:eslint-plugin-nuxt
Nuxt のための ESLint プラグインで、Nuxt のための基本的な ESLint の設定をここから継承している
.vue ファイルに対する ESLint を実行するたえに必要になるvue-eslint-parserもこのライブラリが設定してくれている。実際のコードで言うとbase.js。
ちなみに、parserOptions.parser は ESLint の configuration には存在しない(Specifying Parser Optionsを参照)が、vue-eslint-parser のparserOptions.parserによってそれが利用できるようになっているようである。
prettier:eslint-config-prettier
ESLint と Prettier のルール競合をオフにするもので詳細は
ESLint・Prettier を併用してコードスタイルのチェックは Prettier にまかせてみたを参照
上記のように設定ができている状態で、ESLint でチェックをすると以下のように意図した通りチェックができている事が確認できる。
$ yarn lint:js
yarn run v1.22.19
$ eslint --ext ".js,.vue" --ignore-path .gitignore .
/home/study/workspace/japan-specialty-map/pages/index.vue
94:3 warning The "asyncData" property should be above the "created" property on line 86 vue/order-in-components
95:9 error Unexpected isServer in asyncData nuxt/no-env-in-context
96:13 error 'foo' is assigned a value but never used no-unused-vars
99:3 warning The "fetch" property should be above the "created" property on line 86 vue/order-in-components
99:11 error Unexpected isClient in fetch nuxt/no-env-in-context
101:13 error 'foo' is assigned a value but never used no-unused-vars
✖ 6 problems (4 errors, 2 warnings)
// ESLintでエラーが出るようにわざと実装したindex.vue(抜粋)
<script>
export default {
async created() {
const a = () => {};
for (let index = 0; index < 10; index++) {
await a();
}
},
asyncData(context) {
if (context.isServer) {
const foo = "bar";
}
},
fetch({ isClient }) {
if (isClient) {
const foo = "bar";
}
},
};
</script>
上記の設定でもある程度の静的解析チェックができているが、for 文内での await などパフォーマンス上問題のあるコードに関してエラーが出ないなど不十分な部分もある。そこでそれらのチェックをしてくれる airbnb のルールも継承させる設定を追加する。追加で継承させるものは@vue/eslint-config-airbnbになる。設定の手順は公式に書いてある通り。
$ yarn add @vue/eslint-config-airbnb @rushstack/eslint-patch
上記のコマンドでインストールしたら、 .eslintrc.js に require("@rushstack/eslint-patch/modern-module-resolution") と '@vue/eslint-config-airbnb' を追記すればいい。
require("@rushstack/eslint-patch/modern-module-resolution")
module.exports = {
...
extends: ['@nuxtjs', 'plugin:nuxt/recommended', '@vue/eslint-config-airbnb', 'prettier'],
...
}
airbnb のルールが意図通り設定できているか?確かめるために、再度 ESLint のチェックを実行してみると、以下のように for 文内の await でエラー("no-await-in-loop")が出るようになっている(for 文内の awai の問題点についてはfor ループ内で await したら ESLint に too heavyweight って言われたから本当なのか試してみた ESLint の no-await-in-loop ルールの意味を参照)。
$ yarn lint:js
yarn run v1.22.19
$ eslint --ext ".js,.vue" --ignore-path .gitignore .
/home/study/workspace/japan-specialty-map/pages/index.vue
88:37 error Unary operator '++' used no-plusplus
89:7 error Unexpected `await` inside a loop no-await-in-loop
93:3 warning The "asyncData" property should be above the "created" property on line 86 vue/order-in-components
94:9 error Unexpected isServer in asyncData nuxt/no-env-in-context
95:13 error 'foo' is assigned a value but never used no-unused-vars
98:3 warning The "fetch" property should be above the "created" property on line 86 vue/order-in-components
98:11 error Unexpected isClient in fetch nuxt/no-env-in-context
100:13 error 'foo' is assigned a value but never used no-unused-vars
✖ 8 problems (6 errors, 2 warnings)
※parserOptions.parser の@babel/eslint-parser だが、この設定は初期段階では不要と思われる。@babel/eslint-parser というのはECMAScript の実験的な仕様「ECMAScript throw expressions」を使ってみたいので ESLint を設定してみたで触れていたように、実験的な仕様の構文をパースするためのもので、実験的な仕様の構文を利用していない場合には不要。
実際に、parserOptions.parser を削除した状態で ESLint でチェックを実行してみたが、問題なくチェックできている事が確認できた。
補足 ESLint のコマンドについて
はじめにのような初期設定を行うと、以下のように自動で script や
lint-staged の設定が行われるが、そのコマンドの意味について少し見ていきたいと思う。
{
...
"scripts": {
...
"lint:js": "eslint --ext .js,.vue --ignore-path .gitignore .",
"lintfix": "prettier --write --list-different . && yarn lint:js --fix",
"prepare": "husky install"
},
"lint-staged": {
"*.{js,vue}": "eslint --cache",
"*.**": "prettier --check --ignore-unknown"
},
...
}
eslint --ext ".js,.vue" --ignore-path .gitignore .
"eslint ." とすると、カレントディレクトリ(eslint コマンドを実行しているディレクトリ)のだいる全部に対する ESLint のチェックを実行する ただ、その中で ESLint のチェック対象を制限するために、--extというオプションで .js と .vue ファイルのみを解析対象に限定しつつ、--ignore-pathオプションで .gitignore に指定されているファイルは除外して ESLint のチェックを実行するようにしている
yarn lint:js --fix
これは上記の eslint --ext .js,.vue --ignore-path .gitignore . に--fixオプションを付けて実行するコマンドで、ESLint のチェック結果で違反があり、自動で修正できるものを修正するというコマンド
eslint --cache
これは lint-staged で git commit などの対象ファイルの内、.js と .vue ファイルに対して ESLint を実行するためのコマンドで、--cacheオプションにより、変更のあったファイルに対してのみ ESLint を実行するようにしている(lint-staged の詳細については依存モジュール(ライブラリ)のライセンスをチェックする仕組みを導入してみたなどを参照していただきたい)
※ lint-staged の方で、既に変更されたファイルに対してのみコマンドを実行するという設定ができているので、 eslint --cache とするのは冗長かもしれない(変更のあったファイルでしか ESLint でのチェックを行わないため)
まとめとして
今回は Nuxt.js2.x での環境構築として、ESLint の設定を読み解きつつ追加の設定を行ってみた。やはりこの設定のフェーズを飛ばしてしまうと、後で ESLint の設定を入れた時・最初からESLintを設定しない事で以下のような苦労をするので、最初に工数をケチらずにやるべきだろうなと改めて感じた。
既に実装されたコードが多くなると、ESLintによる修正が膨大になり、修正後に問題なく期待通りに動いているのか?の検証が難しくなる
保守をしていく上でコードの書き方のルールが静的解析のチェックルールで統一されていないことで保守がしずらい
潜在的なバグを埋め込むことになり、後で思わぬバグが出てしまう
お問合せはお気軽に
https://service.shiftinc.jp/contact/
SHIFTについて(コーポレートサイト)
https://www.shiftinc.jp/
SHIFTのサービスについて(サービスサイト)
https://service.shiftinc.jp/
SHIFTの導入事例
https://service.shiftinc.jp/case/
お役立ち資料はこちら
https://service.shiftinc.jp/resources/
SHIFTの採用情報はこちら
https://recruit.shiftinc.jp/career/