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

时间:2018-08-30 17:41:52

标签: vue.js visual-studio-code eslint prettier

在处理.vue文件时,在带有ESLint和Prettier的Visual Studio代码中,看来我无法获得vue / max-attributes-per-line自动正确修复。

例如,将vue / max-attributes-per-line设置为“ off”,并且我尝试手动添加换行符,它将其校正为始终将每个元素都放在一行内,无论是否81、120、200或更多字符宽。 如何找出将我的标记元素强制排成一行的原因?

我正在使用带有Prettier 1.14.2的ESLint版本5.1.0和Visual Studio Code(不带Prettier扩展名)。

这是.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元素将折叠为一行,然后在半秒后断裂为两行,所有操作均来自一次保存操作。我希望它能分成许多行。进行几次保存都可以,但是第一次保存会显示此行为以及以后的所有保存。

7 个答案:

答案 0 :(得分:26)

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

由于this thread from Wes Bos on Twitter,我终于找到了设置的神奇组合。我猜对了,似乎有多个相互冲突的格式化程序,这是正确的。尽管我不确定它们实际上是什么,但我可以按如下所示关闭所有设备,但按如下所述:

在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'。然后,就像kenjiru所写的那样,VS Code的ESLint插件将在每次保存时一次格式化代码。最后一个障碍:HMR无法接受这些更改,因此请从头开始进行重建。

答案 1 :(得分:4)

使用'vue/max-attributes-per-line': 'off'时,该规则被禁用,因此VSCode不会尝试将长行固定为自动保存。可以按预期应用其他eslint修复程序。

使用'vue/max-attributes-per-line': 1时,VSCode每次保存只能修复一个错误。这是 vscode-eslint

的已知限制

vscode-eslint 仅执行一次操作,以将插件生成的编辑量保持在最低水平。目的是在文件中保留尽可能多的标记(如断点)。

VSCode的所有插件的时限为1秒,以计算保存时的更改集。如果其中一个插件导致其他插件连续3次未运行,则将其禁用。

eslint --fix循环运行所有规则,直到没有其他掉毛错误为止。我认为最多可以重复10次。

有关更多详细信息,请参见以下链接:

我创建了一个最小的安装程序来演示此问题:

答案 2 :(得分:2)

这是我最终在 VSC settings.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"
],

答案 3 :(得分:0)

我一直在努力解决类似的问题。我尝试了上述解决方案,但不幸的是,该方法对我没有用。我正在使用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
    }
  ]

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

答案 4 :(得分:0)

我碰到了同样的问题,令人惊讶地发现,漂亮和宽容是矛盾的。我不得不禁用vetur formatter,它现在可以按预期工作。

如果您的编辑器的settings.json中有此部分,并且安装的更漂亮,则

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

机会是,这两个格式化程序发生冲突,因此出现了意外的行为。

一种快速的解决方法是按以下说明对其进行评论,或者只是将其永久删除。

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

答案 5 :(得分:0)

我知道这已经很老了,但是万一有人发现它并且发布的解决方案不成功,我的解决方法是添加:

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

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

答案 6 :(得分:0)

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

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

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