Vue + TypeScriptなプロジェクトにESLintを導入する

TypeScript + VueなプロジェクトでESLintを使ってみて、現状必要なモジュールが複数あって少し複雑だったのでまとめておきます。

サンプルは以下です。 github.com

内容はどうでも良いんですが、こんな感じのすごく簡単なTODO風のアプリケーションです。 f:id:joe-re:20180102214723p:plain

なぜEslintを使うか

JavaScriptのためのLintingツールはたくさんありますが、Vueのroadmapにもある通り、Vueの公式スタイルガイドをサポートするESLintプラグインがESLintのメンテナによる公式プラグインとして作られています。

GitHub - vuejs/roadmap: Roadmap for the Vue.js project

これからもVueの公式としてサポートされていくと思うので、特にこだわりがなければESLintを使うのが良いかと思います。

ESLint for TypeScript

ESLintはJavaScript(ECMAScript)のためのLintingツールですが、TypeScriptをESTree互換の形に変換し、ESLintを適用できるようにするパーサがプラグインとして提供されています。TypeScriptのプロジェクトにESlintを使う場合にはこのプラグインが必要です。

github.com

以下のようにparserに指定すれば動きます。

.eslintrc.json

{
   "parser": "typescript-eslint-parser",
   "extends": [
    "eslint:recommended"
   ]
}

ただし、TypeScriptはもともとESTree互換ではないので、現在(v11.0.0)いくつかのルールが思うように動きません。

Discussion: Extending core ESLint rules to "just work" with TS-specific nodes · Issue #77 · eslint/typescript-eslint-parser · GitHub

eslint-plugin-typescriptというプラグインを使うと、TypeScriptの用のルールを導入することができます。

github.com

今回導入したプロジェクトも冒頭のサンプルもTypeScriptのみで構成されているので問題になりませんが、ピュアなJavaScriptと併用する場合にはルールがぶつかってしまうかもしれません。 ESLintは適用するルールをファイルタイプごとに設定ができるので、これを用いてJavaScriptとTypeScriptを分ければ回避できるはずです。

eslint.org

ESLint for Vue Single File Component

VueのSingleFileComponent(.vue)にESLintを適用するためのパーサを ESLintのメンテナのmysticateaさんが公開しています。

github.com

これを使うと、.vueファイルにESLintを適用することができます。 TypeScriptと併用する場合には、以下のようにparserOptionセクションにtypescript-eslint-parserを指定します。

.eslintrc.json

{
  "parser": "vue-eslint-parser",
  "parserOptions": {
    "parser": "typescript-eslint-parser"
  },
  "extends": [
    "eslint:recommended",
    "typescript"
  ]
}

サンプルを作った時点(2017/1/1)では、現状のstable(1.0.0)ではなくbetaをinstallする必要がありました。

mysticateaさんに教えていただきまして、現在はstableでokだそうです。

npm install vue-eslint-parser -D

Linting according to Vue StyleGuide

Vue.jsの公式として、ESLintプラグインが提供されています。

github.com

これは以下のStyle Guideを提供するための追加ルールと、ルールを組み合わせたテンプレートを提供しています。 vuejs.org

これにはテンプレート部分のシンタックスチェックも含まれるので、以下のようにテンプレート部分の違反を検出することができるようになります。 f:id:joe-re:20180102230305p:plain

最終的に.eslintrc.jsonは以下のようになりました。

{
  "parser": "vue-eslint-parser",
  "parserOptions": {
    "parser": "typescript-eslint-parser"
  },
  "extends": [
    "eslint:recommended",
    "plugin:vue/recommended",
    "typescript"
  ]
}

追記

mysticateaさんから指摘をいただきまして、plugin:vue/recommendedはvue-eslint-parserのparserの指定を含むので、parserの行は削除可能だそうです。 ただし、今回の例だとeslint-plugin-typescriptもparserの設定を上書きするので、以下のようにextendsの順番でplugin:vue/recommendedが後に来るように設定する必要があります。

{
  "parserOptions": {
    "parser": "typescript-eslint-parser"
  },
  "extends": [
    "eslint:recommended",
    "typescript",
    "plugin:vue/recommended"
   ]
}

個人的にはextendsの順番で適用されるparserが変わるのは気持ち悪いので、明示的に指定しておいた方がいいかなーと思います。

参考