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.
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.eslintItegration
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
.
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",
}
}
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.
{
"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"]
}
}
}
}
Thanks!