简体   繁体   English

使用 ESLint 和 Prettier 在 Visual Studio Code 中保存时无法获得正确的自动格式化

[英]Can't get correct autoformat on save in Visual Studio Code with ESLint and Prettier

in Visual Studio Code with ESLint and Prettier when working on .vue files, it seems I can't get vue/max-attributes-per-line to auto-fix correctly.在使用 ESLint 和 Prettier 的 Visual Studio Code 中处理 .vue 文件时,似乎我无法让 vue/max-attributes-per-line 正确自动修复。

For example, with vue/max-attributes-per-line set to 'off', and I try to add line breaks manually it corrects it to always have every element on no more than one line, no matter if it is 81, 120, 200, or more characters wide.例如,将 vue/max-attributes-per-line 设置为“off”,并且我尝试手动添加换行符,它会更正它以使每个元素始终位于不超过一行的位置,无论是 81 还是 120 、200 或更多字符宽。 How can I figure out what is forcing my markup elements onto exactly one line?我怎样才能弄清楚是什么迫使我的标记元素恰好在一行上?

I am using ESLint version 5.1.0 and Visual Studio Code (without the Prettier Extension), with Prettier 1.14.2.我使用的是 ESLint 5.1.0 版和 Visual Studio Code(没有 Prettier 扩展),以及 Prettier 1.14.2。

Here's the example in a .vue file-- I cannot make this go on multiple lines no matter what I do, when 'vue/max-attributes-per-line': 'off' .这是 .vue 文件中的示例——当'vue/max-attributes-per-line': 'off'时,无论我做什么,我都无法在多行上进行。 Every time I save, it forces the long line of markup to be all on one line.每次我保存时,它都会强制将一长串标记全部放在一行上。

<template>
  <font-awesome-icon v-if="statusOptions.icon" :icon="statusOptions.icon" :spin="statusOptions.isIconSpin" :class="['saving-indicator', 'pl-1', 'pt-1', statusOptions.iconClasses]" />
</template>

If I set 'vue/max-attributes-per-line': 2 , it formats like so, with one line break(which is quite wrong as well).如果我设置'vue/max-attributes-per-line': 2 ,它的格式是这样的,有一个换行符(这也是完全错误的)。

<font-awesome-icon
  v-if="statusOptions.icon" 
  :icon="statusOptions.icon"
  :spin="statusOptions.isIconSpin"
  :class="['saving-indicator', 'pl-1', 'pt-1', statusOptions.iconClasses]"
/>

If I try to reformat it manually, it just reverts to the above when I save.如果我尝试手动重新格式化它,它会在我保存时恢复到上述状态。

Additionally, it seems to reformat twice when I hit Ctrl+S: first it reformats to put it all on one line, then a half-second later the formatting above results.此外,当我按下 Ctrl+S 时,它似乎重新格式化了两次:首先它重新格式化以将其全部放在一行上,然后半秒后格式化上述结果。 Any ideas ?什么想法吗? What is causing this weirdness--are there multiple reformatters running?是什么导致了这种奇怪现象——是否有多个重新格式化程序在运行? How do I figure out what the first one is to disable it?我如何弄清楚第一个是什么禁用它?

VS Code workspace settings: VS Code 工作区设置:

{
  "editor.formatOnType": false,
  "editor.formatOnPaste": false,
  "editor.formatOnSave": true,
  "[javascript]": {
    "editor.tabSize": 2
  },
  "[vue]": {
    "editor.tabSize": 2
  },
  "[csharp]": {
    "editor.tabSize": 4
  },
  "javascript.format.insertSpaceAfterFunctionKeywordForAnonymousFunctions": true,
  "javascript.referencesCodeLens.enabled": true,
  "vetur.validation.script": false,
  "vetur.validation.template": false,
  "eslint.autoFixOnSave": true,
  "eslint.alwaysShowStatus": true,
  "eslint.options": {
    "extensions": [
      ".html",
      ".js",
      ".vue",
      ".jsx"
    ]
  },
  "eslint.validate": [
    {
      "language": "html",
      "autoFix": true
    },
    {
      "language": "vue",
      "autoFix": true
    },
    "vue-html",
    {
      "language": "javascript",
      "autoFix": true
    },
    {
      "language": "javascriptreact",
      "autoFix": true
    }
  ],
  "editor.rulers": [
    80,
    100
  ]
}

.eslintrc.js: .eslintrc.js:

