Code Linting
Linting is the process of statically analyzing your code to flag potential errors and help enforce your code quality standards. The biggest benefit of linting is to get very fast and in-context feedback just as you write your code, effectively “shifting left” a good chunk of your code quality checks.
Solution: ESLint
ESLint is the most popular linting solution for JavaScript and Typescript. They are integrations available for most code editors. ESLint is highly configurable and you can write custom rules to enforce guidelines and logic specific to your business.
You can get started here. It features a great command line interface which will ask you questions to generate a good default configuration for your project.
The recommended configuration provides a good set of rules to get started and there are also many open source configurations available.
Start with a script task in your package.json
, for example to run on your source folder:
Recipies
Setup ESLint together with Prettier
As ESLint also covers code formatting, you’ll want to turn off stylistic rules that might conflict with Prettier. This can be easily done with the following package: eslint-config-prettier.
Setup ESLint in your Continuous Integration (CI)
The workflow is as simple as running your previously defined script step after installing dependencies on your Continuous Integration (CI).
For example, with Github Actions, add the following step:
Run ESLint only on changed files
On a very large codebase, validating all files for code formatting can take a bit of time so I would recommend to only do it for changed files.
In that case, you need to configure the changed files action to run ESLint against changed files only, here is an exmaple configuration with pnpm:
We are using the --no-warn-ignored
flag to avoid warnings for files explicitly ignored by ESLint.
Setup ESLint check as pre-push hook with Lefthook
Start by installing Lefthook with your favorite package manager.
Then for the first time setup run:
It will create a file called lefthook.yml
, which we can configure like this for ESLint:
Each time we will push code, it will compare our diff tree with our main branch and for changed files it will run ESLint checks ensuring your code is linted before you can push.
Write your own custom ESLint rules
Every business and project has its own specific requirements that recommended linting rules cannot cover. This is where custom rules come in to codify them and fix them automatically.
Another great use case for custom rules is to to prevent regressions following a bug fix. If you can prevent the problem from occuring again with an ESLint custom rule, it will provide more value than a unit test. The main reason being that it will provide developers with an in-editor contextual error with potentially already a fix for it, saving time in contrast to a test failing, opening and reading the test and its expected assertion.
I would recommend to create a simple custom rule for your prorject to showcase their potential and serve as a blueprint for many more!
ESLint website has documentation on custom rules as well as a great tutorial to get started.
Here is a simple example to automate a rule to enforce the usage of structuredClone over legacy JSON.parse(JSON.stringify(…)) to deep clone objects.
When you import this custom rule in your ESLint config, it will flag usages of JSON.parse(JSON.stringify(…)) and even replace them automatically with structuredClone(…).