Prettier and / or Eslint? - javascript

Most of the projects I work on I just fire up and, at most, disable a linting rule that bugs me. That is to say I don't know much about linting and linters except that eslint is everywhere.
A Vue project I'm working on now (that I did not initially build) has four linting modules and I now want to understand if all of them are necessary, if they are conflicting with each other or complimenting each other. I'm getting so many yellow warnings that don't get fixed with the --fix flag that I want to uninstall everything and install one linter to rule them all.
The project package.json has these:
{
"eslint": "^7.3.1",
"eslint-plugin-prettier": "^3.1.1",
"eslint-plugin-vue": "^6.2.2",
"lint-staged": "^10.2.7"
}
Thoughts?
My eslintrc.js
module.exports = {
root: true,
env: {
node: true,
},
extends: ["plugin:vue/essential", "#vue/prettier"],
rules: {
"no-console": process.env.NODE_ENV === "production" ? "off" : "off",
"no-debugger": process.env.NODE_ENV === "production" ? "error" : "off",
"max-len": [0, 0, 0],
singleQuote: 0,
trailingComma: 0,
"no-unused-vars": 0,
"vue/no-unused-components": 0,
},
parserOptions: {
parser: "babel-eslint",
},
overrides: [
{
files: ["**/__tests__/*.{j,t}s?(x)", "**/tests/unit/**/*.spec.{j,t}s?(x)"],
env: {
jest: true,
},
},
],
};

Not sure if I can give a direct answer, but it's super common to combine eslint along with prettier via eslint-plugin-prettier. We use prettier purely for code formatting rules like:
single vs double quotes
max line length
semicolons or not
eslint is more commonly used to find errors in your code that otherwise wouldn't have been caught until runtime. Not every rule in eslint can be fixed via eslint --fix, but many can be. What does your .eslintrc look like?

Related

Proper way of Installing ESlint with Prettier in a React Project

I've recently started using eslint and prettier in my projects, but I'm always not sure if I'm installing them correctly. I've read several articles online and it seems each one does it differently. I'm trying to use the Airbnb configuration. I currently do not get any errors in a basic React app, but I just want to be sure it's the correct configuration. What would be the best way to run eslint with prettier?
Here are my files:
.eslintrc.js
module.exports = {
env: {
browser: true,
es2021: true,
jest: true,
},
extends: [
'plugin:react/recommended',
'airbnb',
'plugin:prettier/recommended',
],
parserOptions: {
ecmaFeatures: {
jsx: true,
},
ecmaVersion: 12,
sourceType: 'module',
},
plugins: ['react', 'prettier'],
rules: {
'prettier/prettier': 'error',
'react/jsx-filename-extension': [1, { extensions: ['.js', '.jsx'] }],
},
};
.prettierrc.js
module.exports = {
trailingComma: "es5",
tabWidth: 2,
semi: true,
singleQuote: true,
};
in my package.json
"devDependencies": {
"eslint": "^7.25.0",
"eslint-config-airbnb": "^18.2.1",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-import": "^2.22.1",
"eslint-plugin-jsx-a11y": "^6.4.1",
"eslint-plugin-prettier": "^3.4.0",
"eslint-plugin-react": "^7.23.2",
"eslint-plugin-react-hooks": "^4.2.0",
"prettier": "^2.2.1"
}
There are a number of ways to set up prettier to work with eslint and it can be confusing.
To run prettier as an eslint rule, you would want to add a rule that allows eslint to run prettier. You do that with the eslint-plugin-prettier plugin.
"plugins": ["prettier"], // Defines a rule that allows eslint to run prettier.
"rules": {
"prettier/prettier": "error" // Turns on that rule.
}
You would also want to turn off eslint rules that may conflct with prettier. You do this with the eslint-config-prettier extension. Note this should come after any other extensions in order to override the rules as appropriate.
"extends": [
/*other extensions*/,
"prettier" // Turns off conflicting eslint rules.
]
As per their documentation, it sounds the recommended extension that comes with the prettier plugin actually takes care of everything for you, so you should be able to get away with just:
extends: [
// .. other extensions
'plugin:prettier/recommended',
]
https://github.com/prettier/eslint-plugin-prettier
Also, in case third-party plugins come with their own rules that may conflict with prettier, you used to have to add "prettier/that-plugin" - "prettier/react" in your case for instance - to the list of plugins in order to tell eslint to defer to prettier for these non-standard rules as relevant as well. But this no longer seems required.
I used this guide for setting up eslint with airbnb's style guide on a Yarn monorepo/workspace.

