Originally published on my personal blog
Intro
There are many tools that help developers eliminate possible errors and bugs, and in the end, ship more robust and maintainable code. Among them, the most commonly used static code analysis tool is ESLint.
Another trendy tool is Prettier. It makes your code look beautiful to developers' eyes (yours included).
And let's not forget about TypeScript! It's a static type checker for JavaScript, and it improves developer experience by a ton.
Plus, we will publish our ESLint and Prettier config as an NPM package, thus making it reusable and easily installable in any React project (well, generally in any Javascript project, but it will contain react.js / React Native specific rules).
Usually, when I start a new React project, I add all the above-mentioned tools manually, one by one. Finally, I found a time to create my custom config package based on the most typical setup on projects that I'm working/worked on. This blog post is a walkthrough of how I did it.
Also, the blog post will cover how to install Husky and lint-staged. Basically, it will ensure that we don't cheat and follow all the necessary rules.
So, let's start!
1. Create a Node.js module
npm init -y
Now we have a project with a basic package.json file.
Make sure that the module name begins with eslint-config-. I named mine as eslint-config-ramonak.
//package.json
...
"name": "eslint-config-ramonak"
...
2. Add ESLint
The easiest way to add ESLint, necessary dependencies, and basic configuration, is by running:
npx eslint --init
You will be prompted to answer different questions. Based on my typical type of projects, I answered them like that:
It will install @typescript-eslint/eslint-plugin
, @typescript-eslint/parser
, eslint
, eslint-plugin-react
packages as dev dependencies in the project (in your specific use case packages might be different, depending on your answers). And also, it will add .eslintrc file with the basic config.
3. Add Prettier
Run:
npm i -D prettier eslint-config-prettier eslint-plugin-prettier
This will install:
- prettier
- eslint-config-prettier - to turn off all rules that are unnecessary or might conflict with Prettier
- eslint-plugin-prettier - runs Prettier as an ESLint rule and reports differences as individual ESLint issues
Add plugin:prettier/recommended
as the last extension in your .eslintrc
file:
{
"extends": [
///other plugins
...
"plugin:prettier/recommended"
]
}
For the info, it is short for:
{
"extends": ["prettier"],
"plugins": ["prettier"],
"rules": {
"prettier/prettier": "error",
"arrow-body-style": "off",
"prefer-arrow-callback": "off"
}
}
Now we can add our custom prettier options.
As this blog post's final goal is to create an NPM package, I'll add a prettier config directly into the eslint config without making a separate .prettierrc file. But this might conflict with text editor extensions (like prettier-vscode, for example), as they read directly from .prettierrc file. Possible solutions might be:
1.Create .prettierrc file in your project and copy the configuration from .eslintrc file there.
2.Uninstall (if already installed) a prettier extension and config your text editor to use ESLint extension only for code formatting. More on that here.
//.eslintrc
...
"rules": {
"prettier/prettier": [
"error",
{
"trailingComma": "es5",
"singleQuote": true,
"printWidth": 100,
"semi": true
}
]
}
You can customize your formatting preferences whatever you like. The list of all possible options is here.
4. Add additional ESLint plugins (optional)
There are numerous ESLint plugins available for you to add to your project.
I'm going to add eslint-plugin-react-hooks. Also I like all imports to be nicely sorted. Fot that let's add eslint-plugin-simple-import-sort.
npm i -D eslint-plugin-react-hooks eslint-plugin-simple-import-sort
Then update .eslintrc file:
{
"extends": [
// ...
"plugin:react-hooks/recommended"
],
"plugins": ["simple-import-sort"], //other plugins omitted
"rules": {
"simple-import-sort/imports": "error",
"simple-import-sort/exports": "error"
//other rules omitted
}
}
Feel free to add any custom rules based on your specific requirements.
5. Create index.js file
We need to add an entry point to our package. So create index.js
file with the following content:
const eslintrc = require("./.eslintrc.json");
module.exports = eslintrc;
6. Declare peer dependencies
As it is stated in the official ESLint docs, you should declare your dependency on ESLint in package.json
using the peerDependencies
field. So just copy all dev dependencies in the package.json
file to peerDependencies
field:
//package.json
...
"peerDependencies": {
"@typescript-eslint/eslint-plugin": "^5.5.0",
"@typescript-eslint/parser": "^5.5.0",
"eslint": "^8.4.0",
"eslint-config-prettier": "^8.3.0",
"eslint-plugin-prettier": "^4.0.0",
"eslint-plugin-react": "^7.27.1",
"eslint-plugin-react-hooks": "^4.3.0",
"eslint-plugin-simple-import-sort": "^7.0.0",
"prettier": "^2.5.1"
}
7. Test
Probably it's not a bad idea to test the ESLint config locally before sharing it with the world.
Link your eslint-config module globally by running the following command at the root level of your eslint-config folder:
npm link
Then in the project where you'd like to test your eslint-config run:
npm link <name of your eslint-config>
For example, in my case I run:
npm link eslint-config-ramonak
Please note that you won't see any changes in the packages.json
file after running that command. But your eslint-config will be added into node_modules
folder.
Additionally, you need to manually install all peer dependencies (that are not present in your project) from your eslint-config package.
Something like this:
npm i -D @typescript-eslint/eslint-plugin @typescript-eslint/parser eslint-config-prettier eslint-plugin-prettier eslint-plugin-react eslint-plugin-react-hooks eslint-plugin-simple-import-sort prettier
Then you need to tell your project to use your custom eslint-config. For that,
- in
package.json
add or edit (if already exists)eslintConfig
field:
"eslintConfig": {
"extends": [
"ramonak" //your eslint-config module name
]
}
- OR create
.eslintrc
file with the following content:
{
"extends": ["ramonak"] //your eslint-config module name
}
Now you can run linter:
npx eslint .
If you'd like fixable errors to be fixed automatically, run:
npx eslint . --fix
8. Publish
You need an NPM account to be able to publish your eslint-config package. If you don't have it, you can sign up here.
Once you are ready to publish, just run:
npm publish
9. Integration with VSCode
Uninstall or disable any previously installed prettier extensions.
Install (if haven't already) ESLint extension
Edit VSCode settings by pressing CMD + SHIFT + P on Mac (or Ctrl + SHIFT + P on Windows), type
settings
and choosePreferences: Open Settings (JSON)
. Edit or add the following settings:
// Format a file on save
"editor.formatOnSave": true,
// show eslint icon at bottom toolbar
"eslint.alwaysShowStatus": true,
// turns on Auto Fix for all providers including ESLint
"editor.codeActionsOnSave": {
"source.fixAll": true
}
Remove "editor.defaultFormatter": "esbenp.prettier-vscode"
line if you had it before.
Now all fixable ESLint (including Prettier formatting options) errors will be fixed automatically on a file save.
10. BONUS: Add Husky and lint-staged
To enforce linting rules compliance, let's add Husky and lint-staged. These tools will automate the running of the linting scripts before each commit. If there are any lint errors, the code won't be committed. And lint-staged will help save our precious time as it will make run the lint script only for staged (e.g., files that we updated) and not on the whole project.
- Install lint-staged and husky by running just one command:
npx mrm@2 lint-staged
- Update config in
package.json
:
"scripts": {
//other scripts omitted
"lint:fix": "eslint . --fix" //add linting script
},
"lint-staged": {
"*.{js,jsx,ts,tsx}": "npm run lint:fix" //run linting script only on JS and TypeScript files
}
Now, whenever you try to commit any JavaScript or TypeScipt files, the linting script will run, and if there are any unresolved errors, these files won't be committed.
Conclusion
If you want to add ESLint, TypeScript, and Prettier config into your project without any additional tooling, just follow steps 2 and 3.
If your is goal is to add ESLint, TypeScript, and Prettier with Husky and lint-staged, use steps 2, 3, and 10.
And you are very welcome to use my custom eslint-config and report any issues or make pull requests.
P.S. Development of my custom eslint-config inspired by eslint-config-wesbos.
Top comments (0)