This package provides Atomix's base .eslintrc config for ECMAScript 2017.
Our config bases on Airbnb's eslint config and Unicorn by Sindre Sorhus.
Installation:
npm install --save-dev eslint babel-eslint eslint-config-atomix-base
Create .eslintrc
:
{
"extends": "atomix-base",
"parser": "babel-eslint",
"parserOptions": {
"ecmaVersion": 2017
}
}
Add test
script to your package.json "test": "eslint src lib bin"
If you don't want es2017 features:
npm install --save-dev eslint eslint-config-atomix-base
{
"extends": "atomix-base"
}
Config extends airbnb-base
and plugin:unicorn/recommended
.
https://eslint.org/docs/rules/strict
Disable strict mode. You can manually enable it if required.
{ ignoreRestSiblings: false }
https://eslint.org/docs/rules/no-unused-vars
Unused variables/functions/classes should be removed or commented.
https://eslint.org/docs/rules/semi
We don't write semicolons at each line. Only when needed.
https://eslint.org/docs/rules/no-confusing-arrow
Really? You can be confused with?
const x = (a) => 1 ? 2 : 3
https://eslint.org/docs/rules/object-property-newline https://eslint.org/docs/rules/object-curly-newline https://eslint.org/docs/rules/object-curly-spacing
Disabled because broken
https://eslint.org/docs/rules/arrow-parens
As defined in Airbnb JS CodeStyle arrow parens should only for block body.
But when you add more params for lambda, you should add parens. Example:
-.map(value => rotate(value, 1))
+.map((value, index) => rotate(value, 1 - index))
It provides inconsistency.
// Good
() => {};
(a) => {};
(a) => a;
(a) => {'\n'}
a.then((foo) => {});
a.then((foo) => { if (true) {} });
const foo = (bar, baz) => ({ bar: baz })
const bar = ({ bar }) => bar.baz
const baz = (example) => {
return 1
}
// Bad
() => {};
a => {};
a => a;
a => {'\n'}
a.then(foo => {});
a.then(foo => { if (true) {} });
const foo = (bar, baz) => ({ bar: baz })
const bar = ({ bar }) => bar.baz
const baz = example => {
return 1
}
{
properties: false,
onlyDeclarations: true,
}
https://eslint.org/docs/rules/id-match
All identifiers should be camelCased and more that 2 symbols length. Constants can be SCREAMING_UNDERSCORED
// Good
let value = 1
const functionDummy = (argument) => {}
const CONSTANT_NAME = 123
class ExampleName {}
// Bad
const Value = 1
const function_dummy = (MySuper_Argument) => {}
const constant_NAME = 1
class example_CLASS_name {}
{
ignore: [1, 0, -1],
ignoreArrayIndexes: true,
enforceConst: true,
detectObjects: false,
}
https://eslint.org/docs/rules/no-magic-numbers
Magic numbers is not descriptive. Please name it.
Exclude: 1, 0, -1, array indexes, object of numbers.
// Good
const TAX = 1.28
const Coeff = {
A: 0.924,
B: 0.759,
C: 0.552,
V: 0.308,
Z: 0.116,
}
const val = myList[5]
const prev = myList[val.next - 1]
{
arrays: 'always-multiline',
objects: 'always-multiline',
imports: 'always-multiline',
functions: 'ignore',
}
https://eslint.org/docs/rules/comma-dangle
Not all environments supports comma dangle in function call/definition.
{
overrides: {
'?': 'before',
':': 'before',
'&&': 'before',
'+': 'before',
'||': 'before',
},
}
https://eslint.org/docs/rules/operator-linebreak
We like write idented code and readable code in any line width.
// Good
const foo = condition
? firstResult
: second + result
const demo = Foo.first
|| Foo.second
|| 'default value'
// Bad
const foo = condition ?
firstResult :
second + result
const demo = Foo.first ||
Foo.second ||
'default value'
https://eslint.org/docs/rules/brace-style
Because, 1tbs is so dirty.
// Good
function Demo(argument) {
if (argument && argument.chained) {
try {
const result = Target.actionCall(argument, -1)
while (!result.active) {
result.status.to((status) => status + argument.value)
}
return result
.map((value) => value.resolver((res) => res[result.name]))
}
catch (error) {
return Target.chainCall(() => Target.wrapWith(argument, error))
}
}
else if (argument) {
const value = Target.wrap(argument)
try {
return value
.resolver((res) => value.getProp(res))
.map((value) => value.head())
}
catch (error) {
const rawValue = value.chain(Target.useRawSource)
return Target.chainCall(() => Target.wrapWith(rawValue, error))
}
}
else {
const defaultValue = Target.wrap(Target.null())
return defaultValue
.resolver((res) => null)
.map((value) => Target.useRawSource(null).value())
.chain((fut) => fut.status.to((status) => 0))
}
}
// Bad
function Demo(argument) {
if (argument && argument.chained) {
try {
const result = Target.actionCall(argument, -1)
while (!result.active) {
result.status.to((status) => status + argument.value)
}
return result
.map((value) => value.resolver((res) => res[result.name]))
} catch (error) {
return Target.chainCall(() => Target.wrapWith(argument, error))
}
} else if (argument) {
const value = Target.wrap(argument)
try {
return value
.resolver((res) => value.getProp(res))
.map((value) => value.head())
} catch (error) {
const rawValue = value.chain(Target.useRawSource)
return Target.chainCall(() => Target.wrapWith(rawValue, error))
}
} else {
const defaultValue = Target.wrap(Target.null())
return defaultValue
.resolver((res) => null)
.map((value) => Target.useRawSource(null).value())
.chain((fut) => fut.status.to((status) => 0))
}
}
https://eslint.org/docs/rules/quote-props
Use quotes only if needed.
// Good
const foo = {
demo: 1,
'foo-bar': 2,
bar: {
lock: 4
},
baz: 3,
}
// Bad
const baz = {
'demo': 1,
'foo-bar': 2,
'bar': {
'lock': 4
},
'baz': 3,
}
https://eslint.org/docs/rules/no-plusplus
We use it, because it good shorthand for some cases.
{ exceptAfterSingleLine: true }
https://eslint.org/docs/rules/lines-between-class-members
Add lines between class methods/properties.
Example:
class Foo {
id = 1
name = 'Foo'
constructor() {
// code
}
toString() { /* single line */ }
member() {
// code
}
}
https://eslint.org/docs/rules/implicit-arrow-linebreak
Implicit return in arrow function should be on same line.
Correct:
const foo = () => 1
const bar = () => (
2
)
const baz = () => {
const val = 3
return 3
}
Incorrect:
const foo = () =>
1
const bar = () =>
(
2
)
const baz = () =>
() =>
3
{ blankLine: 'always', prev: ['const', 'let', 'var'], next: '*' },
{ blankLine: 'any', prev: ['const', 'let', 'var'], next: ['const', 'let', 'var'] },
https://eslint.org/docs/rules/padding-line-between-statements
Add padding line after let
, const
definitions.
Correct:
const foo = 1
const bar = 2
runFunc(foo, bar)
Incorrect:
const foo = 1
const bar = 2
runFunc(foo, bar)
https://eslint.org/docs/rules/no-await-in-loop
In Node.js LTS await in loop is native and optimized.
Enabled in react
https://eslint.org/docs/rules/no-restricted-syntax
In node.js we want to use "await in for" without Futures.
https://github.com/airbnb/javascript#iterators--nope
Enabled in react
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-unresolved.md
Because some projects use aliases or module resolvers.
But you can configure module resolver for eslint and enable it rule in your config.
always for: json, json5, less, css, scss, sass, styl, jpeg, jpg, png, svg, bmp, gif
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/extensions.md
Node, webpack, rollup not require .js
in file path by default.
{
groups: [
['builtin', 'external'],
['internal', 'parent'],
['sibling', 'index'],
],
'newlines-between': 'ignore',
}
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/order.md
Prefer order of your imports. To correct resolving internal
and external
modules configure module resolver.
{ count: 2 }
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/newline-after-import.md
We separate our imports with main code with 2 empty lines.
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/prefer-default-export.md
Use named exports to resolve naming problem.
With default export you can implicitly rename import binding. And your import not found in search by project.
// foo.js
export default class Foo {}
// bar.js
import SomeAnyName from './foo'
With named import you explicitly rename import binding.
// foo.js
export class Foo {}
// bar.js
import { Foo as SomeAnyName } from './foo'
https://github.com/benmosher/eslint-plugin-import/blob/master/docs/rules/no-named-as-default.md
Rule is not resolving param-case
naming of the files.
import FooBar from './foo-bar' // Correct import. But not solved by rule
{ name: 'error' }
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/catch-error-name.md
Variable names like e
, err
, er
is so short. Name should be comprehensive like error
.
Disabled, because we like functional programming and we check all changelogs before update dependencies.
https://github.com/sindresorhus/eslint-plugin-unicorn/blob/master/docs/rules/import-index.md
Disabled, because we like more descriptive paths.