クソ雑魚エンジニアのメモ帳

学んだことを書くところ

もうprettierで消耗したくない人へのvueでのeslint設定

タイトル通り。vscodeとvuejsを使ってのlintの設定をprettierなしでやってみた。

tl;dr

対象ファイルとpackage.jsonと.eslintrc.jsの対応表👇

構文チェック・自動フォーマット
対象ファイル
npmライブラリ(package.json) .eslintrc.jsでのextends
.vue(<template>) eslint-plugin-vue plugin:vue/recommended
.vue(<script>) eslint eslint:recommended
. js eslint eslint:recommended
yarn add -D eslint eslint-plugin-vue
module.exports = {
  plugins: [
    "vue"
  ],
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended'
  ],
  rules: {
    // タグの最後で改行しないで
    "vue/html-closing-bracket-newline": [2, {"multiline": "never"}],
    // 不要なカッコは消す
    "no-extra-parens": 1,
    // 無駄なスペースは削除
    "no-multi-spaces": 2,
    // 不要な空白行は削除。2行開けてたらエラー
    "no-multiple-empty-lines": [2, {"max": 1}],
    // 関数とカッコはあけない(function hoge() {/** */})
    "func-call-spacing": [2, "never"],
    // true/falseを無駄に使うな
    "no-unneeded-ternary": 2,
    // セミコロンは禁止
    "semi": [2, "never"],
    // 文字列はシングルクオートのみ
    "quotes": [2, "single"],
    // varは禁止
    "no-var": 2,
    // jsのインデントは2
    "indent": [2, 2],
    // かっこの中はスペースなし!違和感
    "space-in-parens": [2, "never"],
    // コンソールは許可
    "no-console": 0,
    // カンマの前後にスペース入れる?
    "comma-spacing": 2,
    // 配列のindexには空白入れるな(hogehoge[ x ])
    "computed-property-spacing": 2,
    // キー
    "key-spacing": 2,
    // キーワードの前後には適切なスペースを
    "keyword-spacing": 2,
  }
}
{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        {
          "language": "vue",
          "autoFix": true,
        },
   ],
    "eslint.autoFixOnSave": true,
}

環境

とあるプロジェクトでnuxt+vuejsを使って実装をしていた時の話。開発初期段階だったのもありnuxtが2.4をリリースしたというのでアップデートしてみた。しかし急にeslintとprettierの構文チェック・自動フォーマットが効かなくなった。。。。

開発環境はvscode

package.jsonのパッケージはだいたいこんな感じ。

  • vue@2.6.6
  • nuxt@2.4.3
  • babel-eslint@7.2.3
  • eslint@4.19.1
  • eslint-config-standard@10.2.1
  • eslint-loader@1.9.0
  • eslint-plugin-html@3.1.1
  • eslint-plugin-import@2.7.0,
  • eslint-plugin-node@5.1.1,
  • eslint-plugin-promise@3.5.0,
  • eslint-plugin-standard@3.0.1,
  • eslint-plugin-vue@5.2.2
  • eslint-config-prettier@4.0.0
  • eslint-plugin-prettier@3.0.1

そこで、再び構文チェック・自動フォーマットが効くように半日頑張ったが無理だった。半日溶けた。

問題点

  1. eslint系が12種と多い、多すぎる😇😇😇😇😇、どれが何の役割を果たしているかわからない
  2. prettier・veturも絡んでいる
  3. 依存関係がわからない(vscodeのconfig.json.eslintrc.jsにもprettierがある。)
  4. 元々の設定もどこかしらのドキュメントを参考につぎはぎしていたので何の設定をどこで制御できるのかわからない

👉カオス味を減らしたい

👉👉prettierはもういらないのでは??

👉👉👉prettierをなくして最低限のeslintによる構文チェック・自動フォーマットを設定する

手順

僕の.eslintrc.jsがいつまでも正しいかどうかわからないので記録を残しておく。苦しんで覚えたい人は再現してほしい。おれのしかばねをこえてゆけ💀💀💀

.vueの構文チェックその1

まずは自動フォーマットはひとまず無視して、構文チェックができるようにする。

eslint公式にはvuejsに関する記述はなかったが、 eslint-plugin-vueには Official ESLint plugin for Vue.jsという記載があったのでこれを信じる。

これだけでいいみたい。

  • eslint
  • eslint-plugin-vue

https://vuejs.github.io/eslint-plugin-vue/user-guide/#installation

以下は不要なもの。多すぎ。使っている人はいますぐpackage.jsonから消し去ろう

  • eslint-config-standard@10.2.1
  • eslint-loader@1.9.0
  • eslint-plugin-html@3.1.1
  • eslint-plugin-import@2.7.0,
  • eslint-plugin-node@5.1.1,
  • eslint-plugin-promise@3.5.0,
  • eslint-plugin-standard@3.0.1,
  • eslint-config-prettier@4.0.0
  • eslint-plugin-prettier@3.0.1

