cdpautsch
cdpautsch

Reputation: 2033

ESLint and Prettier Conflict, Unable to Disable Prettier for code block

Our project is using Prettier and ESLint. Normally they work fine together, but we're running into an issue where the two are in conflict. I don't know why, I can't figure out how to fix it, and I can't disable prettier for the line because I get errors.

Relevant parts of our settings

// .prettierrc
  "printWidth": 80,
  "tabWidth": 2,
  "useTabs": false,
  "semi": true,
  "singleQuote": true,
  "trailingComma": "es5",
  "arrowParens": "always"

// eslintrc.js
  extends: ['airbnb', 'eslint-config-prettier', 'prettier/react'],
  plugins: [
    'eslint-plugin-prettier',
    'redux-saga',
    'react',
    'react-hooks',
    'jsx-a11y',
  ],
  rules: {
    'prettier/prettier': ['error'],
    indent: [
      2,
      2,
      {
        SwitchCase: 1,
      },
    ],
    'max-len': 0,

And here is the code, with comments added to indicate the issues:

    const options =
      children === undefined
        ? items.map((item) => (
          // Prettier complains about the next four lines
          <option key={uuidv1()} value={item}>
            {item}
          </option>
        ))
        : children;

Prettier wants those lines intended another two spaces.

Screenshot of errors

ESLint likes them where they are. I'm inclined to agree with ESLint. If I auto-format for Prettier, ESLint complains and wants it changed back. I am using VSCode. We haven't had such a conflict anywhere else in our code base.

I tried just disabling prettier for those lines, but the auto-disable option with eslint adds // eslint-disable-next-line prettier/prettier, which causes the app to error out with Definition for rule 'prettier/prettier' was not found. Trying to add // prettier-ignore is impossible because of the JSX.

I don't understand why Prettier wants what ESLint says it wants. The only way we've been able to fix it is by removing 'prettier/prettier': ['error'], from our ESLint config entirely, which doesn't seem appropriate.

Suggestions?

Update 10/10/19 - Thanks to a suggestion by user chazsolo, I modified how the function was formatted to get this, which doesn't have any linting issues:

const dropDownOptions =
  children ||
  items.map((item) => (
    <option key={uuidv1()} value={item.value || item}>
      {item.text || item}
    </option>
  ));

This is a viable workaround for this problem, but I'm leaving this question unanswered, as I still feel like my code is entirely valid and shouldn't get this conflict.

The workaround also only works if I'm checking a value like children for being falsey. We have another condition where it is a match, and I can't short-circuit it in the same way. All of these problems involve the use of .map().

// Can't short-circuit here
var === SOME_ENUM
  ? filteredItems.map((item) => (
      // some JSX
    ))
  : filteredItems.map((item) => (
      // some other JSX
    ));

I can move the condition inside the map function, but that leads to checking the condition every loop.

This problem has cropped up a lot, and I'll probably be creating an issue in Prettier for it at this rate, because it's rather annoying to troubleshoot.

Upvotes: 10

Views: 17587

Answers (1)

bravohex
bravohex

Reputation: 1044

My basic setup is working well for vue/ts in .eslintrc.json. You should add prettier in plugins

{
  "parser": "vue-eslint-parser",
  "parserOptions": { 
    "parser": "@typescript-eslint/parser" 
  },
  "plugins": ["@typescript-eslint", "prettier"],
  "rules": {
    "semi": ["error", "never"],
    "quotes": ["error", "single"],
    "prettier/prettier": "error"
  }
}

Upvotes: 4

Related Questions