- Example eslint config
- Linter Rules
- Comma dangle
- No cond assign
- No console
- No debugger
- No dupe args
- No dupe keys
- No empty
- No extra boolean cast
- No unreachable
- Use isNan
- Valid typeof
- Dot location
- No empty function
- No implicit coercion
- No lone blocks
- No loop function
- No multi spaces
- No return assing
- Radix
- Yoda
- No unused vars
- Global require
- Stylistic Rules
- Array bracket spacing
- Block spacing
- Brace style
- Comma spacing
- Comma style
- Computed property spacing
- EOL last
- ID length
- Indent
- JSX quotes
- Key spacing
- Keyword spacing
- New cap
- New parens
- Newline after var
- No array constructor
- No continue
- No lonely if
- Multiple empty line
- No negated conditions
- No spaced func
- No trailing spaces
- No unneeded ternary
- No whitespace before property
- Object curly spacing
- Operator assignment
- Operator linebreak
- Padded blocks
- Quoted props
- Semi
- Space before function paren
- Space in parens
- Space comment
- Arrow body style
- Arrow parens
- Arrow spacing
- No dupe class members
- No duplicate imports
- No this before super
- No var
- Object shorthand
- Prefer rest params
- Prefer spread
- Prefer template
- On Discussion
{
"comma-dangle": ["error", "always-multiline"],
"no-cond-assing": ["error", "always"],
"no-console": ["error", { "allow": ["warn", "error"] }],
"no-debugger": "error",
"no-dupe-args": "error",
"no-dupe-keys": "error",
"no-empty": ["error", { "allowEmptyCatch": true }],
"no-extra-boolean-cast": "error",
"no-unreachable": "error",
"use-isnan": "error",
"valid-typeof": "error",
"dot-location": ["error", "property"],
"no-empty-function": ["error", { "allow": ["arrowFunctions"] }],
"no-implicit-coercion": "error",
"no-lone-blocks": "error",
"no-loop-func": "error",
"no-multi-spaces": "error",
"no-return-assign": "error",
"radix": "error",
"yoda": "error",
"no-unused-vars": "warning",
"global-require": "error",
"array-bracket-spacing": ["error", "never"],
"block-spacing": ["error", "never"],
"brace-style": ["error", "stroustrup", { "allowSingleLine": true }],
"comma-spacing": ["error", { "before": false, "after": true }],
"comma-style": ["error", "last"],
"computed-property-spacing": ["error", "never"],
"eol-last": "error",
"id-length": ["error", { "min": 2 }],
"indent": ["error", 2, { "SwitchCase": 1 }],
"jsx-quotes": ["error", "prefer-double"],
"key-spacing": ["error", { "beforeColon": false, "afterColon": true }],
"keyword-spacing": ["error", { "before": true, "after": true, "overrides": { "catch": { "after": true } } }],
"lines-around-comment": ["warning", { "afterLineComment": false, "beforeLineComment": true }],
"new-cap": ["error", { "newIsCap": true }],
"new-parens": "error",
"newline-after-var": ["error", "always"],
"no-array-constructor": "error",
"no-continue": "error",
"no-lonely-if": "error",
"no-multiple-empty-lines": ["error", { "max": 3 }],
"no-negated-condition": "error",
"no-spaced-func": "error",
"no-trailing-spaces": ["error", { "skipBlankLines": false }],
"no-unneeded-ternary": "warning",
"no-whitespace-before-property": "error",
"object-curly-spacing": ["error", "always"],
"operator-assignment": ["warning", "always"],
"operator-linebreak": ["error", "before"],
"padded-blocks": ["error", "never"],
"quoted-props": ["error", "as-needed"],
"semi": ["error", "always"],
"semi-spacing": ["error", { "before": false, "after": true }],
"space-before-function-paren": ["error", "never"],
"space-in-parens": ["error", "never"],
"spaced-comment": ["error", "always"],
"arrow-body-style": ["error", "as-needed"],
"arrow-parens": ["error", "as-needed"],
"arrow-spacing": ["error", { "before": true, "after": true }],
"no-dupe-class-members": "error",
"no-duplicate-imports": "error",
"no-this-before-super": "error",
"no-var": "error",
"object-shorthand": ["error", "always"],
"prefer-rest-params": "error",
"prefer-spread": "warning",
"prefer-template": "warning",
"template-curly-spacing": ["error", "never"]
}
Добавлять запятую после последнего элемента массива или объекта, только в многострочном определении. Упрощает дописывание элементов в конец, git diff получается однострочный, не затрагивая вышестоящую строку.
Установка значений переменным в условиях влечет за собой сложнообнаруживаемые ошибки. В случае включенной проверки, опечатки сводятся к нулю, код проще для понимания.
Не нужно оставлять в коде ваши отладочные принты в консоль. Если уж необходимо отладить код на dev (например), то добавляйте строчное исключение и пишите об этом к коммите.
// eslint-disable-next-line no-console
console.log("Some data")
console.log('Wow Bad'); // eslint-disable-line no-console
Здесь вроде всё очевидно.
Но при острой необходимости: также // eslint-disable-line no-debugger
и пояснения в коммите.
Желательно, добавлять debugger
отдельным коммитом, чтобы можно было сделать git revert
, а не выискивать по коду, есть человеческий фактор и забывчивость.
Дубликаты имен аргументов это fatal!
Также fatal! проверяйте свой код.
Запрет создания пустых блоков кода, вроде if (some >= 20) {}
.
Так как в таких блоках кода нет смысла. Блоки кода с комментариями не считаются пустыми.
А также catch (e) {}
не считается пустым блоком.
Запрещает дополнительное приведение в boolean в случае условий:
let foo0 = !!!bar;
let foo1 = !!bar ? baz : bat;
let foo2 = Boolean(!!bar);
let foo3 = new Boolean(!!bar);
if (!!foo) {}
if (Boolean(foo)) {}
while (!!foo) {}
do {} while (Boolean(foo))
for (; !!foo; ) {}
Запрещает написание кода, который никогда не выполнится. Например:
function fn() {
x = 1;
return x;
x = 3; // Этот код никогда не выполнится
}
Запрет сравнивания с NaN
. Например: if (foo === NaN) {}
Решает некоторые потенциальные ошибки возникающие при сравнении со специальным значением NaN
Принуждает использовать isNan()
для проверок.
Просто дополнительная проверка на опечатку.
Обязывает в многострочных обращениях к свойствам и методам объекта ставить точку в начале новой строки. Пример правильного расположения точки:
const data = Plant
.select('some')
.filter(a => a < 1)
.unwrap();
Такое расположение точки, явно указывает на вызов метода/свойства объекта выше строчками.
Запрещает описывать пустые функции.
Разрешены только пустые arrow-функции: { defaultHandler: () => {} }
Вносит запрет на неявное приведение типов, вроде:
const b = !!foo;
const b = ~foo.indexOf(".");
const n = +foo;
const n = 1 * foo;
const s = "" + foo;
foo += "";
Вместо этого, необходимо явно приводить к необходимому типу:
let b = Boolean(foo);
let b = foo.indexOf(".") !== -1;
let n = Number(foo);
let n = Number(foo);
let s = String(foo);
foo = String(foo);
Запрещает писать блоки кода без условий, циклов и других определений. Пример неправильного использования блоков кода:
// Wrong!
{
callSomeFunction();
function someDefinition() {}
}
Запрещает описание функций с замыканиями внутри циклов.
Запрет написания нескольких пробелов между инструкциями
Запрещает присваивать значение в теле оператора return
Обязывает при использовании parseInt()
указывать систему счисления вторым параметром.
Чтобы избежать неправильного парсинга строки в число.
Запрещает писать "обратные" условия, вроде: if (1 == foo) {}
или if (true === flag) {}
Неиспользованные переменные загрязняют код, ухудшают понимание. Данное правило вызывает предупреждение, когда в коде встречается неиспользованная переменная.
Все импорты должны быть на верхнем уровне. Правило запрещает заносить импорт в скобки условий или циклов.
Не должно быть пробелов внутри квадратных скобок массива.
let arr = [];
let arr = ['foo', 'bar', 'baz'];
let arr = [['foo'], 'bar', 'baz'];
let arr = [
'foo',
'bar',
'baz'
];
let [x, y] = z;
let [x,y] = z;
let [x, ...y] = z;
let [,,x,] = z;
Обязательны пробелы внутри однострочного блока кода.
function foo() { return true; }
if (foo) { bar = 0; }
Использовать стиль Страуструпа.
function foo() {
return true;
}
if (foo) {
bar();
}
if (foo) {
bar();
}
else {
baz();
}
try {
somethingRisky();
}
catch (e) {
handleError();
}
// без скобок однострочные
if (foo) bar();
else if (baz) boom();
// со скобками однострочные
function nop() { return; }
if (foo) { bar(); }
if (foo) { bar(); }
else { baz(); }
try { somethingRisky(); }
catch (e) { handleError(); }
Пробел ставится только после запятой
let foo = 1, bar = 2, baz = 3;
let arr = [1, 2];
let arr = [1,, 3]
let obj = {"foo": "bar", "baz": "qur"};
foo(a, b);
new Foo(a, b);
function foo (a, b) {}
a, b
Запятая ставится после элемента, а не перед ним.
var foo = 1, bar = 2;
var foo = 1,
bar = 2;
var foo = ["apples",
"oranges"];
function bar() {
return {
"a": 1,
"b:": 2,
};
}
Внутри скобок определениях вычисляемых свойств пробелы не нужны:
obj[foo];
let x = { [b]: a };
obj[foo[bar]] = x;
Каждый файл исходного кода должен заканчиваться переносом строки
Все идентификаторы должны быть не короче 2 символов
Отступы должны быть в 2 пробельных символа.
Определения case/default
должны быть на 1 уровень глубже switch
.
Тело case/default
должно быть глубже его определения.
Тело не может быть на одной строке с определением.
if (a > 20) {
switch (a) {
case 22:
some.func(a, true);
break;
case 24:
some.func(a + 1, false);
notif.ok(a + 1, 'ok');
break;
default:
notif.err(a, 'no one');
}
}
В JSX-тегах необходимо использовать двойные кавычки.
<Component title="Example title">
<div className="description-line" />
</Component>
В определении объекта, пробел должен стоять только после символа двоеточия.
let object = { user: "Name" };
let some = {
key: "Value",
foo: "Bar",
zoo: "Zoo",
}
Ключевые слова должны быть окружены пробелами.
if (foo) {
// ...
}
else if (bar) {
// ...
}
else {
// ...
}
class A {}
function* foo(a) {
return yield + a;
}
try {
throw new Error('Wow');
}
catch (err) {
console.error(err.message);
}
for (let b = 0; b <= 1000; b++) {
some.caller(b, b + 1, true);
}
while (a < 5) {
fnc(a, String(a));
}
do {
connection();
load();
}
while (retry());
Все классы и объекты создаваемые через new
должны начинаться с прописной буквы.
let obj = new DefaultObject();
let dmn = new DomainKnowledge();
let boo = new fooBar(); // ошибка
При вызове конструктора через new
скобки обязательны.
let obj = new ClassDefinition();
let def = new DefaultParams; // ошибка!
После определения переменных необходимо оставить пустую строку. Для увеличения читабельности.
let a = 1;
let b = 2;
let commoncc = new CommonCC();
commoncc.init(a, b);
commoncc.pub(b);
Нельзя создавать массив через конструктор Array
.
let a = Array(500); // 500 элементов
let b = new Array(5); // 5 элементов
Необходимо писать код не используя continue
Нельзя помещать дополнительный if
в тело else
.
Например так нельзя:
if (foo) {
// ...1
}
else {
if (bar) {
// ...2.
}
}
Код должен быть переписан:
if (foo) {
// ...1
}
else if (bar) {
// ...2
}
Максимум 3 пустые строки между методами и определениями.
В коде не должно быть if/else
в котором есть условие с отрицанием.
Такой код должен быть переписан:
if (!a) {
// 1 some
}
else {
// 2 code
}
В такой:
if (a) {
// 2 code
}
else {
// 1 code
}
При вызове функции после идентификатора не должно быть пробела:
someFunc();
// Неправильно!
fn ();
Строки не должны оканчиваться пробелами. Пустые строки также не могут содержать пробелы.
Рекомендуется включить отображение пробельных символов в Вашем редакторе или IDE
Не нужно описывать тернарную операцию лишний раз.
// Неправильно
let isYes = answer === 1 ? true : false;
let isNo = answer === 1 ? false : true;
let foo = bar ? bar : 1;
// Правильно
let isYes = answer === 1;
let isNo = answer !== 1;
let foo = bar || 1;
При обращении к свойству объекта запрещено ставить пробел перед и после точки.
// правильно
foo
.bar()
.baz()
.qux();
foo.bar().baz().qux();
// неправильно
foo .bar();
foo. baz();
foo . qux();
foo
.bar(). baz();
Пробелы должны быть внутри фигурных скобок объекта и destructing-присваивания.
let obj = {};
let oob = { foo: 'bar' };
let ojj = { foo: { bar: 'baz', qux: 'guz' } };
const { foo, bar } = guz;
import { foo } from 'bar';
Операторы изменения переменной с присваиванием должны быть сокращены.
// вместо
x = x + 1;
y = y / 2;
a[0] = a[0] + a[1];
d = d ** c;
// должно быть
x += 1;
y /= 2;
a[0] += a[1];
d **= c; // d = Math.pow(d, c)
При переносе длинного условия операторы необходимо ставить в начале строки.
foo = 1
+ 2
+ 3
+ 4;
if (someLongConditionPartOfManyConditionsArray
|| wowThatsAnotherLongConditionButThatIsOneNotPart) {
// ... some code
}
let result = someLongCondition
? operationTruthy()
: conditionFalsy();
Данный выбор объясняется безусловной видимостью операторов в начале строки. Отсутствует необходимость визуально отыскивать их в конце строк разной длины.
Внутри блоков кода не должно быть пустых строк в начале и конце блока
// неправильно
if (a) {
b();
}
// правильно
if (a) {
b();
}
В определении объекта кавычки для имен свойств использовать только в случае совпадения с ключевым именем:
let obj = {
hello: 'world',
0: 12,
true: 1,
'qux-lorem': true,
'null': 'wow'
};
Так как JavaScript неявно дополняет каждую строку ;
и иногда это совсем не очевидно, двоеточия необходимы.
В случае for
после ;
необходим пробел. Но разрешено писать for (;;) {}
В определении именованной или метода класса перед круглыми скобками не должно быть пробелов.
function foo() {}
const d = function() {};
class Foo {
constructor() {
// ...
}
}
go(function() {
// ... go callback
});
Внутри круглых скобок пробелы не должно быть
foo();
foo('bar');
let foo = (1 + 2) + 3;
(function() { return 'bar'; })();
Комментарии должны начинаться с пробела
// Some comment
//Bad comment
В стрелочной функции необходимо обрамлять тело скобками только:
- Если тело в несколько строк
- Когда необходимо выполнить несколько операторов разделенных
;
- Не нужно возвращать значение
let foo = () => 0;
let foo = (retv, name) => {
retv[name] = true;
return retv;
};
let foo = () => { bar(); };
let foo = () => {};
let foo = () => { /* ничего */ };
let foo = () => {
// ничего не делает
};
В стрелочной функции скобки вокруг аргументов ставятся только в случаях:
- если нет аргументов
- если аргументов больше одного
- если используется деструкция (
([a, b]) => {}
,({a, b}) => {}
) - если есть значение по умолчанию для аргумента (
(a = 2) => {}
)
() => {};
a => {};
a => a;
a => {'\n'};
a.then(foo => {});
a.then(foo => { if (true) {}; });
(a, b, c) => a;
(a = 10) => a;
([a, b]) => a;
({a, b}) => a;
let b = parameter => {
let c = a + parameter;
return c / 2;
}
В стрелочной функции должны быть пробелы вокруг круглых скобок списка аргументов.
() => {};
(a) => {};
let b = a => a;
let c = () => {'\n'};
Запрещает определить в классе свойства и методы с одинаковыми именами.
Необходимо группировать импорты из одного модуля.
Правило запрещает дублирующиеся импорты. Такой код должен быть исправлен.
import { name } from 'mod';
import { second } from 'mod';
В конструкторе класса-наследника запрещает использовать this
до вызова super()
.
Необходимо сначала вызвать родительский конструктор
Вместо var
необходимо использовать let
/const
.
Необходимо использовать коротку форму в объектах.
let b = 1;
let foo = {
w() {},
[y]() {},
b,
j: (a) => ++a,
};
Вместо arguments
необходимо использовать rest-параметр
function foo(bar, ...args) {
bar(...args);
}
Вместо .apply()
лучше использовать spread.
const max = Math.max(...[1, 2, 3, 4]);
Вместо конкатенации строк и переменных лучше использовать шаблонные строки. Внутри фигурных скобок шаблона не должно быть пробелов.
const ex = `Hello ${name}. You balance: $${balance.value}`;