Create a reusable ESLint config
Motivation
There are probably as many coding styles out there as there are developers. Even given programming language syntax restrictions, coding is a very personal craft.
That being said, conventions help establish a readable and maintainable codebase. Luckily, there are tools that can help us achieve a healthy level of code uniformity. In the JavaScript ecosystem, two popular choices are
In this article, I will guide you through the process of defining your personal/team coding style as an ESlint configuration. What's more, you will be able to easily share the same configuration across projects.
- eslint-config-kael89 - for JavaScript/React projects
- eslint-config-kael89-ts - for TypeScript/React projects
Creating an ESLint config package
Step 1: Scaffolding
Create a new npm package. By convention, it should start with
eslint-config-
:mkdir eslint-config-examplecd eslint-config-examplenpm init -yCreate an
index.js
file under the project's root. We will define our rules here.Create a
.gitignore
file with the following contents:node_modules(Optional) It is often a good idea to do some housekeeping in your package:
- Add a
README.md
file - Add a
LICENSE
file - Update the default
package.json
fields (keywords
,author
,license
etc)
- Add a
Step 2: Pick a base config (optional)
This step is optional but I find it very convenient. Instead of having to define an extensive set of rules, you can pick an existing config and adjust it to your needs.
In this example, I will use the popular Airbnb Style Guide as the base config. The following command installs the airbnb config package as well as its plugin dependencies:
npm install eslint-plugin-import eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-jsx-a11y
Step 3: Install additional plugins
There is a multitude of great ESLint plugins out there. In this example, we'll add eslint-plugin-import, which enables linting of import statements:
npm install eslint-plugin-import
Step 4: Install Prettier for ESlint (optional)
Again, this is an optional but recommended step. Prettier is a highly opinionated code formatter. This seems to be its basic strength: it works out of the box and results in an arguably elegant formatting.
npm install eslint-config-prettier eslint-plugin-prettier
Step 5: Specify peer dependencies
Our package includes all the required packages as dependencies
, except for the most basic:
eslint
prettier
(if you followed Step 4)
We will specify those as peer dependencies instead. The reason is that they are not strictly required by the plugins, but rather the other way around:, eslint
and prettier
are "host' packages which will load our config/plugins. I suggest reading this npm blog post for a more detailed explanation.
This is also an effective way to specify the supported host package versions. An example:
{
"peerDependencies": {
"eslint": "^6 || ^7.2.0",
"prettier": ">= 1.13"
}
}
Step 6: Configure ESLint
And now time for the real action! Everything comes together in the index.js
file, where we will specify our selected configs, rules and plugins.
Each config file will be uniquely suited to your needs and taste. For our example:
module.exports = {
// eslint-configs
extends: ['airbnb', 'plugin:prettier/recommended'],
// eslint-plugins
plugins: ['simple-import-sort'],
// enabling/disabling/changing level of rules
rules: {
'class-methods-use-this': 'off',
'import/order': 'warn',
'import/prefer-default-export': 'off',
'no-plusplus': 'off',
'no-restricted-globals': 'off',
'prettier/prettier': [
'error',
// configure Prettier for ESLint
{
arrowParens: 'avoid',
printWidth: 100,
singleQuote: true,
trailingComma: 'all',
},
],
radix: 'off',
},
};
We have plenty of options here: luckily, the ESLint documentation is very helpful. A few key points:
- A config/plugin will not be loaded by ESLint unless if you specify it here!
- The precedence of items in
extends
andplugins
follows the order they are listed. This is important in case some items conflict each other - A rule can be either specified as
- a string/number indicating its level:
'off' | 'warn' | 'error'
,0 | 1 | 2
- an array of
[level, options]
whereoptions
is used to configure the rule. You can look at each rule's documentation for the available options, for example: import/order options
- a string/number indicating its level:
Usage
Publishing
Our style guide should be now ready for consumption! Before we add it in our superCoolProject, there is one last step: we need to publish it. We have two main options:
npm: publish your package, then simply install it running
npm install {{packageName}}a git repository: GitHub, GitLab etc. Publish your package, then
npm install git+{{gitUrl}}# Example:npm install git+https://github.com/kael89/eslint-config-kael89.git
Don't forget to update your package's version
with each change, which will allow you to pick up any updates in your projects.
Installation
Install the peer dependencies as
devDependencies
in our project:npm install -D eslint prettierInstall our config. For npm packages:
npm install {{packageName}}For git repositories:
npm install git+{{gitUrl}}# Example:npm install git+https://github.com/organisation/packageName.gitConfigure ESLint to use our package. There are many ways to do so, the simplest probably is adding an
eslintConfig
field in our project's package.json file:{"extends": "{{configName}}"}
🤓Tip: We can omit the eslint-config-
prefix in our package's name. Eg if our package is called eslint-config-example
:
{
"extends": "example"
}
Next steps
Rules breaking between version updates is not at all uncommon. If your config is used by multiple users, it may be a good idea to add some tests to ensure there is no regression when you update it.
You may prefer to publish a personal style guide just on your GitHub account, and not in the npm registry. I will describe how to maintain a versioned node package in GitHub
in a future article.
Until then, rock the code with your tailor-made ESLint config! 🤘🤓