This is a giant pain in the ass to get working correctly and consistently. Even when it does work, often trying to replicate it in another repository or workspace the setting's don't always seem to work.
I can at times entirely remove my `.eslintrc`and vscode will still go on its merry way, linting from some mysterious ghost rules. On other occasions things will be great and then, after restarting vscode, I'll be told my imports are invalid (they are not).
As a matter of fact, as I sat down to write this I couldn't get it to linting/format according to my rules. Eventually I reinstalled my node packages with `npm install` and tried to commit a poorly formatted file (which thankfully failed). That seemed to finally kick something (not sure what) in the pants and linting began to function correctly. But literally, I've spent days getting this sorted out.
Anyway, here's my current setup.
### VSCODE SETTINGS
In either `~/.config/Code/User/settings.json` or `myworkspace.code-workspace`:
```
{
"folders": [{ "path": "myProject" }],
"settings": {
"editor.formatOnSave": true,
"eslint.autoFixOnSave": true,
"eslint.alwaysShowStatus": true,
"eslint.options": {
"configFile": "/home/path/to/.eslintrc"
},
"javascript.validate.enable": true,
"prettier.eslintIntegration": true,
"prettier.printWidth": 100,
"prettier.singleQuote": true,
"prettier.trailingComma": "all",
"typescript.format.enable": false,
"typescript.validate.enable": false,
"typescript.suggest.autoImports": false
}
}
```
I have both ESLint and Prettier extensions installed and enabled.
`prettier.eslintIntegration` is supposed to rely on eslint for formatting rules and the other settings are fallbacks. They _shouldn't_ be necessary, but you know, this doesn't always seem so stable.
`editor.formatOnSave` is optionally set to true. This uses Prettier's settings.
`eslint.options` seems to be the most reliable way of dictating which linting config file should be used. Just in case though, I make sure that no global eslint thing exists: `npm uninstall eslint -g`. I've had that before and it was messing things up.
Note: Make sure that your npm directory is not nested in the workspace tree (eg. SomeDir > myProject). This will cause problems with path resolution and a failure to find config files such as `.prettierignore`.
### Project
There is no global eslint setup. I have all my eslint related libraries included in my `package.json`. I also have `husky` and `lint-staged` set up to run prior to committing. This is helpful when working with others on a team who's linting may not be configured correctly (or when my own is failing). :/
```
{
"husky": {
"hooks": {
"pre-commit": "lint-staged"
}
},
"lint-staged": {
"**/*.js": [
"prettier --check",
"./node_modules/.bin/eslint",
"git add"
]
},
"devDependencies"
"babel-eslint": "^10.0.1",
"eslint": "^5.3.0",
"eslint-config-airbnb": "^17.1.0",
"eslint-config-prettier": "^4.1.0",
"eslint-import-resolver-alias": "^1.1.2",
"eslint-plugin-import": "^2.16.0",
"eslint-plugin-jsx-a11y": "^6.2.1",
"eslint-plugin-prettier": "^3.0.1",
"eslint-plugin-react": "^7.12.4",
"eslint-plugin-react-native": "^3.6.0",
"husky": "^2.7.0",
"lint-staged": "^8.2.1",
"prettier": "^1.16.4",
"prettier-eslint": "^8.8.2",
}
}
```
### .prettierrc / .prettierignore
Note: The `.prettierrc` file in the route directory is used when husky is run. If you don't want to use husky, there is no need for `.prettierrc`.
```
//.prettierrc
{
"printWidth": 100,
"singleQuote": true,
"trailingComma": "all",
"bracketSpacing": true,
"semi": true,
"tabWidth": 2
}
```
These are the same as what's configured in your vscode settings (the vscode default for `prettier.brackSpacing` is true which is why it isn't included in my workplace settings.
```
//.prettierignore
*.whatever.js
```
If you are having trouble getting this to work, it might be because `eslint.workingDirectories` is not configured. For me, it's because (as mentioned above) I had a nest directory in my vscode workspace which seemed to throw things off.
### .eslintrc
```
{
"root": true,
"parser": "babel-eslint",
"env": {
"es6": true,
"node": true,
"jest": true
},
"extends": ["airbnb", "prettier", "prettier/react"],
"plugins": ["react", "jsx-a11y", "import", "prettier"],
"rules": {
"padding-line-between-statements": [
"error",
{ "blankLine": "always", "prev": "*", "next": "return" },
{ "blankLine": "always", "prev": "*", "next": "export" },
{ "blankLine": "any", "prev": "export", "next": "export" },
{ "blankLine": "always", "prev": ["const", "let", "var"], "next": "*" },
{ "blankLine": "any", "prev": ["const", "let", "var"], "next": ["const", "let", "var"] }
],
"object-curly-spacing": ["error", "always"],
"max-len": ["error", 100, 2],
"comma-dangle": [
"error",
{
"arrays": "always-multiline",
"objects": "always-multiline"
}
],
"react/jsx-filename-extension": [
1,
{
"extensions": [".js", ".jsx"]
}
]
},
"settings": {
"import/resolver": {
"alias": {
"map": [["app", "./app"], ["myProject", "./"]],
"extensions": [".js", ".json", ".jsx"]
}
}
}
}
```