Reputation: 2033
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.
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
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