Agathon's ESLint configuration
There are three ESLint configurations available for your usage:
The default includes non specific frontend framework rules. This configuration can be used in vanilla JS, Node, or non front-end framework projects.
In your .eslintrc
:
1. Install dependencies
yarn add --dev @agathongroup/eslint-config eslint babel-eslint prettier eslint-config-prettier
2. In your .eslintrc
:
{
"extends": "@agathongroup"
}
NOTE: Make sure to specify your environment based on your project
Includes everything in the default config, plus environment specification and react-specific rules with
1. Install dependencies
yarn add --dev @agathongroup/eslint-config eslint babel-eslint prettier eslint-config-prettier eslint-plugin-react eslint-plugin-jsx-a11y
2. In your .eslintrc
:
{
"extends": "@agathongroup/eslint-config/react"
}
Includes everything in the default config, plus environment specification and react-native specific rules with
1. Install dependencies
yarn add --dev @agathongroup/eslint-config eslint babel-eslint prettier eslint-config-prettier eslint-plugin-react eslint-plugin-react-native
2. In your .eslintrc
:
{
"extends": "@agathongroup/eslint-config/react-native"
}
The default configuration does not specify a certain environment as to not make any assumptions about the project. The only default environment specified is es2020
. You can see the default settings here.
You can specify individual project environments in the .eslintrc
file:
{
"extends": "@agathongroup",
"env": {
"browser": true,
"node": true
}
}
View all available environments in the ESLint Docs
Once you've installed the config, the following are recommended settings for your editor to lint and fix the code for you.
-
Install the ESLint extension:
View → Extensions
then search and install ESLint -
You may need to reload the editor
-
In your VS Code user settings
Code → Preferences → Settings
click the icon with the arrow and paper in the top right corner to modify yoursettings.json
file. Add the following to your settings:// Format on save with Prettier rules "editor.formatOnSave": true, // Tell the ESLint plugin to run on save "editor.codeActionsOnSave": { "source.fixAll.eslint": true } // An array of language identifiers specify the files to be validated "eslint.validate": ["html", "javascript", "javascriptreact"]
- Install Package Control
- Install ESLint-Formatter
- And then allow auto fix on save:
Preferences → Package Settings → ESLint Formatter → Settings
then add"format_on_save": true
to the settings file
Our ESLint config extends eslint:recommended
which enable rules that relate to possible syntax or logic errors in JavaScript. Rules marked with check marks in the large list of ESLint rules are enforced with eslint:recommended
.
The rules listed below are enabled in addition to eslint:recommended
.
no-console
Using console.log
during development is fine, but you shouldn't use console.log
in production code.
In JavaScript that is designed to be executed in the browser, it's considered a best practice to avoid using methods on console. Such messages are considered to be for debugging purposes and therefore not suitable to ship to the client. In general, calls using console should be stripped before being pushed to production.
// bad
console.log('bad');
curly
Require following curly brace conventions
Always wrap the block of code in curly braces when using conditionals.
JavaScript allows the omission of curly braces when a block contains only one statement. However, it is considered by many to be best practice to never omit curly braces around blocks, even when they are optional, because it can lead to bugs and reduces code clarity.
// bad
if (foo) foo++;
while (bar) baz();
if (foo) {
baz();
} else qux();
// good
if (foo) {
foo++;
}
while (bar) {
baz();
}
if (foo) {
baz();
} else {
qux();
}
eqeqeq
Use strict equality or inequality operators.
It is considered good practice to use the type-safe equality operators
===
and!==
instead of their regular counterparts==
and!=.
The reason for this is that==
and!=
do type coercion which follows the rather obscure Abstract Equality Comparison Algorithm. For instance, the following statements are all considered true:
- [] == false
- [] == ![]
- 3 == 03
// bad
a == b;
foo == true;
bananas != 1;
value == undefined;
typeof foo == 'undefined';
'hello' != 'world';
0 == 0;
true == true;
foo == null;
// good
a === b;
foo === true;
bananas !== 1;
value === undefined;
typeof foo === 'undefined';
'hello' !== 'world';
0 === 0;
true === true;
foo === null;
no-eq-null
Use strict equality/inequality when checking null
values.
Comparing to
null
without a type-checking operator (==
or!=
), can have unintended results as the comparison will evaluate to true when comparing to not just anull
, but also anundefined
value.
// bad
if (foo == null) {
bar();
}
while (qux != null) {
baz();
}
// good
if (foo === null) {
bar();
}
while (qux !== null) {
baz();
}
no-use-before-define
Define the variable or function before using it.
In JavaScript, prior to ES6, variable and function declarations are hoisted to the top of a scope, so it's possible to use identifiers before their formal declarations in code. This can be confusing and some believe it is best to always declare variables and functions before using them. In ES6, block-level bindings (
let
andconst
) introduce a "temporal dead zone" where aReferenceError
will be thrown with any attempt to access the variable before its declaration.
// bad
alert(a);
const a = 10;
f();
function f() {}
function g() {
return b;
}
const b = 1;
// good
let a;
a = 10;
alert(a);
function f() {}
f(1);
const b = 1;
function g() {
return b;
}
prefer-const
Use const
instead of let
when a constiable is never reassigned.
If a variable is never reassigned, using the
const
declaration is better.const
declaration tells readers, "this variable is never reassigned," reducing cognitive load and improving maintainability.
// bad
// it's initialized and never reassigned.
let a = 3;
console.log(a);
let a;
a = 0;
console.log(a);
// `i` is redefined (not reassigned) on each loop step.
for (let i in [1, 2, 3]) {
console.log(i);
}
// `a` is redefined (not reassigned) on each loop step.
for (let a of [1, 2, 3]) {
console.log(a);
}
// good
// using const.
const a = 0;
// it's never initialized.
let a;
console.log(a);
// it's reassigned after initialized.
let a;
a = 0;
a = 1;
console.log(a);
// it's initialized in a different block from the declaration.
let a;
if (true) {
a = 0;
}
console.log(a);
// it's initialized at a place that we cannot write a variable declaration.
let a;
if (true) {
a = 0;
}
console.log(a);
// `i` gets a new binding each iteration
for (const i in [1, 2, 3]) {
console.log(i);
}
// `a` gets a new binding each iteration
for (const a of [1, 2, 3]) {
console.log(a);
}
prefer-template
Suggest using template literals instead of string concatenation
Use template literals instead of string concatenation.
// bad
const str = 'Hello,' + name + '!';
const str = 'Time: ' + 12 * 60 * 60 * 1000;
// good
const str = 'Hello World!';
const str = `Hello, ${name}!`;
const str = `Time: ${12 * 60 * 60 * 1000}`;
Our ESLint config extends plugin:react/recommended
which enable rules that relate to common React and JSX errors. You can view all available react rules in the eslint-plugin-react repo. The following rule is enforced in addition to the recommended configuration.
react/no-unescaped-entities
This rule prevents characters that you may have meant as JSX escape characters from being accidentally injected as a text node in JSX statements.
// bad
<MyComponent
name="name"
type="string"
foo="bar"> {/* oops! */}
x="y">
Body Text
</MyComponent>
// good
<MyComponent>{'Text'}}</MyComponent>
react/react-in-jsx
DISABLE missing React variable when using JSX
This is rule is turned "off" because we use React
as a global variable.
react/prop-types
This is rule is turned "off" because prop types are not generally used in our projects.
You can view all available react native rules in the eslint-plugin-react-native repo. The following rules are enforced:
react-native/no-raw-text
Detect raw text outside of Text component
All strings in React Native should be wrapped with a Text component.
// bad
<View>some text</View>
const text = 'some text';
<View>{`${text}`}</View>
// good
<View><Text>some text</Text></View>
const text = 'some text';
<View><Text>{`${text}`}</Text></View>
react-native/no-single-element-style-arrays
No Single Element Style Arrays are allowed
These cause unnecessary re-renders as each time the array's identity changes.
// bad
<View style={[{height: 10}]} />
// good
<View style={{ height: 10 }} />
If you'd like to override any rules, you can add the rules to your .eslintrc
file.
{
"rules": {
"rule-name-here": "off"
}
}