あとは .eslintrc.jsの設定だけ。これでOK

module.exports = {
  plugins: [
    "vue"
  ],
  extends: [
    // 'eslint:recommended',
    'plugin:vue/recommended'
  ],
  rules: {
  }
}

https://vuejs.github.io/eslint-plugin-vue/user-guide/#configuration

この段階ではまだvscodeでの自動フォーマットは効いていないはず。落ち着いてまずは構文チェックができるかを確認

# srcフォルダにvueファイルがある前提

$ eslint --ext .js,.vue src
# または
$ eslint "src/**/*.{js,vue}"

構文チェックがうまく走るとおそらくこんな表示になる。

$ yarn run eslint "pages/**/*.{js,vue}"
....
....
✖ 70 problems (21 errors, 49 warnings)
  13 errors and 49 warnings potentially fixable with the `--fix` option.

出力からわかると思うが、--fixをつけることでフォーマットすることができる。

このことからeslintを用いることで、vueファイルの構文チェック・自動フォーマットができることが確認できた。

vscode上での自動フォーマット

こんどはCmd + Sft + Psettingと打ち、Open Settings(JSON)を選択。

ここで、vscode上でeslint構文チェック・自動フォーマットができるように以下を設定

{
  "eslint.validate": [
    "javascript",
    "javascriptreact",
    {
      "language": "vue",
      "autoFix": true,
    },
  ],
  "eslint.autoFixOnSave": true,
}

このことからvalidate=構文チェックかつautoFixOnSave=自動フォーマットなのがわかる

試しに、.vueファイルのtemplate内のインデントをぐちゃぐちゃにするとエラーが出て、Cmd + Sを何回か押すと自動フォーマットができることが確認できる。

しかしまだ不完全のようである。.vue<script>タグの中が全くフォーマットされていない

.vueの構文チェックその2

.eslintrc.jsを振り返り、以下の行をコメントアウト

module.exports = {
  plugins: [
    "vue"
  ],
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended'
  ],
  rules: {
  }
}

すると、例えば以下のvueファイルで自動フォーマットをするとconsole.log("hoge");;;;;;;が自動で消えるようになる

<template>
  <div>
    <p>aaaa</p>
  </div>
</template>

<script>
export default {
  created() {
-      console.log("hoge");;;;;;
+   console.log("hoge");
          const    a     =     "A"
    var b = (4+(1-1))
    let c = [  1  ,  2 ,  3]


    const d = "zzzzzzzz"
  }
}
</script>

🎊🎊🎊おめでとう🎊🎊🎊。ここまで来ればeslintの設定はほとんど終わり。だけどscriptの中はまだまだ混沌としているので、あとでカスタマイズ。

rulesをカスタマイズ

<template>のカスタマイズ

今までの内容を見るに、vueファイルの<template>の構文チェックを行なっているのは eslint-plugin-vueであり、<template>eslint-plugin-vue独自のルールが適用されている。

独自のルールはここにまとめられている。今回の設定(以下ファイル)では、 'plugin:vue/recommended'として導入されているので、Priority A: Essential (Error Prevention)Priority B: Strongly Recommended (Improving Readability)の内容も含んでおり、一通りvuejs公式が推奨するルールはだいたい入っている。

module.exports = {
  plugins: [
    "vue"
  ],
  extends: [
    'eslint:recommended',     // これ
    'plugin:vue/recommended'
  ],
  rules: {
  }
}

'plugin:vue/recommended'に入っていないルールであっても自分で追加することができる。

例えば筆者は以下の部分をカスタマイズした。

  rules: {
    // タグの最後で改行しないで
    "vue/html-closing-bracket-newline": [2, {"multiline": "never"}],
  }

簡単にいうと、2はエラー。このルールを厳しく適用する

html-closing-bracket-newlineは、 'plugin:vue/recommended'には含まれているがカスタマイズしないと以下の構文のpタグがOKになってしまう。

<template>
  <div>
    <p
      hoge="#"
      huga="%%%"
      >
      aaaa
    </p>
  </div>
</template>

これは個人的には気に入らないので、"multiline": "never"という設定にした。

<template>
  <div>
    <p
      hoge="#"
-     huga="%%%"
-     >
+     huga="%%%">
      aaaa
    </p>
  </div>
</template>

注意点として、自動フォーマットができないルールもいくつかある。ルールの一覧画面に🔧マークがなければ自動フォーマットができないので注意しよう、

<script>をカスタマイズ

これが思ったよりしんどい。

