Vue.js始めるおれおれアドベントカレンダー2016 – 8日目

例示されるコードと自分が書くコードの書き方が違うのが気になってきたので、lintツールを入れてみようと思いました。

eslint-plugin-vue

Vue公式でESLintのプラグインが公開されていた。

これを導入してみる。

$ npm i -S eslint eslint-plugin-vue eslint-config-vue

で .eslintrc.js を用意する。

  • .eslintrc.js
module.exports = {
    "extends": "vue",
};

あ、こんだけで良いんだ。さてlint実行。

対象を src/ で指定するとJSファイルしか見てくれないので、 src/* にして *.vue も対象に含める。

$ ./node_modules/.bin/eslint src/*

/my/impressive/path/08-vue-lint/src/App.vue
   8:40  error  Extra semicolon                                    semi
  11:3   error  Expected indentation of 2 spaces but found 1 tab   indent
  12:4   error  Expected indentation of 2 spaces but found 2 tabs  indent
  13:3   error  Expected indentation of 0 spaces but found 1 tab   indent
  13:4   error  Unexpected trailing comma                          comma-dangle
  14:3   error  Extra semicolon                                    semi

/my/impressive/path/08-vue-lint/src/main.js
   1:27  error  Extra semicolon                                    semi
   2:29  error  Extra semicolon                                    semi
   3:14  error  Extra semicolon                                    semi
   5:33  error  Extra semicolon                                    semi
…

✖ 70 problems (70 errors, 0 warnings)

うは、なんかいっぱい言われてる。

自動修復

ESLintの機能だけど、 --fix を付けると簡単な(機械的に変換できる)書式エラーは自動的に修正してくれる。ファイルはGitで管理してるから機械変換しても怖くはないでしょう?

$ $ ./node_modules/.bin/eslint src/* --fix

/my/impressive/path/08-vue-lint/src/App.vue
   8:40  error  Extra semicolon                                    semi
  11:3   error  Expected indentation of 2 spaces but found 1 tab   indent
  12:4   error  Expected indentation of 2 spaces but found 2 tabs  indent
  13:3   error  Expected indentation of 0 spaces but found 1 tab   indent
  13:4   error  Unexpected trailing comma                          comma-dangle
  14:3   error  Extra semicolon                                    semi

/my/impressive/path/08-vue-lint/src/MyTitle.vue
   6:35  error  Extra semicolon                                    semi
   9:3   error  Expected indentation of 2 spaces but found 1 tab   indent
   9:17  error  Missing space before function parentheses          space-before-function-paren
…

✖ 51 problems (51 errors, 0 warnings)

エラーが70件から51件に減った。 *.js は全部自動で直してくれたけど、 *.vue はまるまる残ってる感じだ。

ESLintとしてはJSファイルじゃないものは対応しない方針の様子。まあそうだね。Stack Overflowでも「無理だよ☆」という回答だ……。

さてどうしたものか

JS部分だけ取り出してうまいことやれば自動変換で全て丸く収まりそうなんだけどなー。手作業で直して確認するより、手作業で自動変換できる形にして変換して戻す、みたいな形が好み。

自分の場合はVim使ってるので、こんな感じでJS部以外をコメントアウトしました。 <style> の中身には対応できないけど、今回はまだ書いてないからこれで良いや。

:g/^\s*</norm 0i///

で拡張子を変えまして。

  • App.js
///<template>
/// <div class="container">
///     <my-title></my-title>
/// </div>
///</template>

///<script>
    var MyTitle = require('./MyTitle.vue');

    module.exports = {
        components: {
            MyTitle
        },
    };
///</script>

さあどうだ。

$ ./node_modules/.bin/eslint src/* --fix
  • App.js
// /<template>
// /    <div class="container">
// /        <my-title></my-title>
// /    </div>
// /</template>

// /<script>
var MyTitle = require('./MyTitle.vue')

module.exports = {
  components: {
    MyTitle
  }
}
// /</script>

あーインデント変わっちゃったな。まあこんなもんか。ではコメントアウトを解除してファイル名を戻して。

:g/^\/\/ \//norm 4x

別にインデントはこれで怒られないけど、手動で戻しました。結局手動かあ……。

開発環境へ組み込む

ファイル変更を検知して、ビルドの前に検証するようにします。

  • package.json
{
  "scripts": {
    "start": "npm run vue-watch",
    "vue-build": "browserify -t vueify -e src/main.js -o out/app.js ",
    "vue-lint": "eslint src/*",
    "vue-watch": "chokidar src/* -c 'npm run vue-lint && npm run vue-build'"
  },
  "dependencies": {
    "browserify": "^13.1.1",
    "chokidar-cli": "^1.2.0",
    "eslint": "^3.11.1",
    "eslint-config-vue": "^2.0.1",
    "eslint-plugin-vue": "^1.0.0",
    "vue": "^2.1.4",
    "vueify": "^9.3.0",
    "vuex": "^2.0.0"
  }
}

ESLintを直接呼んだ方が、失敗時にnpmの出力が出なくて良いようにも思う。長いんだよなーあれ。

よくわからないこと

自動修正をもっとうまくやりたい

まあ仕方ないかこんなもんか。lintがある状態で書いてれば自動修正いらないし。

lint失敗時の出力を減らしたい

さっき言ったnpmのやつ。こういうの。

$ npm run vue-lint

> @ vue-lint /my/impressive/path/08-vue-lint
> eslint src/*


/my/impressive/path/08-vue-lint/src/App.vue
  45:4  error  Extra semicolon  semi

✖ 1 problem (1 error, 0 warnings)


npm ERR! Linux 4.8.4-200.fc24.x86_64
npm ERR! argv "/my/impressive/path "/my/impressive/path"run" "vue-lint"
npm ERR! node v5.7.1
npm ERR! npm  v3.8.2
npm ERR! code ELIFECYCLE
npm ERR! @ vue-lint: `eslint src/*`
npm ERR! Exit status 1
npm ERR! 
npm ERR! Failed at the @ vue-lint script 'eslint src/*'.
npm ERR! Make sure you have the latest version of node.js and npm installed.
npm ERR! If you do, this is most likely a problem with the  package,
npm ERR! not with npm itself.
npm ERR! Tell the author that this fails on your system:
npm ERR!     eslint src/*
npm ERR! You can get information on how to open an issue for this project with:
npm ERR!     npm bugs 
npm ERR! Or if that isn't available, you can get their info via:
npm ERR!     npm owner ls 
npm ERR! There is likely additional logging output above.

npm ERR! Please include the following file with any support request:
npm ERR!     /my/impressive/path/08-vue-lint/npm-debug.log

npm通さずに普通に呼ぶと簡単。

$ ./node_modules/.bin/eslint src/*

/my/impressive/path/08-vue-lint/src/App.vue
  45:4  error  Extra semicolon  semi

✖ 1 problem (1 error, 0 warnings)

うーんでもなー。lintだけ呼びたいこともあろうし、同じこと二度書きたくないし。

おしまい

これでだいぶ開発環境が整ってきた気がする。

コード