On save, VSCode is fixing eslint is fixing all the rules. How to fix the below conflict?
Expected Indentation
Unexpected Indentation
VScode Plugins in use:
[
"formulahendry.auto-close-tag",
"msjsdiag.debugger-for-chrome",
"hookyqr.beautify",
"mikestead.dotenv",
"dbaeumer.vscode-eslint",
"donjayamanne.githistory",
"eamodio.gitlens",
"sidthesloth.html5-boilerplate",
"ecmel.vscode-html-css",
"abusaidm.html-snippets",
"wix.vscode-import-cost",
"lonefy.vscode-js-css-html-formatter",
"eg2.vscode-npm-script",
"christian-kohler.npm-intellisense",
"sibiraj-s.vscode-scss-formatter",
"octref.vetur",
"blanu.vscode-styled-jsx",
"jcbuisson.vue",
"hollowtree.vue-snippets",
"wscats.vue",
"sdras.vue-vscode-snippets",
"dariofuzinato.vue-peek",
]
Error
Here is the config in use:
'vue/html-closing-bracket-newline': [
'error',
{
singleline: 'never',
multiline: 'never'
}
],
'indent': ['error', 2],
'vue/html-indent': ['error', 2],
'vue/script-indent': ['error', 2],
'vue/multiline-html-element-content-newline': 0
VSCode settings
{
"editor.formatOnSave": true,
"[javascript]": {
"editor.formatOnSave": true
},
"eslint.alwaysShowStatus": true,
"files.autoSave": "onFocusChange",
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"vue-html": "html",
"plaintext": "jade",
"edge": "html"
},
"emmet.syntaxProfiles": {
"javascript": "jsx"
},
"emmet.triggerExpansionOnTab": true,
"emmet.showSuggestionsAsSnippets": true,
"files.associations": {
"*.js": "javascriptreact"
},
"editor.fontSize": 14,
"git.enableSmartCommit": true,
"git.confirmSync": false,
"search.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/bower_components": true,
"**/tmp": true,
"**/.bin": true,
"**/.next": true,
"**/__snapshots__/**": true,
"**/coverage/**": true,
"**/report/**": true
},
"javascript.updateImportsOnFileMove.enabled": "always",
"explorer.confirmDragAndDrop": false,
"explorer.confirmDelete": false,
"diffEditor.ignoreTrimWhitespace": false,
"workbench.editor.enablePreviewFromQuickOpen": false,
"files.exclude": {
".next": true,
"*.log": true,
"**/__pycache__": true,
"**/node_modules": true,
"**/o": true,
"dist": true,
"geckodriver.log": true,
"package-lock.json": true,
"yarn.lock": true
},
"window.zoomLevel": 1,
"editor.find.globalFindClipboard": true,
"editor.fontLigatures": true,
"editor.formatOnType": true,
"team.showWelcomeMessage": false,
"git.autofetch": true,
"workbench.startupEditor": "newUntitledFile",
"editor.codeActionsOnSave": {
// For ESLint
"source.fixAll.eslint": true,
// For TSLint
"source.fixAll.tslint": true,
// For Stylelint
"source.fixAll.stylelint": true
},
"launch": {},
"workbench.colorCustomizations": {},
"javascript.validate.enable": true,
"javascript.suggestionActions.enabled": false,
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"prettier.disableLanguages": [],
"vetur.format.defaultFormatter.js": "vscode-typescript",
"vetur.format.defaultFormatter.html": "js-beautify-html",
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"eslint.validate": [
"vue",
"html",
"javascript",
"typescript",
"javascriptreact",
"typescriptreact"
]
}
4 space/tab is a pain and its a challenge to fix. Hence sticking to 2 space along with few changes in settings to match my requirement.
.vscode/settings.json
{
"editor.formatOnSave": true,
"[javascript]": {
"editor.tabSize": 4,
"editor.insertSpaces": true
},
"[vue]": {
"editor.tabSize": 4,
"editor.insertSpaces": true
},
"eslint.alwaysShowStatus": true,
"files.autoSave": "onFocusChange",
"emmet.includeLanguages": {
"javascript": "javascriptreact",
"vue-html": "html",
"plaintext": "jade",
"edge": "html"
},
"emmet.syntaxProfiles": {
"javascript": "jsx"
},
"emmet.triggerExpansionOnTab": true,
"emmet.showSuggestionsAsSnippets": true,
"files.associations": {
"*.js": "javascriptreact"
},
"editor.fontSize": 14,
"git.enableSmartCommit": true,
"git.confirmSync": false,
"search.exclude": {
"**/.git": true,
"**/node_modules": true,
"**/bower_components": true,
"**/tmp": true,
"**/.bin": true,
"**/.next": true,
"**/__snapshots__/**": true,
"**/coverage/**": true,
"**/report/**": true
},
"javascript.updateImportsOnFileMove.enabled": "always",
"explorer.confirmDragAndDrop": false,
"explorer.confirmDelete": false,
"diffEditor.ignoreTrimWhitespace": false,
"workbench.editor.enablePreviewFromQuickOpen": false,
"files.exclude": {
".next": true,
"*.log": true,
"**/__pycache__": true,
"**/node_modules": true,
"**/o": true,
"dist": true,
"geckodriver.log": true,
"package-lock.json": true,
"yarn.lock": true
},
"window.zoomLevel": 1,
"editor.find.globalFindClipboard": true,
"editor.fontLigatures": true,
"editor.formatOnType": true,
"team.showWelcomeMessage": false,
"git.autofetch": true,
"workbench.startupEditor": "newUntitledFile",
"editor.codeActionsOnSave": {
// For ESLint
"source.fixAll.eslint": true,
// For TSLint
"source.fixAll.tslint": true,
// For Stylelint
"source.fixAll.stylelint": true
},
"launch": {},
"workbench.colorCustomizations": {},
"javascript.validate.enable": true,
"javascript.suggestionActions.enabled": false,
"editor.insertSpaces": false,
"editor.detectIndentation": false,
"prettier.disableLanguages": [],
"vetur.format.defaultFormatter.html": "prettyhtml",
"vetur.format.defaultFormatter.css": "prettier",
"vetur.format.defaultFormatter.postcss": "prettier",
"vetur.format.defaultFormatter.scss": "prettier",
"vetur.format.defaultFormatter.less": "prettier",
"vetur.format.defaultFormatter.stylus": "stylus-supremacy",
"vetur.format.defaultFormatter.js": "prettier",
"vetur.format.defaultFormatter.ts": "prettier",
"vetur.format.defaultFormatter.sass": "sass-formatter",
"vetur.validation.template": true,
"vetur.format.defaultFormatterOptions": {
"prettyhtml": {
"printWidth": 100, // No line exceeds 100 characters
"singleQuote": false // Prefer double quotes over single quotes
}
},
"javascript.format.insertSpaceBeforeFunctionParenthesis": true,
"eslint.validate": ["javascript", "javascriptreact", "html", "vue"],
"eslint.options": {
"extensions": [".js", ".vue"]
},
"eslint.probe": [
"javascript",
"javascriptreact",
"typescript",
"typescriptreact",
"html",
"vue"
]
}
package.json devDependencies
"devDependencies": {
"@vue/cli-plugin-babel": "4.2.3",
"@vue/cli-plugin-eslint": "^4.3.1",
"@vue/cli-plugin-router": "4.2.3",
"@vue/cli-service": "4.2.3",
"@vue/eslint-config-prettier": "6.0.0",
"@vue/eslint-config-standard": "^5.1.2",
"babel-eslint": "^10.1.0",
"eslint": "6.8.0",
"eslint-config-airbnb": "^18.1.0",
"eslint-config-import": "0.13.0",
"eslint-config-prettier": "^6.11.0",
"eslint-plugin-es-beautifier": "^1.0.1",
"eslint-plugin-import": "^2.20.2",
"eslint-plugin-modules": "^1.1.1",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-prettier": "^3.1.3",
"eslint-plugin-prettier-vue": "^2.1.0",
"eslint-plugin-promise": "^4.2.1",
"eslint-plugin-standard": "^4.0.0",
"eslint-plugin-vue": "^6.2.2",
"express": "^4.17.1",
"fibers": "4.0.2",
"gulp": "4.0.2",
"gulp-append-prepend": "1.0.8",
"husky": "^4.2.5",
"jest": "^25.4.0",
"jest-sonar-reporter": "^2.0.0",
"json-server": "^0.16.1",
"node-sass": "4.13.1",
"nodemon": "^2.0.3",
"pretty-quick": "^2.0.1",
"sass": "1.26.3",
"sass-loader": "^8.0.2",
"vue-jest": "^3.0.5",
"vue-template-compiler": "2.6.11"
},
.eslintrc.js
module.exports = {
root: true,
env: {
node: true,
jest: true
},
extends: ['plugin:vue/essential', '@vue/standard'],
rules: {
quotes: [
2,
'single',
{
avoidEscape: true
}
],
'no-console': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-debugger': process.env.NODE_ENV === 'production' ? 'warn' : 'off',
'no-unused-vars': [
'error',
{
vars: 'all',
varsIgnorePattern: 'css',
args: 'all'
}
],
'no-use-before-define': [
'error',
{
functions: false,
classes: true
}
],
'no-var': 'error',
'prefer-const': 2,
eqeqeq: [
'error',
'always',
{
null: 'ignore'
}
],
'no-array-constructor': 'error',
'no-new-object': 'error',
'no-bitwise': 'error',
'no-redeclare': 2,
'no-proto': 2,
'no-invalid-regexp': 2,
'vue/script-indent': ['error', 2],
'vue/html-closing-bracket-newline': [
'error',
{
singleline: 'never',
multiline: 'always'
}
],
'space-before-function-paren': [2, 'never'],
'no-new': 0,
'no-implied-eval': 0,
'handle-callback-err': 0,
'no-extend-native': 0,
indent: ['error', 2, { SwitchCase: 1 }],
semi: [2, 'always'],
'vue/html-indent': [
'error',
2,
{
attribute: 1,
baseIndent: 1,
closeBracket: 0,
alignAttributesVertically: true,
ignores: ['pre', 'textarea', 'span']
}
],
'no-tabs': 0,
'vue/singleline-html-element-content-newline': [
'error',
{
ignoreWhenNoAttributes: true,
ignoreWhenEmpty: true,
ignores: ['pre', 'textarea', 'span']
}
]
},
parserOptions: {
parser: 'babel-eslint'
},
globals: {
console: true,
alert: true,
document: true,
__dirname: true,
require: true,
window: true,
process: true,
module: true,
define: true,
_: true,
Promise: true,
setTimeout: true,
clearTimeout: true,
mount: true,
clearInterval: true,
setInterval: true,
$: false,
MutationObserver: false,
Map: false,
localStorage: true
}
};
.prettierrc.js
module.exports = {
singleQuote: true,
tabWidth: 2
};
.jshintrc
{
"esversion": 9
}
.editorconfig
[*.{js,jsx,ts,tsx,vue}]
indent_style = space
indent_size = 2
trim_trailing_whitespace = true
insert_final_newline = true
That's it, and everything working as per expectations. Hope this helps someone.