ESLint is a code linter for JavaScript.
This configuration combines:
- functional programming.
- Standard JavaScript which prescribes how to format your code.
- Prettier which allows you to automatically format your code as part of your build process or inside your IDE.
- editorconfig which fulfills a similar goal but more generic and limited.
- modularity by encouraging splitting your code into small modules and functions.
- modern JavaScript.
- strictness.
Install
npm install -D eslint-config-fp eslint@^5.6.0 eslint-config-prettier@^3.0.1 eslint-config-standard@^12.0.0 eslint-import-resolver-node@^0.3.2 eslint-plugin-eslint-comments@^3.0.1 eslint-plugin-filenames@^1.3.2 eslint-plugin-fp@^2.3.0 eslint-plugin-html@^5.0.0-alpha.0 eslint-plugin-import@^2.14.0 eslint-plugin-markdown@^1.0.0-beta.8 eslint-plugin-node@^7.0.1 eslint-plugin-promise@^4.0.1 eslint-plugin-standard@^4.0.0 eslint-plugin-unicorn@^6.0.1 eslint-plugin-you-dont-need-lodash-underscore@^6.4.0 prettier@^1.14.3
Then in your .eslintrc.json
:
The configuration is very opinionated but you can override specific rules in
your .eslintrc.json
to fit your needs and coding style.
Then create a symlink to the Prettier configuration and .editorconfig
in your
project:
ln -sf node_modules/eslint-config-fp/.prettierrc.yml node_modules/eslint-config-fp/.editorconfig .
Badge
The following badge can be added to your project:
[![eslint-config-fp](https://img.shields.io/badge/eslint-config--fp-green.svg?logo=eslint)](https://github.com/autoquality/eslint-config-fp)
Prettier
prettier
must be run before eslint
to avoid conflicts.
We recommend using first prettier --write
then eslint --fix --cache
.
Do not forget to add .eslintcache
to your .gitignore
file.
Functional programming
This enforces that state is never directly mutated and global state is not referenced:
- immutability: mutating variables or object properties is not allowed. In other words it enforces no assignment after declaration, i.e. variables must be copied instead of mutated.
- no global variables except the ones that are built-in (e.g.
module
orObject
) unless they are Node-specific (e.g.process
) or should be wrapped (e.g.console
). - loops (
for
,while
,switch
) are forbidden as they imply state. Instead functional methods (likeArray.map()
andArray.filter()
), recursion and smallif
blocks (with early returns) can be used. - Classes/OOP are forbidden as they imply state. To inherit/share behavior, one can use composition or Generic programming instead.
- Events are forbidden as they imply state.
However throwing exceptions are allowed as this can simplify code.
Modularity
The following rules are enforced to encourage splitting your code into small modules and functions:
- lines are at most 80 characters long
- lines are at most 2 statements long
- branches/blocks cannot be nested
- functions have at most 4 branches/blocks (cyclomatic complexity)
- functions are at most 10 statements long
- files are at most 90 non-empty lines long
- files have at most 10 dependencies
(
require
/import
)
Modern JavaScript
- object and array destructuring
- object spreading:
{ ...object }
instead ofObject.assign({}, ...object)
- arguments spreading:
funcName(...args)
instead offuncName.call(this, ...args)
- parameters spreading:
function(...args)
instead offunction(arguments)
- template strings instead of concatenation
async
/await
instead of explicit promises or callbacks.**
instead ofMath.pow()
- vanilla JavaScript instead of Lodash/Underscore
- only JavaScript features supported by the Node.js version specified in your
package.json
engines
field.
Strictness
The configuration is very explicit and enforces strict linting. This should help you find bugs and maintain a consistent coding style.
This includes:
use strict
- typecasting must be explicit
- file dependencies must be sorted
- variable names must remain short
- constants must be assigned to variables
- avoiding turning off ESLint rules with comments
- RegExps must use the
u
flag - no variable shadowing
Other styling rules
- named parameters (i.e. passing an object as single parameter) instead of positional parameters.
- using
index.js
files andrequire('./dir')
instead ofrequire('./dir/subdir')
- function declarations must be
const funcName = function() { ... }
- errors must be named
error
HTML and Markdown
eslint-plugin-html and eslint-plugin-markdown are included so you can lint JavaScript inside HTML or Markdown files.
Projects using this configuration
- autoserver: create a full-featured REST/GraphQL API from a configuration file
Feel free to submit an issue or PR to add your project to the list above!