eslint-config-peerigon
Peerigon coding rules as ESLint config.
![Dependency Status](https://david-dm.org/peerigon/eslint-config-peerigon.svg)
These rules are intentionally strict about formatting or whitespace issues. You should use an editor configuration where you can apply autofixes (eslint --fix
) on demand (for instance when saving the file). The goal of these rules is to achieve a consistent coding style while avoiding common pitfalls.
We use warnings for typical code smells (e.g. too many dependencies, high complexity, ...) or when a better alternative exists (e.g. throw Error("...")
over process.exit(1)
).
Please do not just disable warnings. First, try to fix them. If it's too difficult for now, leave them as hints for other developers that this place might need some refactoring in the future. If there is a good reason why the code is written that way, you're allowed to disable that particular warning with a disabling comment using the rule-code. Please put an explanation above that comment why it's ok to disable the rule in that case, like:
function validate() {
}
// eslint-disable-next-line
is usually better because it resists Prettier reformatting.
Provided configs
Base rules for every project. You should always add these rules.
npm i eslint@5 eslint-config-peerigon --save-dev
These rules assume a modern project with full ES2015 support, including ES modules. For specific environments like Node.js or old JS engines, see below. The base rules do not define an env
, so you might want to do that for yourself to enable specific globals.
Add an .eslintrc.json
to the project's root folder:
{
"extends": [
"peerigon"
],
"env": {
"node": true
},
"root": true
}
In your package.json
, add a lint
script and run it as posttest
:
{
"scripts": {
"lint": "eslint ./src ./test",
"posttest": "npm run lint"
}
}
The base rules use the eslint-plugin-import
to resolve imports. Although it's possible to define custom resolvers, it's highly discouraged to deviate from the common Node/webpack resolving algorithm. Other tools like linters and intellisense don't work reliably when you change the resolver.
Special rules for tests, like allowing deeper function nesting and function inlining.
Create a .eslintrc.json
file inside your test
folder with these contents:
{
"extends": [
"peerigon/tests"
]
}
Do not add "root": true
here since we want to extend our project config.
Special rules for Node.js >= 8.0.0 environments:
{
"extends": [
"peerigon",
"peerigon/node"
]
}
Important: Requires eslint-plugin-react
and eslint-plugin-jsx-a11y
as project dependency.
npm i eslint-plugin-react eslint-plugin-jsx-a11y --save-dev
Rules for React development, including accessibility rules.
These rules are also applicable in other JSX environments, like Preact:
{
"extends": [
"peerigon",
"peerigon/react"
],
"root": true
}
Important: Requires @typescript-eslint/eslint-plugin
, @typescript-eslint/parser
and eslint-import-resolver-typescript
as project dependency.
npm i @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-import-resolver-typescript --save-dev
Rules for TypeScript.
{
"extends": [
"peerigon",
"peerigon/typescript"
],
"root": true
}
You need to add --ext js,ts,tsx
to the lint
script:
{
"scripts": {
"lint": "eslint ./src ./test --ext js,ts,tsx"
}
}
Important: Requires babel-eslint
and eslint-plugin-flowtype
as project dependency.
npm i babel-eslint eslint-plugin-flowtype --save-dev
Rules for Flowtype.
{
"extends": [
"peerigon",
"peerigon/flowtype"
],
"root": true
}
Special rules for older projects:
{
"extends": [
"peerigon",
"peerigon/es5"
],
"root": true
}
Styles
The following rules enable specific writing styles. Use them as you prefer.
Important: Requires eslint-plugin-prefer-arrow
as project dependency.
npm i eslint-plugin-prefer-arrow --save-dev
Enforces arrow function expressions instead of function declarations (see #23).
Regular functions are still allowed as methods in objects or classes.
{
"extends": [
"peerigon",
"peerigon/styles/prefer-arrow"
],
"root": true
}
Important: Use it in combination with peerigon/typescript
.
Prefer interface
over type
.
{
"extends": [
"peerigon",
"peerigon/typescript",
"peerigon/styles/prefer-interface"
],
"root": true
}
Goals
Coding rules and coding conventions are always a hot topic because they tend to be subjective.
But for the benefit of all team members, it's reasonable to have common rules among projects.
We judge our rules by these features, ordered by priority:
- Ease of reading
- Ease of refactoring
- Ease of writing
Because:
- we read code more often then we change it and
- we change code more often then we write it.
Since the "ease of reading" tends to be subjective again, we should stick to well-known typography rules:
Avoid long lines
This line is hard to follow because it's long. The human eye is not used to follow a straight line for so long that's why it feels more comfortable to have some line breaks between them.
Avoid unbalanced lines
The following two lines look a little bit strange because the first one has a lot of text and is very long while the second
is short.
Use horizontal whitespace
this=is+hard-to;read-because/we,can't,distinguish&tokens
andLongVariableNamesAreHardToReadBecauseCamelCaseHasNoWhitespace
Don't use too much vertical whitespace
This is a line with some text in it, and after that
There is
another
blank
line and than
another blank link and again
Avoid unnecessary characters
(yes) = {we: (are)}, (programmersWhoAreUsedToReadThis - but);
this = is ? nicer : to(read);
Repeat familiar patterns and stay consistent
it =is distracting {to :use } { whitespaces}= inconsistently .
We should also take into account that code is different than regular paragraphs of text. That's why there are also other concerns, like the following:
A change should be as atomic as possible
That's why this change:
let a = 1; let a = 1;
let bb = 2; change to const bb = 2;
let ccc = 3; let ccc = 3;
is better than that change:
let a = 1, let a = 1,
bbb = 2, change to cc = 3;
cc = 3; const bbb = 3;
If you don't have to change a lot of lines, refactoring is more fun. As a nice side-effect, git diff
also becomes more readable.
Recommendations
Disabling rules
Sometimes, there is a legitimate use-case to disable a specific rule. You can disable a rule for the current line like this
where rule-code
is the code that is displayed along the error message.
In rare cases, it makes sense to disable a rule for the whole project. For instance, if you work with JSON data coming from a foreign API that uses underscore property names.
If you don't agree with a rule, please do not disable the rule. It's better to create an issue here to start a discussion about the pros and cons of a rule.
Should I apply --fix
as part of my posttest
script?
No. Because this way, eslint won't report all linting errors on Travis CI. Thus, a PR could contain linting errors without Travis CI complaining about it.
License
Unlicense
![](https://assets.peerigon.com/peerigon/logo/peerigon-logo-flat-spinat.png)