I am setting up my React Redux project to use ESLint with Airbnb configs and Prettier. I've been modifying certain things to how I want them, but now I've run into a problem with indentations on switch & case statements that I can't seem to fix.
I am editing my project in VSCode. I click on the errors and fix with ESLint, reducing the indent by 4 spaces, but then more errors show up from Prettier, asking to re-indent everything by another 4 spaces.
I want to change the current indentation width. I want it set to 4 spaces when I use tabs. It's not a must, but if it is possible, I would prefer that the case
keywords in switch
blocks to be indented.
prettier
eslint
eslint-config-airbnb
eslint-plugin-import
eslint-plugin-jsx-a11y
eslint-plugin-react
eslint-import-resolver-webpack
eslint-config-prettier
eslint-plugin-prettier
.eslintrc.json
{
"extends": ["airbnb", "prettier", "prettier/react"],
"plugins": ["react", "prettier"],
"rules": {
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", "jsx"]
}
],
"prettier/prettier": "error",
"indent": ["error", 4, { "SwitchCase": 1 }],
"react/jsx-indent": ["error", 4],
"react/jsx-indent-props": ["error", 4],
"class-methods-use-this": 0,
"no-else-return": 0,
"no-plusplus": [2, { "allowForLoopAfterthoughts": true }],
"no-param-reassign": 0
},
.prettierrc
config-file: "prettier": {
"tabWidth": 4
}
switch (action.type) {
case GUESS_LETTER:
return Object.assign(
{},
state,
state.guessWord.includes(action.guessLetter)
? addCorrectGuess(
state.rightLetters.slice(), // <-- error here!
action.guessLetter, // <-- error here!
state.guessWord // <-- error here!
) // <-- error here!
: addWrongGuess(
state.wrongLetters.slice(), // <-- error here!
action.guessLetter // <-- error here!
) // <-- error here!
);
My first attempt to get this working was to add { "SwitchCase": 1 }
to the ESLint config file. That reduced the number of errors (which was almost the entire block), but there are still errors. I can't figure out where the conflict is exactly.
[UPDATE] To my eternal shame, I believe I discovered the problem. I simply removed the configuration for intends from the ESLint configuration. I removed this:
"indent": ["error", 4, { "SwitchCase": 1 }],
"react/jsx-indent": ["error", 4],
"react/jsx-indent-props": ["error", 4],
And now it seems to be behaving normally. I assume this is because it screws up Prettier when trying to handle indents. I only needed the configuration for Prettier.
Lesson: test more by removing configurations which may be causing conflict before posting.
To make sure this is marked as solved:
I simply removed the configuration for indents from the ESLint configuration. I removed this:
"indent": ["error", 4, { "SwitchCase": 1 }],
"react/jsx-indent": ["error", 4],
"react/jsx-indent-props": ["error", 4],
And now it seems to be behaving normally. I assume this is because it screws up Prettier when trying to handle indents. I only needed the configuration for Prettier.
Lesson: test more by removing configurations which may be causing conflict before posting.
I had the same problem as mentioned in the question above, however I figured out how to solve it in a way that not only could the "indent" setting be kept, but so it can be adjusted, allowing for tabWidth to be set as you like.
First I want to note, so we're all on the same page, what the set-up I am using for linting/formatting exactly is:
Additionally I also equip the following, which I download using NPM:
For those familiar with linting while using V.S. Code, you guys know that what I am using is actually the short list. There is all kinds of other configs, plugins & extensions that can be obtained. The important thing to note here, is that I am using a tried & true setup, that allows Prettier, and ESLint to work harmoniously together.
With that said, even having a good configuration, and all the correct extensions I still had a problem with the above rule, the same as the developer who posted the question. I knew the problem had to do with ESLint's rules, and how they were being configured in my .eslintrc.json file. After much research, and near mastering ESLint, I found that I was correct. There are a few ESLint rules, (3 ESLint rules, and 1 Prettier Setting), that you need to have configured properly, however; at the same time you need to make sure your .prettierrc file settings are in-sync with your .eslintrc.json file rules. Once you understand it all, it is actually not as complicated as it sounds.
First off you need to decide what you want your styles tab-width to be. (Most Style-Guides set there tab-width at (2x Space-Width), but many dev's will change there settings to a (4x Space-Width). Any thing other than 2x and 4x is considered taboo.)
Go ahead and open your .prettierrc file (or what ever mimetype of prettier configuration file you use), then set 'tabWidth' to your liking, just make sure that you stick with a consistant tabWidth from here on out, becuase ESLint needs to be in sync with prettier.
Your '.prettierrc' file should look similar to this:
{
"printWidth": 90,
"tabWidth": 4,
"useTabs": false,
"trailingComma": "all",
"singleQuote": true,
"semi": true,
"bracketSpacing": false,
}
- open up your .eslintrc.json file (or whatever version of ESLint configuration file mime-type that you use), and set the "max-len" rule in the rules property of your eslintrc.json. The rule is not in the file by default so you will have to write it in. To see how, review the Example I Created Below.
- Be sure that the "tabWidth" property within ESLint's "max-len" rule, holds exactly the same value, as the "tabWidth" setting within your .prettierrc file.
- There are some other rule options here that are important to set properly as well. The first, 'code', sets the max amount of chars each line can hold, aka(max-line-length). When "code" is set ESlint will not allow more characters than what "code" has been set to. The catch is that you absolutely must Make sure that the "printWidth" setting in your .prettierrc file, which you probably will have to write in, is set to the same value as the "code" property's value in your .eslintrc.json max-len rule.
- "ignoreUrls" can be set either way and make sure the rule does throw an error by leaving the word "error" as it is.
Here is an example of my max-len rule in ESLint
"rules": {
"max-len": [
"error",
{
"code": 90,
"tabWidth": 4,
"ignoreUrls": true
}
],
}
See the .prettierrc example above, to view how to set "printWidth"
- The "no-tabs" rule, is a 'must set', w/o it your linting & formatting > can unsynchronize.
- You can set "allowIndentationTabs" as you like, Allowing for, or disallowing indentation tabs won't make a difference.
What the no-tabs rule should look like:
"rules": {
"no-tabs": ["error", {"allowIndentationTabs": true}],
"max-len": [
"error",
{
"code": 90,
"tabWidth": 4,
"ignoreUrls": true
}
],
}
Seriously this one is important. Its the one that gets thrown out in an attempt to fix the switch indentation problem, which doesn't give you control over other settings, like setting your own tab-width. The "indent" rule.
"indent": ["error", 4, {"SwitchCase": 1}],
"indent": 4; // throws error
// or
"indent": ["warn", 4] // Throws warning, which is somtimes less annoying than an error
So it is important to note that the value 4 that you see in the "indent" rule, is how many spaces an indent will be. This led me to believe that the 1 after "SwitchCase" meant how many spaces that the switch keyword case will be indented.
Example:
switch(x){
case 1:
break;
}
That is not how it works though. The number that rule "SwitchCase" is set to, tells the editor how many times to indent the keyword 'case'. So if the "indent" rule is set to 4, and the "SwitchCase" rule is set to 4, then ESLint will expect an indentation of 4x4=16. At the end of the day ESLint will actually expect more than 16, because ESLint is going to take on all the indentation from different levels of blocks that the switch statement is found in, this ends up leading to ESLint expecting 24-36 spaces of indentation, that's crazy.
"SwitchCase" needs to be set to 1.
"rules": {
"indent": ["error", 4, {"SwitchCase": 1}],
"no-tabs": ["error", {"allowIndentationTabs": true}],
"max-len": [
"error",
{
"code": 90,
"tabWidth": 4,
"ignoreUrls": true
}
],
}
If you set all the rules right that should work for you
If it is still not working, try starting with a clean slate, delete your .eslintrc.json file, and create a new eslintrc.json file, and build it anew. You shouldn't have to start over with a new .prettierrc file.
To Wrap Up
Prettier wants to indent everything uninformed like. So if tabWidth is set to 4, and tabWidth & indent is set to 4 in ESlint then every block gets indented 4 spaces be prettier, no more and no less.
The whole problem initially is that, the style guides often ask that the keyword case not be indented, so when ESLint is setup, that is what it is configured to do by the NPM config you install upon initializing ESLint. However that does not work with prettier.
This answer wound up much longer than I thought it would. Getting Prettier, ESLint & VS Code to work harmoniously together is a very involved task, especially for first timers. I use Babel on top of this AST stack (I made that term up lol, what else would you call it?). If you want to be able to lint documents that contain TC39 ECMAScript Stage-3 Proposals, this includes features such as Private-Members, Static Methods, ect..., then you will need to use configure ESLint to use Babel's parser.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With