How to resolve eslint(vue/html-closing-bracket-newline) conflict
Asked Answered
S

5

3

On save, VSCode is fixing eslint is fixing all the rules. How to fix the below conflict?

Expected Indentation

Expected Indentation

Unexpected 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

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"
    ]
}
  • Multiline formatting should be retained, but the closing bracket should be in the same line itself as expected from the image.
  • There should be no conflict between eslint and vscode settings
  • Require necessary vscode settings. and eslint settings for vue setup Also, the sass files should not get affected with alignments every time on pre-commit checks.
  • It will be good if tab alignments are considered instead of 2 spaces for vue, js and sass files
Squander answered 10/5, 2020 at 16:47 Comment(4)
Sick and tired of these conflicts. Is there no solution to this problem?Squander
I'm guessing you've already done this, but did you follow this?: vuejs.github.io/vetur/linting-error.html#linting-error-checking to either change eslint to use essentials only, or to override the plugin's fixed linting settings and make sure template validation is off?Actinal
After following the vetur guidelines from the provided link: 1. Still the HTML tag is closing next line. 2. vue-cli-service lint --fix is not throwing any lint errors even the template files with 2 space is not fixing. I need indentation to be fixed to tabs during lint time which runs on pre-commit hooks.Squander
@MithunShreevatsa: I am still getting "Multiline formatting should be retained, but the closing bracket should be in the same line itself as expected from the image." issue. Any suggestionMudpack
S
3

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.

Squander answered 17/5, 2020 at 17:4 Comment(1)
Het which extensions you have installed?Mudpack
D
2

you can config .prettierrc.js

bracketSameLine: true
Druggist answered 11/2, 2022 at 8:45 Comment(0)
O
0

You can change your config to this, hopefully it should allow what you are trying to do:

{
  "vue/html-closing-bracket-newline": ["error", {
    "singleline": "never",
    "multiline": "always"
  }]
}

If you want to read more about it, please refer this.

Orpha answered 13/5, 2020 at 15:24 Comment(0)
N
0

Add in .eslintrc under the rules:

rules: {
  "prettier/prettier": [
    "warn",
      {
        htmlWhitespaceSensitivity: "ignore"
      }
  ]
}
Nocti answered 19/10, 2022 at 8:19 Comment(0)
S
-1

if I have understood correctly, what you need is to use in your eslint extends:

  extends: [
    'plugin:vue/recommended',
    '@vue/standard',
  ]

which have pretty much everything you need for a sane formatting.

Keep in mind you have to install them

My vs-code settings just have the default formatter

"vetur.format.defaultFormatter.html": "js-beautify-html",
...
"editor.formatOnSave": true,
...
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},

And nothing else related to this matter - I hope this helps.

Strong answered 13/5, 2020 at 7:25 Comment(7)
Error: Failed to load config "@vue/standardSquander
You need to install them first. npmjs.com/package/@vue/eslint-config-standard && npmjs.com/package/eslint-plugin-vueStrong
Unfortunately, your proposed solution is leading a lot of dependency installation not helping me to resolveSquander
I am sorry, but what I am suggesting is the preferred and recommended way. Whatever else is most likely spaghetti. If you use Vue cli everything is out of the box for you to work.Strong
I am just looking for closing tag same line with a tab indentationSquander
I understand that. Installing the recommended vue eslint rules, will help you.Strong
I should turn off just one particular rule and support for tabs properly because eslint/vue has a conflict with 4 space indentation.Squander

© 2022 - 2024 — McMap. All rights reserved.