40

在使用 ESLint 和 Prettier 的 Visual Studio Code 中处理 .vue 文件时,似乎我无法正确地自动修复 vue/max-attributes-per-line。

例如,将 vue/max-attributes-per-line 设置为“关闭”,并且我尝试手动添加换行符,它会更正它以始终将每个元素放在不超过一行的位置,无论它是 81、120 , 200 或更多字符宽。 我怎样才能弄清楚是什么迫使我的标记元素恰好在一行上?

我正在使用 ESLint 5.1.0 版和 Visual Studio Code(没有 Prettier 扩展)和 Prettier 1.14.2。

这是 .vue 文件中的示例——无论我做什么,当 'vue/max-attributes-per-line': 'off'. 每次我保存时,它都会强制一长串标记都在一行上。

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

如果我设置'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]"
/>

如果我尝试手动重新格式化它,它只会在我保存时恢复到上述状态。

此外,当我按 Ctrl+S 时,它似乎重新格式化了两次:首先它重新格式化以将其全部放在一行上,然后半秒后格式化上述结果。 有什么想法吗?是什么导致了这种怪异——是否有多个重新格式化程序正在运行?我如何弄清楚第一个是禁用它?

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:

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'
  }
}

在不更改任何设置的情况下,ESLint --fix确实可以正确格式化——将我所有的 .vue 模板元素正确地分成多行。那么有什么想法可以让 VS Code 成形吗?上述设置没有帮助,但我什至不知道是什么在干扰。有任何想法吗?

需要强调的是,当我在 VS Code 中保存时,一个长的 HTML 元素会折叠成一行,然后在半秒后断成两行,这一切都来自一次保存操作。我希望它把它分成多行。如果它需要多次保存,那将是可以的,但第一次保存会显示此行为以及随后的每次保存。

4

7 回答 7

81

简短的回答:我需要:"editor.formatOnSave": false, "javascript.format.enable": false

感谢Wes Bos 在 Twitter 上的这个帖子,我终于找到了神奇的设置组合。我怀疑似乎有多个相互冲突的格式化程序是正确的。虽然我不确定它们实际上是什么,但我能够关闭除 eslint 之外的所有内容,如下所示:

在 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 }
]

在 .eslintrc.js 中,我可以使用原始帖子中的设置,然后根据需要更改“vue/max-attributes-per-line”。然后 VS Code 的 ESLint 插件将在每次保存时一步一步格式化代码,就像 kenjiru 写的那样。最后一个问题:HMR 不会接受这些更改,所以从头开始重建。

于 2018-09-10T14:13:05.387 回答
5

由于'vue/max-attributes-per-line': 'off'该规则被禁用,因此 VSCode 不会尝试修复自动保存的长行。正如预期的那样,应用了其他 eslint 修复程序。

使用'vue/max-attributes-per-line': 1VSCode 每次保存仅修复一个错误。这是vscode-eslint的一个已知限制

vscode-eslint只执行一次传递,以便将插件生成的编辑量保持在最低限度。目标是在文件中保留尽可能多的标记(如断点)。

VSCode 的所有插件在保存时计算更改集的时间限制为 1 秒。如果其中一个插件导致其他插件连续 3 次无法运行,它将被禁用。

eslint --fix循环运行所有规则,直到不再有 linting 错误。我认为它的最大迭代次数为 10 次。

有关更多详细信息,请参阅这些链接:

我创建了一个最小设置来演示这个问题:

于 2018-09-08T11:02:24.687 回答
2

这是我最终在 VSCsettings.json文件中使用的设置。

非常适合在本地设置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"
],
于 2021-01-27T20:52:11.960 回答
2

我知道这已经过时了,但如果有人发现这个并且发布的解决方案没有成功,我的解决方法是添加:

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

由于某种原因我不需要"editor.formatOnSave": true。我没有安装 Prettier - 只有 ESLint - 但是现在我保存时会自动执行任何修复。

于 2020-09-19T19:17:38.137 回答
0

我试过这些东西,但没有奏效。

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

但最后我尝试了这个。并工作 "diffEditor.wordWrap": "off"

于 2021-01-17T14:56:45.993 回答
-1

我遇到了同样的问题,令人惊讶地发现 prettier 和 vetur 是冲突的。我不得不禁用 vetur 格式化程序,它现在按预期工作。

如果你的编辑器中有这个部分settings.json并且你安装了 prettier,

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

很有可能,这两个格式化程序是冲突的,因此会出现意想不到的行为。

一个快速的解决方法是如下评论它,或者干脆永久删除它。

{
 "[vue]": {
     // "editor.defaultFormatter": "octref.vetur",
  },
}
于 2020-05-02T12:13:54.880 回答
-2

我一直在努力解决类似的问题。不幸的是,我尝试了上面的解决方案,但对我不起作用。我正在使用 eslint 和 Vetur,没有安装更漂亮的插件,而是通过 eslint 配置它并启用“eslint.autoFixOnSave”:true。通过删除 settings.json 中的以下配置,我终于在保存时获得了正确的自动格式化。不知道为什么,但它对我有用。

"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
  }
]

如果我遇到与此相关的其他问题,将更新此答案。

于 2019-06-18T14:45:05.567 回答