Svelte and ESLint

A few days ago I decide to migrate frontend application to Svelte from Vanilla JS (specific reasons).
And at first I decided to configure eslint config. I spent about 3 hours to find an answer of how to integrate svelte into eslint and I didn't find nothing besides this plugin
Here is my eslint config
module.exports = {
extends: ['eslint:recommended', 'prettier'],
parserOptions: {
ecmaVersion: 2019,
sourceType: 'module'
},
env: {
es6: true,
browser: true
},
plugins: [ 'svelte3' ],
overrides: [
{
files: '*.svelte',
processor: 'svelte3/svelte3'
}
],
globals: {
"module": true,
"process": true,
},
rules: {
// ...
},
settings: {
// ...
}
};
Here is dev. dependencies of package.json:
Where is contains my svelte components:
I have non formatted code:
And what tell me eslint:
After eslint . and eslint . --fix commands the code of svelte component still non formatted
I'm sure that I'm doing something wrong, hope on your help.
To use eslint with svelte 3, all you have to do is :
npm install \
eslint \
eslint-plugin-import \
eslint-plugin-node \
eslint-plugin-promise \
eslint-plugin-standard \
eslint-plugin-svelte3 \
--save-dev
Add this script in package.json :
"scripts": {
"lint": "eslint . --ext .js,.svelte --fix"
},
And add a file .eslintrc.js next to the package.json file :
module.exports = {
parserOptions: {
ecmaVersion: 2019,
sourceType: 'module'
},
env: {
es6: true,
browser: true,
node: true
},
extends: [
'eslint:recommended'
],
plugins: [
'svelte3'
],
ignorePatterns: [
'public/build/'
],
overrides: [
{
files: ['**/*.svelte'],
processor: 'svelte3/svelte3'
}
],
rules: {
// semi: ['error', 'never'] // uncomment if you want to remove ;
},
settings: {
// ...
}
}
Then you can run npm run lint to fix your files.
ESLint (and linters in general) are good for finding and potentially fixing things that violate certain rules, but ESLint isn't primarily a formatting tool.
To format Svelte files automatically, you'll have better luck with Prettier and the Svelte plugin for Prettier.
If you're using Visual Studio Code, you can install the Svelte for VS Code plugin which will be able to format your files automatically when you save them (assuming you have formatOnSave turned on).
I assume you are using VSCode by looking at your screenshots. At the documentation's page of the plugin you mention, there's an explanation of how to configure it in your code editor. ( https://github.com/sveltejs/eslint-plugin-svelte3/blob/master/INTEGRATIONS.md )
You'll need the ESLint extension installed.
Unless you're using .html for your Svelte components, you'll need to configure files.associations to associate the appropriate file extension with the html language. For example, to associate .svelte, put this in your settings.json:
{
"files.associations": {
"*.svelte": "html"
}
}
Then, you'll need to tell the ESLint extension to also lint files with language html and to enable autofixing where possible. If you haven't adjusted the eslint.validate setting, it defaults to [ "javascript", "javascriptreact" ], so put this in your settings.json:
{
"eslint.validate": [
"javascript",
"javascriptreact",
{
"language": "html",
"autoFix": true
}
]
}
If you are using an extension that provides Svelte syntax highlighting, don't associate *.svelte files with the html language, and instead enable the ESLint extension on "language": "svelte".
Reload VS Code and give it a go!

Flow type checking performance in VSCode

I've built a new project using create-react-app and wanted to start it using a static type checking, there are two choices now in market:
TypeScript
Flow
I kind want to go with Flow just because it's also built by Facebook and should(?) have better support for a React project.
So what I'm struggling it is type-checking performance in VSCode. Once I created my project, I ran the following commands:
yarn add -D eslint-plugin-prettier husky prettier pretty-quick babel-eslint eslint-plugin-flowtype flow-bin eslint
Added Airbnb React style: eslint --init
Ran flow init
Installed Flow Language Support
Disabled JavaScript and TypeScript language support as recommended
Added following config to my Workspace settings:
-
{
"flow.useNPMPackagedFlow": true,
"flow.pathToFlow": "${workspaceRoot}/node_modules/.bin/flow"
}
My .eslintrc is as follows:
{
"extends": ["airbnb", "plugin:flowtype/recommended"],
"plugins": ["prettier", "flowtype"],
"parser": "babel-eslint",
"env": {
"browser": true,
"es6": true,
"jest": true,
"node": true
},
"rules": {
"react/jsx-filename-extension": [1, { "extensions": [".js", ".jsx"] }],
"prettier/prettier": [
"error",
{
"printWidth": 80,
"singleQuote": true,
"useTabs": false,
"tabWidth": 2,
"semi": true,
"bracketSpacing": true
}
]
},
"settings": {
"import/resolver": {
"node": {
"paths": ["src"]
}
}
}
}
However Flow seems to be quite slow on my machine, I have added a simple function to my App.js:
const sum = (a: number, b: number) => a + b;
sum(1, '12323');
And it takes up to 10 seconds to validate my code which is quite a bummer. Is there a way to speed this up?
Maybe it's worth to start with TypeScript and don't bother with Flow?
There are some open issues regarding possible memory leaks and performance related problems with flow, some links below:
https://github.com/facebook/flow/issues/2152
https://github.com/flowtype/flow-bin/issues/70
Both tools are great and have their pros and cons, I would personally recommend to give a try to TypeScript too and perform a comparison yourself.
In my own experience on a large code base I have found TypeScript:
more performant
more types for external libraries
larger community

Why eslint does not check JS?

Eslint loads, but does not fix 'problem js'...
File eslint.config.json
{
"ecmaFeatures": {
"jsx": true
},
"env": {
"browser": true,
"node": true,
"jquery": true
},
"rules": {
"quotes": 0,
"no-trailing-space": 0,
"eol-last": 0,
"no-unused-vars":0,
"no-underscore-dangle":0,
"no-alert": 0,
"no-lone-blocks": 0
},
"globals": {
jQuery: true,
$ : true
}
}
In JS file i can use global variables...
Lint does not check JS.
If you are using version newer then 1.0.0 none of the rules are enabled by default. Since your config above only shows disabling rules, that means eslint runs with no enabled rules, and as such, doesn't find any errors. What you might want to do is add the following line to your config:
{
"extends": "eslint:recommended"
}
which will enabled all of the rules marked as recommended on this page.
Or you can also extend from existing configs that you can find on NPM by searching for eslint-config-
I had same issue. Adding below line in the .eslintrc helped:
"extends": ["eslint:recommended", "plugin:react/recommended"]
Note: extends option might be already there but without the plugin option.

How to use ESLint with Jest

I'm attempting to use the ESLint linter with the Jest testing framework.
Jest tests run with some globals like jest, which I'll need to tell the linter about; but the tricky thing is the directory structure, with Jest the tests are embedded with the source code in __tests__ folders, so the directory structure looks something like:
src
foo
foo.js
__tests__
fooTest.js
bar
bar.js
__tests__
barTest.js
Normally, I'd have all my tests under a single dir, and I could just add an .eslintrc file there to add the globals... but I certainly don't want to add a .eslintrc file to every single __test__ dir.
For now, I've just added the test globals to the global .eslintrc file, but since that means I could now reference jest in non-testing code, that doesn't seem like the "right" solution.
Is there a way to get eslint to apply rules based on some pattern based on the directory name, or something like that?
The docs show you are now able to add:
"env": {
"jest/globals": true
}
To your .eslintrc which will add all the jest related things to your environment, eliminating the linter errors/warnings.
You may need to include plugins: ["jest"] to your esconfig, and add the eslint-plugin-jest plugin if it still isn't working.
ESLint supports this as of version >= 4:
/*
.eslintrc.js
*/
const ERROR = 2;
const WARN = 1;
module.exports = {
extends: "eslint:recommended",
env: {
es6: true
},
overrides: [
{
files: [
"**/*.test.js"
],
env: {
jest: true // now **/*.test.js files' env has both es6 *and* jest
},
// Can't extend in overrides: https://github.com/eslint/eslint/issues/8813
// "extends": ["plugin:jest/recommended"]
plugins: ["jest"],
rules: {
"jest/no-disabled-tests": "warn",
"jest/no-focused-tests": "error",
"jest/no-identical-title": "error",
"jest/prefer-to-have-length": "warn",
"jest/valid-expect": "error"
}
}
],
};
Here is a workaround (from another answer on here, vote it up!) for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
You can also set the test env in your test file as follows:
/* eslint-env jest */
describe(() => {
/* ... */
})
To complete Zachary's answer, here is a workaround for the "extend in overrides" limitation of eslint config :
overrides: [
Object.assign(
{
files: [ '**/*.test.js' ],
env: { jest: true },
plugins: [ 'jest' ],
},
require('eslint-plugin-jest').configs.recommended
)
]
From https://github.com/eslint/eslint/issues/8813#issuecomment-320448724
As of 2021, I think the correct way or at least the one that works is to install #types/jest and eslint-plugin-jest:
npm i -D eslint-plugin-jest #types/jest
And adding the Jest plugin into .eslintrc.js with the overrides instruction mentioned by #Loren:
module.exports = {
...
plugins: ["jest"],
...
overrides: [
{
files: ["**/*.test.js"],
env: { "jest/globals": true },
plugins: ["jest"],
extends: ["plugin:jest/recommended"],
},
],
...
};
This way you get linting errors in your source files as well as in test files, but in test files you don't get linting errors for test and other Jest's functions, but you will get them in your source files as they will appear as undefined there.
I solved the problem REF
Run
# For Yarn
yarn add eslint-plugin-jest -D
# For NPM
npm i eslint-plugin-jest -D
And then add in your .eslintrc file
{
"extends": ["airbnb","plugin:jest/recommended"],
}
some of the answers assume you have eslint-plugin-jest installed, however without needing to do that, you can simply do this in your .eslintrc file, add:
"globals": {
"jest": true,
}
First install eslint-plugin-jest
Running:
yarn add eslint-plugin-jest or npm install eslint-plugin-jest
Then edit .eslintrc.json
{
"env":{
"jest": true
}
}
As of ESLint V 6 (released in late 2019), you can use extends in the glob based config as follows:
"overrides": [
{
"files": ["*.test.js"],
"env": {
"jest": true
},
"plugins": ["jest"],
"extends": ["plugin:jest/recommended"]
}
]
Add environment only for __tests__ folder
You could add a .eslintrc.yml file in your __tests__ folders, that extends you basic configuration:
extends: <relative_path to .eslintrc>
env:
jest: true
If you have only one __tests__folder, this solution is the best since it scope jest environment only where it is needed.
Dealing with many test folders
If you have more test folders (OPs case), I'd still suggest to add those files. And if you have tons of those folders can add them with a simple zsh script:
#!/usr/bin/env zsh
for folder in **/__tests__/ ;do
count=$(($(tr -cd '/' <<< $folder | wc -c)))
echo $folder : $count
cat <<EOF > $folder.eslintrc.yml
extends: $(printf '../%.0s' {1..$count}).eslintrc
env:
jest: true
EOF
done
This script will look for __tests__ folders and add a .eslintrc.yml file with to configuration shown above. This script has to be launched within the folder containing your parent .eslintrc.
Pattern based configs are scheduled for 2.0.0 release of ESLint. For now, however, you will have to create two separate tasks (as mentioned in the comments). One for tests and one for the rest of the code and run both of them, while providing different .eslintrc files.
P.S. There's a jest environment coming in the next release of ESLint, it will register all of the necessary globals.
I got it running after spending some time trying out different options. Hope this helps anyone else getting stuck.
.eslintrc.json (in root project folder):
{
"env": {
"browser": true,
"es2021": true,
"jest/globals": true
},
"extends": [
"standard",
"plugin:jest/all"
],
"parser": "#babel/eslint-parser",
"parserOptions": {
"ecmaVersion": 12,
"sourceType": "module"
},
"rules": {
"jest/no-hooks": [
"error",
{
"allow": [
"afterEach",
"beforeEach"
]
}
]
},
"plugins": [
"jest"
]
}
Empty .babelrc (in root project folder):
{}
.package.json (in root project folder):
{
"scripts": {
"test": "jest",
"lint": "npx eslint --format=table .",
"lintfix": "npx eslint --fix ."
},
"devDependencies": {
"#babel/core": "^7.15.0",
"#babel/eslint-parser": "^7.15.0",
"aws-sdk-mock": "^5.2.1",
"eslint": "^7.32.0",
"eslint-config-standard": "^16.0.3",
"eslint-plugin-import": "^2.24.0",
"eslint-plugin-jest": "^24.4.0",
"eslint-plugin-node": "^11.1.0",
"eslint-plugin-promise": "^5.1.0",
"jest": "^27.0.6"
}
}
VS Code settings.xml (editor configuration: enables auto fix on save + babel parser):
"eslint.alwaysShowStatus": true,
"eslint.format.enable": true,
"eslint.lintTask.enable": true,
"eslint.options": {
"parser": "#babel/eslint-parser"
},
"editor.codeActionsOnSave": {
"source.fixAll.eslint": true
},
"eslint.validate": [
"javascript"
]
In your .eslintignore file add the following value:
**/__tests__/
This should ignore all instances of the __tests__ directory and their children.

Categories