これも今までの内容を見るに、<script>の構文チェックを行なっているのはeslintである。eslintのルールはこちらにある。100個以上あってなかなかしんどいが、一通り目を通すと非常に勉強になるのでみなさんにも読んでほしい。

今回は'eslint:recommended',として導入しており、ルール一覧画面では✔️マークがあるルールは全て含まれている。(こちらも注意点として、自動フォーマットができないルールもいくつかある。ルールの一覧画面に🔧マークがなければ自動フォーマットができない。)

ただし、recommendedでは先ほど出てきた構文でも特に何もエラー・警告を吐かない。ツッコミどころしかないのだが。。

          const    a     =     "A"
    var b = (4+(1-1))
    let c = [  1  ,  2 ,  3]


    const d = "zzzzzzzz"

これをどう直すかは人次第なので一意見として僕のrulesをいかに貼ります。

  rules: {
    // 不要なカッコは消す
    "no-extra-parens": 1,
    // 無駄なスペースは削除
    "no-multi-spaces": 2,
    // 不要な空白行は削除。2行開けてたらエラー
    "no-multiple-empty-lines": [2, {"max": 1}],
    // 関数とカッコはあけない(function hoge() {/** */})
    "func-call-spacing": [2, "never"],
    // true/falseを無駄に使うな
    "no-unneeded-ternary": 2,
    // セミコロンは禁止
    "semi": [2, "never"],
    // 文字列はシングルクオートのみ
    "quotes": [2, "single"],
    // varは禁止
    "no-var": 2,
    // jsのインデントは2
    "indent": [2, 2],
    // かっこの中はスペースなし!違和感
    "space-in-parens": [2, "never"],
    // コンソールは許可
    "no-console": 0,
    // カンマの前後にスペース入れる?
    "comma-spacing": 2,
    // 配列のindexには空白入れるな(hogehoge[ x ])
    "computed-property-spacing": 2,
    // キー
    "key-spacing": 2,
    // キーワードの前後には適切なスペースを
    "keyword-spacing": 2,
  }

ちなみに2は先ほど出てきたが、10もここで出てきた。1は警告(エラーではない)、0は許可。

例えばこのルールで先ほどの構文を自動フォーマットするとこうなる。幸せ。

    const a = 'A'
    let b = 4+(1-1)
    let c = [ 1, 2, 3]

    const d = 'zzzzzzzz'

まとめ。

prettierの設定に疲れた人はやって見ると良い。

対象ファイルとpackage.jsonと.eslintrc.jsの対応表👇

構文チェック・自動フォーマット
対象ファイル
npmライブラリ(package.json) .eslintrc.jsでのextends
.vue(<template>) eslint-plugin-vue plugin:vue/recommended
.vue(<script>) eslint eslint:recommended
. js eslint eslint:recommended
yarn add -D eslint eslint-plugin-vue
module.exports = {
  plugins: [
    "vue"
  ],
  extends: [
    'eslint:recommended',
    'plugin:vue/recommended'
  ],
  rules: {
    // タグの最後で改行しないで
    "vue/html-closing-bracket-newline": [2, {"multiline": "never"}],
    // 不要なカッコは消す
    "no-extra-parens": 1,
    // 無駄なスペースは削除
    "no-multi-spaces": 2,
    // 不要な空白行は削除。2行開けてたらエラー
    "no-multiple-empty-lines": [2, {"max": 1}],
    // 関数とカッコはあけない(function hoge() {/** */})
    "func-call-spacing": [2, "never"],
    // true/falseを無駄に使うな
    "no-unneeded-ternary": 2,
    // セミコロンは禁止
    "semi": [2, "never"],
    // 文字列はシングルクオートのみ
    "quotes": [2, "single"],
    // varは禁止
    "no-var": 2,
    // jsのインデントは2
    "indent": [2, 2],
    // かっこの中はスペースなし!違和感
    "space-in-parens": [2, "never"],
    // コンソールは許可
    "no-console": 0,
    // カンマの前後にスペース入れる?
    "comma-spacing": 2,
    // 配列のindexには空白入れるな(hogehoge[ x ])
    "computed-property-spacing": 2,
    // キー
    "key-spacing": 2,
    // キーワードの前後には適切なスペースを
    "keyword-spacing": 2,
  }
}
{
    "eslint.validate": [
        "javascript",
        "javascriptreact",
        {
          "language": "vue",
          "autoFix": true,
        },
   ],
    "eslint.autoFixOnSave": true,
}

おまけ

eslintのruleと死闘を繰り広げてるときに投げられた無慈悲なメッセージ

f:id:Kouchannel55:20190221202322p:plain

ESLintを入れただけでは今までのおまえのコードは何一つ綺麗にならない。おまえはメキシコの夕日よりも赤いコードを見ることになるだろう。

https://qiita.com/khsk/items/0f200fc3a4a3542efa90