visual-studio-codeeslintprettier

In VSCode, how do I effectively run eslint --fix and prettier --write on "Format Document"?


For context, I've locally installed prettier, eslint, and their respective VS Code extensions. I used the word "effectively" in my title because I don't literally need to run eslint --fix; prettier --write on "Format Document," I merely want the current file to change as though I did.

There are plenty of questions about running eslint and prettier on save, but I have autosave turned on: pressing ctrl + S feels unnatural. On the other hand, I run "Format Document" all the time.

Is there a way I can have "Format Document" run eslint --fix and prettier --write (in that order1) on the current file? I know I can put this in my Visual Studio code settings.json file:

  "[typescript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },
  "[javascript]": {
    "editor.defaultFormatter": "dbaeumer.vscode-eslint"
  },

or this:

  "[typescript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },
  "[javascript]": {
    "editor.defaultFormatter": "esbenp.prettier-vscode"
  },

but that runs eslint --fix or prettier --write on "Format Document." I want to run both. Is this possible?


I've read the prettier documentation on integrating with linters, and some of those links appear to be relevant to my question, but those same links are recommended against. Also, most of those projects (and most of the questions on this site) run in the opposite order: I want eslint --fix then prettier, but everyone else wants prettier then eslint --fix. And to be honest, I'm not sure why. I've explained my reasoning in a github issue, but this is tangential to my actual question. This is why I bring it up: if the answer goes against the recommendations of prettier, please include some justification for why the prettier recommendations don't apply.


1: As I mentioned in the beginning, I don't really care about the order in which these run, I care about the result. The file should have the same formatting as running eslint --fix; prettier --write on the CLI.


Solution

  • VSCode doesn't support chaining multiple formatters. More at this related question.

    But chaining formatters isn't the answer to your problem. If you're using Prettier and ESLint properly then they do not overlap in their ruleset. You can use eslint-plugin-prettier to format the document with only ESLint and it will run Prettier as an ESLint rule. Adding eslint-config-prettier disables any ESLint rules that would conflict with Prettier.

    Aftewards, running eslint --fix would apply both your ESLint and Prettier rules in a single format.

    If you would like to use ESLint with other filetypes then you need to find ESLint plugins that work for those filetypes. They require installation and configuration unique to each plugin. An example is eslint-plugin-jsonc to add support for JSONC.

    In package.json:

    {
      "devDependencies": {
        "@typescript-eslint/eslint-plugin": "^6.10.0",
        "@typescript-eslint/parser": "^6.10.0",
        "eslint": "^8.53.0",
        "eslint-config-prettier": "^9.0.0",
        "eslint-plugin-prettier": "^5.0.1",
        "prettier": "^3.0.3",
        "typescript": "^5.2.2"
      }
    }
    

    In .eslintrc.json:

    {
      "extends": [
        "plugin:prettier/recommended" // must be last element in "extends"
      ],
      "parser": "@typescript-eslint/parser",
      "plugins": [
        "@typescript-eslint"
      ],
      "settings": {
        "import/parsers": {
          "@typescript-eslint/parser": [
            ".ts"
          ]
        },
      }
    }
    

    Set your Prettier rules in .prettierrc.json, for example:

    {
      "printWidth": 100
    }
    

    Now eslint --fix will format the document in a single pass.

    For VSCode, install both the dbaeumer.vscode-eslint and the esbenp.prettier-vscode extensions. These each require you to have the corresponding npm package installed, whether locally in your app or globally on your device. You may also need to configure VSCode so that it can find the packages, depending on how they were installed.

    Then when you run Format Document With and select ESLint it will apply both your ESLint and Prettier rules with the equivalent of eslint --fix. For example, leaving a trailing space will trigger this INFO alert:

    Delete `·` eslint (prettier/prettier)
    

    Formatting the document with ESLint resolves the issue.