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 formatter
and some other formatters which I don’t know. - For rules, there are
.eslintrc.js
,.prettierrc.js
,user settings
and 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
script
in .vue. - Format and lint .css, .less, .scss and
style
in .vue. - Format and lint
template
in .vue. - Format and lint
.html
. - Format and lint before commit
- Can be unified on
vscode
at 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
vscode
highlight it as html.
"files.associations": { "*.vue": "html" }, |
- install Vetur plugin.
I would recommend Vetur
because
- Vue
VSCode
Snippets 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-vue
was usingeslint-plugin-html
to lint code inside script tags.
Since v3,eslint-plugin-vue
is using its own parser, so it is incompatible witheslint-plugin-html
.
You should useeslint-plugin-vue
exclusively and removeeslint-plugin-html
from 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-vue
supports linting both thetemplate
andscript
parts 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,
stylelint
supports 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-vue
wouldn’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,
stylelint
would lintstyle
in it automatically.- While
htmlhint
would be needed to format and linthtml
in it. - The only problem is the
script
. However, I didn’t addeslint-plugin-html
for 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-vue
to format and lint .js,script
andtemplate
in .vue files.stylelint
to format and lint .css, .less, .scss files andstyle
in .vue files.htmlhint
to 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:
Prettier
can do some formatting thing that eslint can’t do and vice versa. So, here comesprettier-eslint
which 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-eslint
andprettier-stylelint
which is
Code ➡️ prettier ➡️ eslint/stylelint –fix ➡️ Formatted Code
- or
eslint-config-prettier
andstylelint-config-prettier
which 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-stylelint
doesn’t support auto fix. You can find the issue here.vscode-eslint
can’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-vscode
support auto fix and fix all at one time.
the cons are
- You don’t have too many choices in code style because
Prettier
only 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.
-
vscode
also 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
htmlhint
They haven’t support it yet. The latest issue.
git
In 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
,stylelint
andhtmlhint
for lintprettier
for format.Vetur
for 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
prettier
as default formatter. - Disable
vetur
formatter. - Disable
vetur
validation for .vue files and internal validation for .css, .less, .scss,style
in .html, .js. - Enable
stylelint
,eslint
andhtmlhint
validation. - Enable internal
script
in .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-snippets
andStylelint Disable Snippets
editor plugin.
Commit the modified files by
git commit -m "init format and lint"
.
Remarks
prettier
doesn’t supportstylus
until v1.18.2.eslint
would ignore files whose names start from dot. For example,- .postcssrc.js
- .prettierrc.js
- .stylelintrc.js
- …
However,
prettier
would format these files. So, if you want to keep consistent withprettier
we can add these files to .eslintignore like!/*.js
vue-cli3.0
has 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
tabWidth
etc.If you have enabled multiple formatters in
vscode
, you would seeFormat Document with ...
choice when you right click your mouse.The
Format Document
choice is using your default formatter which is defined by"editor.defaultFormatter"
. For example,"editor.defaultFormatter": "esbenp.prettier-vscode"
is usingprettier
as default formatter.lint-staged
has 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.