2020/04/22 追記:VSCodeやESLint機能拡張のアップデートで設定が変わったので、新しく記事を書きました
今どきのWebフロントエンドの開発環境はさっぱりわからないので、もう少し良いやり方があるかもしれません。参考までに。
tl;dr
VSCodeの拡張機能「Vetur」と「ESLint」を入れます。
ワークスペース設定(.vscode/settings.json
)に以下を書いてバージョン管理します。
vue-cliを使っていない場合、後述の環境設定も参考にしてください。
{
"eslint.autoFixOnSave": true,
"eslint.validate": [
{
"language": "vue",
"autoFix": true
}
],
"vetur.format.defaultFormatter.js": "none",
}
以下を参考にしました
理由
ESLintを使う理由は、ESLintの--fix
がフォーマッタのような役割になっているので、Lintとフォーマッタを兼ねてるような良さを感じます。
またnpm run lint:fix
で独立して行えるようにしておくと、エディタに縛られなくなり良いです。
また、VSCodeはかなりカスタマイズが出来てしまうので、それを抑制するためワークスペース設定に入れてしまい、バージョン管理しておくのが良いと思います。
蛇足
VSCodeの設定の説明
- .vueファイルでeslintが行われるようになります
(eslint.validate
による) - .vueファイルの保存時にファイルに対して
eslint --fix
が行われます(eslint.autoFixOnSave
とeslint.validate
のautoFix
による。両方必要。) - .vueファイル内のJavaScriptに対してVeturのフォーマッタを無効にします(
vetur.format.defaultFormatter.js
による)
環境設定
vue-cliは色々入れてくるため、何が必要なのかよくわからないので、Vueファイルに対してESLintが効くだけのミニマムなプロジェクトを作り、そのpackage.jsonと.eslintrc.jsを抜粋します。
"scripts": {
"lint": "eslint --ext .js,.vue src",
"lint:fix": "eslint --fix --ext .js,.vue src"
},
"devDependencies": {
"babel-core": "^6.26.3",
"babel-eslint": "^10.0.1",
"babel-helper-vue-jsx-merge-props": "^2.0.3",
"babel-plugin-istanbul": "^5.1.0",
"babel-plugin-syntax-jsx": "^6.18.0",
"babel-plugin-transform-runtime": "^6.23.0",
"babel-plugin-transform-vue-jsx": "^3.7.0",
"eslint": "^5.12.1",
"eslint-config-standard": "^12.0.0",
"eslint-plugin-import": "^2.14.0",
"eslint-plugin-node": "^8.0.1",
"eslint-plugin-promise": "^4.0.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^5.1.0"
},
.eslintrc.js
は以下の通りです。
ただ、これはvue-cliで作成されたものを流用していて、よくわからず使っていました。。
module.exports = {
root: true,
parserOptions: {
parser: 'babel-eslint'
},
env: {
browser: true,
},
extends: [
'plugin:vue/essential',
'standard'
],
plugins: [
'vue'
],
rules: {
'generator-star-spacing': 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'error' : 'off'
}
}
多分、Vuejs的な要点は以下の部分です
-
'plugin:vue/essential'
でVueのスタイルガイドでEssentialなものを適用している -
plugins: ['vue']
でvueファイルを解釈できるようにしている
自動保存時にフォーマットをかける設定をしている場合(editor.formatOnSave: true
)
ここの要約は「"vetur.format.defaultFormatter.js": "none"
を書き足せばよい」です。
個人設定等でeditor.formatOnSave: true
を使っている事が多いかもしれません。
しかし、これはESLintのautofixとは別で動くのでVeturのフォーマッタの動作と競合して変な動きになります。
遭遇した例では、セミコロンレスにしたいのに既存のフォーマッタ(prettier)でセミコロンがつき、その後にESLintによるfixがかかり、セミコロンを除去しきれずESLintで怒られる、といった感じです。
現状は、formatOnSaveの動作をいじる仕組みが提供されていないのでESLint側も対応できない模様で、ワークアラウンドが紹介されています。
なので、これに倣って、vueファイルに対してのみeditor.formatOnSave
を無効にしてみます。
{
"[vue]": {
"editor.formatOnSave": false
},
}
これで確かに競合するような動きはなくなります。
しかし、これだと「vueファイル内はHTMLとCSSがあるんだから、そっちは既存のフォーマッタをかけたい」という要望をカバーできません。そもそも、手癖でフォーマットのショートカットを入力した場合は、この設定をいれても既存のフォーマッタが動作してしまいます。
この解決策としては、editor.formatOnSave
で動くフォーマッタがvetur.format.defaultFormatter.js
の設定によるので、この値をnone
にしておくとVueファイル内のJS部分だけ既存のフォーマッタを無効にできます。
気になる点
"vetur.format.defaultFormatter.js":"prettier-eslint"
があるのでnpmでprettier-eslintをいれてあれば、これで良いのでは?と思ったが、自分の手元ではeslint --fix
がかからずダメ。これが出来ればVSCodeの拡張機能のESLintが不要になって良い感じな気がするんですが。。
{
"editor.formatOnSave": true,
"vetur.format.defaultFormatter.js": "prettier-eslint"
}
ここで力尽きる。