You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
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 like eslint-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?
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.
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.
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 using eslint-plugin-html to lint code inside script tags.
Since v3, eslint-plugin-vue is using its own parser, so it is incompatible with eslint-plugin-html.
You should use eslint-plugin-vue exclusively and remove eslint-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={//...// required to lint *.vue filesplugins: ["html"]//...};
The official eslint-plugin-vue supports linting both the template and script 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={root: true,parserOptions: {parser: "babel-eslint",// https://eslint.vuejs.org/user-guide/#usagesourceType: "module"// "module" if your code is in ECMAScript modules},env: {browser: true,node: true,es6: true// enable ES6 global variables//...},extends: [// ...other rule libs"eslint:recommended","plugin:vue/essential"// ...other rule libs],// required to lint *.vue filesplugins: ["vue"],rules: {// add your custom rules here, including .vue and es rules.}};
Format and Lint .css, .less, .scss and style in .vue.
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 lint style in it automatically.
While htmlhint would be needed to format and lint html in it.
The only problem is the script. However, I didn't add eslint-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.
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 and template in .vue files.
stylelint to format and lint .css, .less, .scss files and style 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 comes prettier-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.
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-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-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 provide 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={semi: false,singleQuote: true};
and .eslintrc.js
// https://eslint.org/docs/user-guide/configuringmodule.exports={root: true,parserOptions: {// https://eslint.vuejs.org/user-guide/#usageparser: "babel-eslint",ecmaVersion: 2019},env: {browser: true,node: true,es6: true},extends: [// https://github.com/standard/standard/blob/master/docs/RULES-en.md"standard",// rules for vue, didn't include any js rules lib like standard or airbnb// https://github.com/vuejs/eslint-plugin-vue#priority-a-essential-error-prevention."plugin:vue/recommended",// turn off ESLint default stylistic rules// https://github.com/prettier/eslint-config-prettier/blob/master/index.js"prettier",// turn off stylistic rules defined in standard// https://github.com/prettier/eslint-config-prettier/blob/master/standard.js"prettier/standard",// turn off stylistic rules defined in plugin:vue/recommended// https://github.com/prettier/eslint-config-prettier/blob/master/vue.js"prettier/vue"],// required to lint index.html and *.vue filesplugins: ["vue"],// add your custom rules hererules: {//! avoid add stylistic rules// non stylistic rules which are not in the standard but I need"no-debugger": "error","no-console": "error","no-extra-semi": "error","no-prototype-builtins": "error","require-atomic-updates": "error","array-callback-return": ["error",{allowImplicit: true}],"block-scoped-var": "error","guard-for-in": "error","no-alert": "error","no-implicit-coercion": "error","no-extra-label": "error","no-eq-null": "error","no-else-return": "error","no-case-declarations": "error","vars-on-top": "error","require-unicode-regexp": "error","require-await": "error",radix: "error","prefer-promise-reject-errors": ["error",{allowEmptyReject: true}],"prefer-named-capture-group": "error","no-void": "error","no-useless-concat": "error","no-useless-catch": "error","no-script-url": "error","no-return-await": "error","no-undef": "error","no-use-before-define": ["error",{functions: false,classes: true}],"no-delete-var": "error","no-label-var": "error","no-restricted-globals": ["error",{name: "event",message: "Use local parameter instead."}],// todo not good enough for confusing let foo=()=>{}"arrow-body-style": ["error","as-needed"],"arrow-parens": ["error","as-needed"],"no-confusing-arrow": ["error",{allowParens: true}],"no-var": "error","prefer-const": "error","prefer-rest-params": "error","prefer-spread": "error","require-yield": "error","symbol-description": "error",// eslint-plugin-vue Uncategorized rules"vue/v-on-function-call": ["error","never"],"vue/require-direct-export": "error",// 'vue/no-empty-pattern': 'error',"vue/eqeqeq": "error","vue/comma-dangle": "error",// disable if too many violations"vue/component-name-in-template-casing": ["error","PascalCase"|"kebab-case",{registeredComponentsOnly: true,ignores: []}]}};
and .stylelintrc.js
module.exports={extends: ["stylelint-config-recommended",// https://github.com/bjankord/stylelint-config-sass-guidelines"stylelint-config-sass-guidelines","stylelint-config-prettier"],plugins: ["stylelint-color-format","stylelint-no-indistinguishable-colors"],rules: {//! avoid add stylistic rules"color-named": "never","declaration-no-important": true,"selector-max-empty-lines": 0,"selector-max-id": 1,"selector-max-universal": 0,"no-unknown-animations": true,"selector-class-pattern": null,"declaration-property-value-blacklist": null,// todo reduce to 1 when BEM is determined"max-nesting-depth": [1,{ignore: ["pseudo-classes","blockless-at-rules"],ignoreAtRules: ["each","media","supports","include"]}],"scss/at-import-partial-extension-blacklist": null,"scss/at-import-partial-extension-whitelist": ["scss"],"scss/dollar-variable-pattern": /--.+/u,"scss/partial-no-import": null,"scss/double-slash-comment-inline": null,"scss/double-slash-comment-empty-line-before": null,"scss/selector-nest-combinators": null,"scss/dollar-variable-default": null,"scss/at-function-pattern": null,"scss/at-mixin-pattern": null,"scss/at-import-no-partial-leading-underscore": null,"plugin/stylelint-no-indistinguishable-colors": true,"color-format/format": {format: "rgb"}}};
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,
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-stagedwith 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.
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
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 and htmlhint for lint
prettier 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 and htmlhint validation.
Enable internal script in .html validation because we didn't add validation for that.
And in the user settings, take the vscode for example
{
"files.autoSave": "onFocusChange",
// call internal formatter for current file on save."editor.formatOnSave": true,
// set internal formatter as prettier-vscode"editor.defaultFormatter": "esbenp.prettier-vscode",
// default value is ['vue']"prettier.disableLanguages": [""],
// show eslint on status bar"eslint.alwaysShowStatus": true,
// some rules like [spaced-comment](https://github.com/prettier/prettier/issues/5755) enable in standard// but not disabled in prettier/standard, so need auto fix by eslint."eslint.autoFixOnSave": true,
// enable validation in real time"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "html",
"autoFix": true
},
{
"language": "vue",
"autoFix": true
}
],
// enable validation in real time"stylelint.enable": true,
"htmlhint.enable": true,
// disable vetur formatter because formatting job would be done by prettier"vetur.format.enable": false,
//disable vetur validation because// eslint plugin in editor will validate template and script using configuration file in project."vetur.validation.template": false,
"vetur.validation.script": false,
// stylelint plugin in editor will validate using configuration file in project."vetur.validation.style": false,
"html.validate.styles": false,
"css.validate": false,
"less.validate": false,
"scss.validate": false,
// we didn't validate script in html, so enable default validation"html.validate.scripts": true,
// disable default validate// eslint plugin in editor will validate template and script using configuration file in project."javascript.validate.enable": false,
// tslint plugin in editor will validate template and script using configuration file in project."typescript.validate.enable": false
}
And I made this image for a better understanding.
How to Handle History Files with Current Formatter and Linter?
Actually, there are many choices and it is up to you. 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 too much effect in the code review.
Or we can fix all the errors one by one though it will need lots of time.
...
If you want to lint and format all the files now, you might need to add these script in your package.json.
However, prettier would format these files. So, if you want to keep consistent with prettier we can add these files to .eslintignore like
!/*.js
vue-cli3.0 has choice for formatOnSave. 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 see Format 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 using prettier as default formatter.
This latest vue project format template can be found in my repository vue-project-template.
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,
ESLint
,prettier
,vscode internal formatter
and some other formatters which I don't know..eslintrc.js
,.prettierrc.js
,user settings
and other plugins likeeslint-plugin-html
,eslint-plugin-vue
, etc.What Do You Want?
Before we keep going we have to figure out one question.
After thinking, I figure it out.
To be more specific, I want
script
in .vue.style
in .vue.template
in .vue..html
.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,
Therefore, we have to do it one by one.
Main Work
Syntax-highlighting
I found two ways:
I would recommend
Vetur
becauseVetur
.Format and Lint .js,
script
andtemplate
in .vue.Parser
As ESLint said,
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 ineslint-plugin-html
,That's why we still can see some .eslintrc.js like below in old projects.
Also, as documented in vue-loader doc,
So, we can use
eslint-plugin-vue
to lint .js,script
andtemplate
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 isplugin: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:
Format and Lint .css, .less, .scss and
style
in .vue.As documented in vue-loader doc,
Format and lint
.html
.There is two cases happen to
.html
.One is vue component file like
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.htmlhint
would be needed to format and linthtml
in it.script
. However, I didn't addeslint-plugin-html
for this file becausebabel
. 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 supporthtmlhint
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 thePrettier
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:Actually, it's a good question. Someone just ask here,
And the answer is something like:
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 combinePrettier
withESLint
andstylelint
.Prettier First or Linter First?
Generally, there are four ways to combine them.
prettier-eslint
eslint-config-prettier
prettier-stylelint
Code ➡️ prettier ➡️ stylelint ➡️ Formatted
stylelint-config-prettier
Code ➡️ stylelint ➡️ prettier ➡️ Formatted
I guess most people chose
prettier-eslint
andprettier-stylelint
which iseslint-config-prettier
andstylelint-config-prettier
which isBoth of them would work when formatting and linting before commit. The only difference is
Obviously, the latter would decide the code style.
If you choose
prettier-eslint
andprettier-stylelint
, the pros arethe 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
andstylelint-config-prettier
, the pros areprettier-vscode
support auto fix and fix all at one time.the cons are
Prettier
only provide a few options for user to choose.Finally, I choose
eslint-config-prettier
andstylelint-config-prettier
.Actually, these two configs just do one thing:
So, when you chose this it means that
Also, you shouldn't add stylistic rules in your .eslintrc.js and .stylelintrc.js files as those rules would overwrite
eslint-config-prettier
andstylelint-config-prettier
. Even though you choseprettier-eslint
andprettier-stylelint
, you should also avoid adding conflicting stylistic rules between .prettierrc.js and .eslintrc.js or .stylelintrc.js.In the end, my .prettierrc.js
and .eslintrc.js
and .stylelintrc.js
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 usehusky
to add git hook and uselint-staged
to run my linters and formatters. So, in my project, I add .huskyrc.js,and .lint-staged.config.js,
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
andlint-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.
eslint
vscode also provides convenience like below,
eslint-plugin-vue
Find it via this issue.
stylelint
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
prettier
as default formatter.vetur
formatter.vetur
validation for .vue files and internal validation for .css, .less, .scss,style
in .html, .js.stylelint
,eslint
andhtmlhint
validation.script
in .html validation because we didn't add validation for that.And in the user settings, take the 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 and it is up to you. For example,
If you want to lint and format all the files now, you might need to add these script in your package.json.
And then start your fixing work from
npm run lint && npm run format
.Remarks
prettier
doesn't supportstylus
until 1.18.2 version.eslint
would ignore files whose names start from dot. For example,However,
prettier
would format these files. So, if you want to keep consistent withprettier
we can add these files to .eslintignore likevue-cli3.0
has choice forformatOnSave
. However, I don't recommend because it has multiple consSometimes 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.Reference
Source
The text was updated successfully, but these errors were encountered: