ESLint runs prettier twice if config in .eslintrc and .prettierrc

3.3k Views Asked by At

I am trying to solve a problem with battling formatting on save in VSCode. I do not have prettier installed as a standalone extension. I have eslint installed. I am working with typescript files.

In my editor, I see a warning on trailing commas and when I hit save, I see the trailing comma vanish, then reappear. I realized that I have trailing comma set to "none" in my .eslintrc.js file and set to "always" in my .prettierrc.js file. They are both below.

My have Vetur installed as well, but I think I only have vetur running on save because my vsconfig file specifies this:

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

But prettier is definitely being run twice. Is there some other setting I should be looking for? Or does eslint run prettier once for each set of config it finds.

Here is my eslintrc file:

module.exports = {
  root: true,

  env: {
    node: true,
    browser: true
  },

  extends: [
    'plugin:vue/strongly-recommended',
    '@vue/airbnb',
    '@vue/typescript',
    'plugin:prettier/recommended'
  ],

  parserOptions: {
    ecmaVersion: 2020,
    parser: '@typescript-eslint/parser',
    sourceType: 'module'
  },

  rules: {
    'no-console': 'off',
    'no-debugger': 'off',
    '@typescript-eslint/no-empty-function': 'off',
    '@typescript-eslint/no-namespace': 'off',
    '@typescript-eslint/no-explicit-any': 'off',
    '@typescript-eslint/no-non-null-assertion': 'off',
    '@typescript-eslint/no-non-null-asserted-optional-chain': 'off',
    'vue/component-name-in-template-casing': ['error', 'PascalCase'],
    'vue/no-v-html': 'off',
    'prettier/prettier': [
      'warn',
      {
        singleQuote: true,
        semi: true,
        trailingComma: 'none',
        printWidth: 100,
        tabWidth: 2,
        endOfLine: 'lf',
        arrowParens: 'always',
        bracketSpacing: true
      }
    ]
  },

  overrides: [
    {
      files: ['**/*.test.ts'],
      env: {
        jest: true
      }
    }
  ]
};

and here is my .pretterrc.js file:

module.exports = {
  semi: true,
  trailingComma: 'all',
  singleQuote: true,
  printWidth: 100,
  tabWidth: 2,
  endOfLine: 'lf',
  arrowParens: 'always',
  bracketSpacing: true
};

I know that I could just make the two files consistent and I will get the proper output, but I don't want the formatting to be run twice. Working with typescript files seems to be slow enough as it is without formatting twice all the time.

I think the relevant portions of my settings.json file are:

  "eslint.alwaysShowStatus": true,
  "eslint.validate": [
    "vue",
    "html",
    "javascript",
    "typescript"
  ],
  "editor.codeActionsOnSave": {
    "source.fixAll.eslint": true
  },
  "[vue]": {
    "editor.defaultFormatter": "octref.vetur"
  },
  "[typescript]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  "[json]": {
    "editor.defaultFormatter": "vscode.json-language-features"
  },
  "[html]": {
    "editor.defaultFormatter": "vscode.html-language-features"
  },
  "[javascript]": {
    "editor.defaultFormatter": "vscode.typescript-language-features"
  },
  "editor.formatOnSave": true,
  "vetur.experimental.templateInterpolationService": true,
  "vetur.format.defaultFormatter.js": "prettier-eslint",
  "vetur.format.defaultFormatter.ts": "prettier-tslint",
  "vetur.format.defaultFormatterOptions": {
    "js-beautify-html": {
      "wrap_attributes": "force-expand-multiline"
    },
    "prettyhtml": {
      "printWidth": 100,
      "singleQuote": false,
      "wrapAttributes": true,
      "sortAttributes": true
    },
    "vetur.grammar.customBlocks": {
      "docs": "md",
      "i18n": "json"
    }
  },

Any pointers of which settings to look at would be appreciated.

2

There are 2 best solutions below

0
On

I believe I have found the answer.

The first round of prettying is done by eslint and it uses the prettier config found in eslintrc. The second round of prettying is done by vetur on the typescript section of the vue file and it uses the prettier config found in the prettierrc file.

What I did to fix the problem is to tell vetur not to format the typescript code by changing these two lines in the settings.json file for the workspace:

  "vetur.format.defaultFormatter.js": "none",
  "vetur.format.defaultFormatter.ts": "none",

These were prettier-eslint previously. Once I changed these to none, the typescript portion of the file removed the trailing commas and left them removed. The html template portion of the file was still formatted properly.

I assume this will speed up my file save since vetur can now ignore the typescript portion of the file when saving since it has already been processed by eslint.

0
On

You don't need to put the prettier config in the .eslintrc file, as the latest version of ESLint-plugin-prettier will load it from .prettierrc