As far as I know, several formatters would run with several rules when I want to format .vue file in the vscode editor. I have been confused for a long time about these formatters and their specific rules, also the combined situations. Sometimes it makes me crazy. For example,
- For formatters, there are
ESLint,prettier,vscode internal formatterand some other formatters which I don’t know. - For rules, there are
.eslintrc.js,.prettierrc.js,user settingsand other plugins likeeslint-plugin-html,eslint-plugin-vue, etc. - In some cases, I am so sure that the code has been processed by at least 2 formatters because I saw the process of the code.
- …
What Do You Want?
Before we keep going we have to figure out one question.
What exactly format do we want ?
After thinking, I figure it out.
How can I let different developers commit with the identical styles?
To be more specific, I want
- Slightly dependent on developers’ user settings, use configuration files instead of plugins or rules in developers’ editor as possible as we can.
- Syntax-highlighting
- Format and lint .js and
scriptin .vue. - Format and lint .css, .less, .scss and
stylein .vue. - Format and lint
templatein .vue. - Format and lint
.html. - Format and lint before commit
- Can be unified on
vscodeat least, better if works on more editors.
Can We Do This by One Plugin Like Prettier?
Well, I didn’t find that plugin. And prettier can’t do this job either.
As we all know, currently prettier is the most popular format plugins. And it supports lots of editors and languages. So, it’s quite common to think that why don’t we just use prettier directly instead of using lots of linters or plugins?
Well, according to doc in prettier,
Linters have two categories of rules:
Formatting rules: eg: max-len, no-mixed-spaces-and-tabs, keyword-spacing, comma-style…
Prettier alleviates the need for this whole category of rules! Prettier is going to reprint the entire program from scratch in a consistent way, so it’s not possible for the programmer to make a mistake there anymore :)
Code-quality rules: eg no-unused-vars, no-extra-bind, no-implicit-globals, prefer-promise-reject-errors…
Prettier does nothing to help with those kind of rules. They are also the most important ones provided by linters as they are likely to catch real bugs with your code!
Therefore, we have to do it one by one.
Main Work
Syntax-highlighting
I found two ways:
- add config below to settings.json which let
vscodehighlight it as html.
"files.associations": { "*.vue": "html" }, |
- install Vetur plugin.
I would recommend Vetur because
- Vue
VSCodeSnippets and other plugins may depend on it. - Highlight .vue as html won’t get better highlighting effect than
Vetur. - Other problems may appear…
Format and Lint .js, script and template in .vue.
Parser
As ESLint said,
ESLint’s parser only officially supports the latest final ECMAScript standard.
In other cases (including if rules need to warn on more or fewer cases due to new syntax, rather than just not crashing), we recommend you use other parsers and/or rule plugins. If you are using Babel, you can use the babel-eslint parser and eslint-plugin-babel to use any option available in Babel.
Once a language feature has been adopted into the ECMAScript standard (stage 4 according to the TC39 process), we will accept issues and pull requests related to the new feature, subject to our contributing guidelines.
In my case, there is stage2 in my .babelrc presets.
{ |
So, I have to use babel-eslint as parser.
Plugins
Also, I want to lint script in .vue, obviously I need plugins. According to the doc in eslint-plugin-html,
Initially,
eslint-plugin-vuewas usingeslint-plugin-htmlto lint code inside script tags.
Since v3,eslint-plugin-vueis using its own parser, so it is incompatible witheslint-plugin-html.
You should useeslint-plugin-vueexclusively and removeeslint-plugin-htmlfrom your dependencies if you still have it.
That’s why we still can see some .eslintrc.js like below in old projects.
module.export = { |
Also, as documented in vue-loader doc,
The official
eslint-plugin-vuesupports linting both thetemplateandscriptparts of Vue single file components.
So, we can use eslint-plugin-vue to lint .js, script and template in .vue.
Specific Rules
Though there is a lot of rule libs I can choose. For example, eslint:recommended, standard, airbnb, etc. Also, for .vue files, there is plugin:vue/recommended, "plugin:vue/base, etc. However, You might still need to read and check which lib or rules you can accept or want because it is quite common to find that there is some rules you can’t accept in lots of rule libs.
In the end, our configuration might be something like this:
module.exports = { |
Format and Lint .css, .less, .scss and style in .vue.
As documented in vue-loader doc,
stylelintsupports linting style parts of Vue single file components.
Format and lint .html.
There is two cases happen to .html.
One is vue component file like
<!-- component.vue -->
<template src="./template.html"></template>
<style src="./style.scss"></style>
<script src="./index.js"></script>For this one,
eslint-plugin-vuewouldn’t support in the near future and recommend using .vue file. Related issue1, issue2.Another is index.html or public/index.html
In rare cases, we would need to modify this file. So, we might want to add formatter and linter for this file. Actually,
stylelintwould lintstylein it automatically.- While
htmlhintwould be needed to format and linthtmlin it. - The only problem is the
script. However, I didn’t addeslint-plugin-htmlfor this file because- Normally, there shouldn’t be inline script in index.html
- Inline script has different linting requirements because it would directly run in the browser and not be transformed by
babel. So, It has to be written in ES5. If you want to lint the script, you might have to write lots of disable comments in it.
So, in my project I add .htmlhintrc which is like
{ |
However, prettier doesn’t support htmlhint integration, so make sure that you don’t add stylistic rules in .htmlhintrc. You might not be able to understand previous sentence before finish reading the Prettier part. Don’t worry, keep reading.
Prettier
Do We Need Prettier
Until now, we can use
ESLint,eslint-plugin-vueto format and lint .js,scriptandtemplatein .vue files.stylelintto format and lint .css, .less, .scss files andstylein .vue files.htmlhintto format and lint .html.
It seems that all formatting and linting job have been done without Prettier. So, here comes a question:
Do we need
Prettier?
Actually, it’s a good question. Someone just ask here,
If eslint can auto fix/format code why to use
Prettier?
And the answer is something like:
Prettiercan do some formatting thing that eslint can’t do and vice versa. So, here comesprettier-eslintwhich combines them.
The same thing also happens on stylelint. Until 0.49.0 version, vscode-stylelint still doesn’t support auto fix in editor but prettier-vscode can.
So, we do need Prettier, also with plugins to combine Prettier with ESLint and stylelint.
Prettier First or Linter First?
Generally, there are four ways to combine them.
prettier-eslint |
eslint-config-prettier |
|
|---|---|---|
prettier-stylelint |
Code ➡️ prettier ➡️ eslint/stylelint ➡️ Formatted | Code ➡️ eslint➡️ prettier ➡️ Formatted Code ➡️ prettier ➡️ stylelint ➡️ Formatted |
stylelint-config-prettier |
Code ➡️ prettier ➡️ eslint ➡️ Formatted Code ➡️ stylelint ➡️ prettier ➡️ Formatted |
Code ➡️ eslint/stylelint ➡️ prettier ➡️ Formatted |
I guess most people chose
prettier-eslintandprettier-stylelintwhich is
Code ➡️ prettier ➡️ eslint/stylelint –fix ➡️ Formatted Code
- or
eslint-config-prettierandstylelint-config-prettierwhich is
Code ➡️ eslint/stylelint ➡️ prettier –write ➡️ Formatted Code
Both of them would work when formatting and linting before commit. The only difference is
Prettier first or linter first?
Obviously, the latter would decide the code style.
If you choose prettier-eslint and prettier-stylelint, the pros are
- you can decide the code style by .eslintrc.js and .stylelintrc.js which provide lots of options.
the cons are about the editor plugins.
vscode-stylelintdoesn’t support auto fix. You can find the issue here.vscode-eslintcan’t fix all at one time by enable"eslint.autoFixOnSave": true. You can find the issue here. You might encounter situations like:

or even worse like

If you choose eslint-config-prettier and stylelint-config-prettier, the pros are
prettier-vscodesupport auto fix and fix all at one time.
the cons are
- You don’t have too many choices in code style because
Prettieronly provides a few options for user to choose.
Finally, I choose eslint-config-prettier and stylelint-config-prettier.
Actually, these two configs just do one thing:
Turns off all rules that are unnecessary or might conflict with Prettier.
So, when you chose this it means that
let prettier do the formatting job while let eslint and stylelint do the linting job.
Also, you shouldn’t add stylistic rules in your .eslintrc.js and .stylelintrc.js files as those rules would overwrite eslint-config-prettier and stylelint-config-prettier. Even though you chose prettier-eslint and prettier-stylelint, you should also avoid adding conflicting stylistic rules between .prettierrc.js and .eslintrc.js or .stylelintrc.js.
In the end, my .prettierrc.js
module.exports = { |
and .eslintrc.js
// https://eslint.org/docs/user-guide/configuring |
and .stylelintrc.js
module.exports = { |
Format and Lint Before Commit
After some research, I found that git hook can help us do this job. We can build it by ourself or use third party tools like husky. In my case, I use husky to add git hook and use lint-staged to run my linters and formatters. So, in my project, I add .huskyrc.js,
module.exports = { |
and .lint-staged.config.js,
module.exports = { |
It will run eslint/stylelint/htmlhint before commit. If error appears, commit would be blocked until errors have been fixed.
So far, we can ensure the code quality in the repository by eslint, eslint-plugin-vue, stylelint, htmlhint, prettier, husky and lint-staged with no requirements for user settings.
Hope svg below can help you organize thoughts.
Ways to Avoid Linting Some Lines
Sometimes, we might need to avoid linting some lines. So, I made a disable list.
-
vscodealso provides convenience like below,
eslint-plugin-vue
Find it via this issue.try
<!-- eslint-disable -->this will disable linting for everything below it, you can use<!-- eslint-enable -->to re-enable it back.-
You can find it in the change log. Also, for convenience you can install a snippet plugin. For example, I use Stylelint Disable Snippets which works like

htmlhintThey haven’t support it yet. The latest issue.
gitIn the situation that we need to commit directly and skip the git hook, we can use command like
git commit --no-verify -m "your commit message".
Let Editor Consistent With Project Configurations
It is quite common that we want to develop with auto-save, auto-formatter and auto-lint with our editor. In this case, we need to depend on editor’s plugins. According to above configuration. We need
eslint,stylelintandhtmlhintfor lintprettierfor format.Veturfor the syntax highlighting.
After installing these plugins in your editor, we have to combine them in a proper way. For me, the way is
- Set
prettieras default formatter. - Disable
veturformatter. - Disable
veturvalidation for .vue files and internal validation for .css, .less, .scss,stylein .html, .js. - Enable
stylelint,eslintandhtmlhintvalidation. - Enable internal
scriptin .html validation because we didn’t add validation for that.
And in the user settings, take vscode for example
{ |
And I made this image for a better understanding.
How to Handle History Files with Current Formatter and Linter?
Actually, there are many choices. For example,
- We can fix all the stylistic errors at one time and add disable comments around the remaining linting errors. After that, each time we commit, it won’t have any effects on the code review.
- Or we can fix all the errors one by one though it will need lots of time.
- Or you can just leave it there until one day you commit that file. In that case, you might need adding comments each time you commit which would have a little effects on our code review.
- …
For me, I choose the first one. So,
- I add these scripts in my package.json.
{ |
and install related packages by
npm i eslint@latest eslint-plugin-vue@latest eslint-config-prettier@latest eslint-plugin-standard@latest eslint-config-standard@latest eslint-loader@latest eslint-plugin-node@latest eslint-plugin-promise@latest eslint-plugin-json@latest -D |
Run
npm run lint-format.Check all the formatted and linted files.
- Add the files which don’t need formatting and linting to the .stylelintignore, .prettierignore or .eslintignore.
- Add configuration comments to disable the errors which the linters can’t fix. In this case, you might need
eslint-disable-snippetsandStylelint Disable Snippetseditor plugin.
Commit the modified files by
git commit -m "init format and lint".
Remarks
prettierdoesn’t supportstylusuntil v1.18.2.eslintwould ignore files whose names start from dot. For example,- .postcssrc.js
- .prettierrc.js
- .stylelintrc.js
- …
However,
prettierwould format these files. So, if you want to keep consistent withprettierwe can add these files to .eslintignore like!/*.js
vue-cli3.0has choice forformatOnSave. However, I don’t recommend because it has multiple cons- Project has to run
- Consume more time on dev
- Equals compulsory which is not friendly
Sometimes you need to restart editor after modifying the .prettierrc.js or .eslintrc.js, especially when you modified options like
tabWidthetc.If you have enabled multiple formatters in
vscode, you would seeFormat Document with ...choice when you right click your mouse.

The
Format Documentchoice is using your default formatter which is defined by"editor.defaultFormatter". For example,"editor.defaultFormatter": "esbenp.prettier-vscode"is usingprettieras default formatter.lint-stagedhas problems with committing partially staged files currently. The related issues are #62, #75 and article.Prettier support vue at v1.15. So to make sure that prettier will work for you, you might need to check if your prettier version is not earlier than
v1.15.This latest vue project format template can be found in my repository vue-project-template.
Actually, this idea was not only for vue but also for other front end projects. Whatever lib we choose, we are always writing style, html and script. All we need to do is to choose different plugins for our project. In this case, we choose,
eslint-plugin-vue. In other case, you might needeslint-plugin-react,eslint-plugin-angular, etc.