module.exports = {
  parserOptions: {
    parser: 'babel-eslint'
  },
  env: {
    browser: true,
    node: true,
    jest: true
  },
  globals: {
    expect: true
  },
  extends: [
    'prettier',
    'plugin:vue/recommended',        // /base, /essential, /strongly-recommended, /recommended
    'plugin:prettier/recommended',   // turns off all ESLINT rules that are unnecessary due to Prettier or might conflict with Prettier. 
    'eslint:recommended'
  ],
  plugins: ['vue', 'prettier'],
  rules: {
    'vue/max-attributes-per-line': 'off',
    'prettier/prettier': [            // customizing prettier rules (not many of them are customizable)
      'error',
      {
        singleQuote: true,
        semi: false,
        tabWidth: 2
      },
    ],
    'no-console': 'off'
  }
}

Without changing any settings, ESLint --fix does indeed format properly--breaking all my .vue template elements into many lines properly.在不更改任何设置的情况下, ESLint --fix确实正确格式化——将我所有的 .vue 模板元素正确地分成多行。 So any ideas how I whip VS Code into shape?那么我有什么想法可以让 VS Code 成型? The above settings didn't help, but I am at a loss how as to even know what is interfering.上述设置没有帮助,但我不知如何甚至知道什么是干扰。 Any ideas?有任何想法吗?

To emphasize, when I save in VS Code, a long HTML element will collapse to one line then break to two lines a half-second later, all from one save operation.强调一下,当我在 VS Code 中保存时,一个很长的 HTML 元素将折叠为一行,然后在半秒后拆分为两行,所有这些都来自一次保存操作。 I'm expecting it instead to break it up into many lines.我期待它把它分解成多行。 It would be okay if it took several saves, but instead the first save shows this behavior as well as every subsequent save.如果需要多次保存也没关系,但是第一次保存以及随后的每次保存都会显示此行为。

Short answer: I needed: "editor.formatOnSave": false, "javascript.format.enable": false .简短回答:我需要: "editor.formatOnSave": false, "javascript.format.enable": false

I finally found the magical combination of settings, thanks to this thread from Wes Bos on Twitter .多亏了Wes Bos 在 Twitter 上的这个帖子,我终于找到了神奇的设置组合。 I was right in my suspicion that there seem to be multiple conflicting formatters.我怀疑似乎有多个相互冲突的格式化程序是正确的。 Though I'm not sure what they actually are, I was able to turn off all but eslint as follows:虽然我不确定它们到底是什么,但我能够关闭除 eslint 之外的所有内容,如下所示:

In the VS Code settings, I need:在 VS Code 设置中,我需要:

"editor.formatOnSave": false,
"javascript.format.enable": false,
"eslint.autoFixOnSave": true,
"eslint.alwaysShowStatus": true,
"eslint.options": {
  "extensions": [ ".html", ".js", ".vue", ".jsx" ]
},
"eslint.validate": [
  { "language": "html", "autoFix": true },
  { "language": "vue", "autoFix": true },
  { "language": "javascript", "autoFix": true },
  { "language": "javascriptreact", "autoFix": true }
]

In .eslintrc.js, then I can use the settings in my original post and then also change 'vue/max-attributes-per-line' as desired.在 .eslintrc.js 中,我可以使用原始帖子中的设置,然后根据需要更改“vue/max-attributes-per-line”。 Then VS Code's ESLint plugin will format code one step at a time on every save, much as kenjiru wrote.然后 VS Code 的 ESLint 插件将在每次保存时一次一步地格式化代码,就像 kenjiru 写的那样。 One last snag: HMR won't pick up these changes, so rebuild from scratch.最后一个障碍:HMR 不会接受这些更改,所以从头开始重建。

With 'vue/max-attributes-per-line': 'off' the rule is disabled so VSCode does not try to fix the long line on autosave.使用'vue/max-attributes-per-line': 'off'规则被禁用,因此 VSCode 不会尝试修复自动保存时的长行。 Other eslint fixes are applied, as expected.正如预期的那样,应用了其他 eslint 修复程序。

With 'vue/max-attributes-per-line': 1 VSCode fixes only one error per save.使用'vue/max-attributes-per-line': 1 VSCode 每次保存仅修复一个错误。 This is a known limitation of vscode-eslint这是vscode-eslint 的一个已知限制

vscode-eslint only does a single pass in order to keep to a minimum the amount of edits generated by the plugin. vscode-eslint只执行一次,以将插件生成的编辑量保持在最低限度。 The goal is to keep as many markers (like break points) in the file as possible.目标是在文件中保留尽可能多的标记(如断点)。

VSCode has a time limit of 1 second for all the plugins to compute the change set on save. VSCode 有 1 秒的时间限制,所有插件在保存时计算更改集。 If one of the plugins causes the other plugins to not run for 3 times in a row, it will be disabled.如果其中一个插件导致其他插件连续 3 次无法运行,它将被禁用。

eslint --fix runs all the rules in a loop until there are no more linting errors. eslint --fix运行所有规则,直到不再出现 linting 错误。 I think it has a limit of 10 iterations maximum.我认为它最多有 10 次迭代的限制。

See these links for more details:有关更多详细信息,请参阅这些链接:

I've created a minimal setup to demonstrate this issue:我创建了一个最小设置来演示这个问题:

I know this is old but in case anyone should find this and not have success with the posted solutions, the fix for me was to add:我知道这是旧的,但如果有人发现这个并且在发布的解决方案中没有成功,我的解决方法是添加:

"editor.codeActionsOnSave": {
   "source.fixAll": true
}

I did not need "editor.formatOnSave": true for some reason.由于某种原因,我不需要"editor.formatOnSave": true I do not have Prettier installed - only ESLint - but this now performs any fixes automatically when I save.没有安装 Prettier - 只有 ESLint - 但现在我保存时它会自动执行任何修复。

This is the setup I ended up going with in VSC settings.json file.这是我最终在 VSC settings.json文件中使用的settings.json

Works perfectly for locally set up eslint disabling the default vetur settings (if the plugin is installed).非常适合本地设置eslint禁用默认 vetur 设置(如果安装了插件)。

"files.autoSave": "onFocusChange",
"editor.codeActionsOnSave": {
  "source.fixAll.eslint": true
},
"editor.formatOnSave": false,
"javascript.format.enable": false,
"eslint.alwaysShowStatus": true,
"eslint.options": {
  "extensions": [ ".html", ".js", ".vue", ".jsx" ]
},
"eslint.validate": [
  "html",
  "javascript",
  "vue"
],

I tried this things and it didn't worked.我试过这些东西,但没有奏效。

"typescript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
"javascript.format.insertSpaceAfterOpeningAndBeforeClosingNonemptyBraces": false,
"typescript.format.insertSpaceAfterOpeningAndBeforeClosingEmptyBraces": false,

but it at last i tried this.但最后我试过了。 and worked "diffEditor.wordWrap": "off" ,并工作"diffEditor.wordWrap": "off" ,

I bumped into the same issue, and surprisingly found that prettier and vetur were conflicting.我遇到了同样的问题,意外地发现 prettier 和 vetur 是矛盾的。 I had to disable vetur formatter and it now works as expected.我不得不禁用 vetur 格式化程序,它现在按预期工作。

If you have this section in your editor's settings.json and you have prettier installed,如果您在编辑器的settings.json有此部分并且安装了更漂亮的,

{
 "[vue]": {
     "editor.defaultFormatter": "octref.vetur",
  },
}

chances are, these two formatters are conflicting and thus the unexpected behaviour.很有可能,这两个格式化程序是冲突的,因此会出现意外的行为。

A quick workaround is to comment it as below, or simply delete it permanently.一个快速的解决方法是在下面评论它,或者干脆永久删除它。

{
 "[vue]": {
     // "editor.defaultFormatter": "octref.vetur",
  },
}

I've struggled through a similar problem.我一直在努力解决类似的问题。 I tried the solution above but didn't work for me, unfortunately.我尝试了上面的解决方案,但不幸的是对我不起作用。 I'm using eslint and Vetur, didn't install prettier plugin but configured it via eslint and enabled "eslint.autoFixOnSave": true.我正在使用 eslint 和 Vetur,没有安装更漂亮的插件,而是通过 eslint 配置它并启用了“eslint.autoFixOnSave”:true。 I finally got the correct autoformat on save by removing the following configuration in settings.json.通过删除 settings.json 中的以下配置,我终于在保存时获得了正确的自动格式。 Not sure why but it's working for me.不知道为什么,但它对我有用。

"eslint.options": {
  "extensions": [".html", ".js", ".vue", ".jsx"]
},
"eslint.validate": [{
    "language": "html",
    "autoFix": true
  },
  {
    "language": "vue",
    "autoFix": true
  },
  {
    "language": "javascript",
    "autoFix": true
  },
  {
    "language": "javascriptreact",
    "autoFix": true
  }
]

Will update this answer if I get other issues related to this.如果我遇到与此相关的其他问题,将更新此答案。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM