[EN] The first step to cleaner, more consistent Frontend code
ℹ️ 本記事の日本語版はこちらをご覧ください。
Introduction
The first important decision you make with a frontend codebase is how you start it. Picking the framework and package manager to start it all is a necessary step, much like the lump of clay a potter picks to throw onto their wheel. However, without the proper approach, the final product can come out all uneven and disorganised, or even worse, fall apart. For this, tools like ESLint and Prettier are the steady guiding hand that ensure a clean and consistent codebase.
In this article, I would like to share my perspective on how to best use these tools for your frontend projects.
This is a two-part series; the first part looks at installing a very robust linter/formatter combo: ESLint and Prettier. The second part will be more in-depth, looking at how to get the most out of this setup and adapting it to your needs.
Who is this for?
- Anyone who wants clean, consistent code
Tools for quality coding
ESLint is the de facto code linter for Javascript. It helps to identify errors in your code, alert you to them, and even automatically fix them. It is highly customisable, allowing for exceptional tailoring to your project's needs.
Prettier on the other hand, is a popular code formatter that can handle Javascript and more. It focuses on taking existing code and reformatting it to follow a strict predefined coding style. It is very opinionated; this is by design. The minds behind Prettier have done all the thinking for you so you don't have to nitpick.
They are relatively easy to implement, but provide an enormous benefit to existing codebases that don't have them (more on that soon). They have great integration with a diverse number of editors, making them suitable for almost all developer environments. They can be set up in a way such that you never really have to think to use them.
I will mainly be focusing on ESLint and Prettier, but there are a couple of other tools that you can consider adding to improve your code quality assurance.
Honorable Mentions
stylelint
A CSS linting equivalent to ESLint, with many built-in features and the potential to cover even embedded styles (in HTML, Markdown, CSS-in-JS) and CSS-like languages (SCSS, Sass, Less).
cspell
A lightweight compared to the tools mentioned above, but useful nonetheless if you are concerned with spelling functions, variables and so on correctly.
Why use them together
Writing code to be error-free on the first try, and making sure that code always follows the set coding style is a tiresome task. To err is human, and any developer is bound to make a mistake here and there. Add to that the chaos of multiple err-ing humans working on the same codebase, and you have a recipe for disaster.
Tools like ESLint and Prettier can be implemented early in a project's life to completely eliminate that mental burden. No longer will you stumble over incorrect function names or missing references; ESLint will tell you before you even go to test it. No longer do you need to remember to put semicolons everywhere, or use the right number of spaces for indenting. Right after saving the file, Prettier will clean it all up for you.
In the larger scope of developing as a team, it gives peace of mind knowing that everyone's local repo is aligned to the same standard. It also means code reviewers can worry less about common mistakes and correctness.
With these two alone, you can set the standard for the codebase once, and never have to think about it twice. Unless of course your project evolves beyond your original scope and you need to rein it in again...
How to start
Installing Prettier
Prettier is quite opinionated, meaning that a lot of decisions for formatting have already been made for you (this is a good thing). It is so developers don't have to fret about the coding style and just focus on the coding. It also means once you get it started, it work relatively hands-free.
The main steps to implementing Prettier are:
- Install as a dev dependency* with your favourite package manager, preferably as the exact version**
- e.g.
npm install --save-dev --save-exact prettier
- *This is important as you don't need Prettier for production builds
- **Saving the exact version means consistency across all workspaces
- e.g.
- Create an empty
.prettierrc
file so that editors know you are using Prettier- Or
.prettierrc.json
,.prettierrc.js
, or any other valid file listed
- Or
- Create a
.prettierignore
file to define what file Prettier should avoid - Configure your editor to run Prettier locally
- Prettier can be run from the command line, but we're here to automate!
- Most editors have a plugin for Prettier (e.g. VSCode has
prettier-vscode
, Vim hasprettier-vim
, etc.)
- Define a keyboard shortcut to run Prettier, or better yet, have it run every time you save
- For VSCode, this looks like adding
"editor.formatOnSave": true
to your settings.json
- For VSCode, this looks like adding
Installing ESLint
There are a dizzying number of configurations for ESLint that you can add on, but actually getting started is made easy by the handy initialiser.
- Run the initialiser with your favourite package manager
- e.g.
npm init @eslint/config@latest
- This will ask you a number of questions to configure ESLint to your project
- e.g.
- Configure further in the
eslint.config.js
and.eslintignore
files (more details in part 2)
Playing nice with Prettier
ESLint itself does some checks on formatting, but it is more efficient to let Prettier handle those things. After installing eslint-config-prettier
first,
npm install --save-dev --save-exact eslint-config-prettier
we can then add it to the newly created eslint.config.js
file.
export default defineConfig([
// ...
prettier
]);
Incorporating into your workflow
ESLint and Prettier have CLI commands that allow you to manually run them:
npx eslint file1.js file2.js
npx prettier path/to/file1.js --write
However, this can get very repetitive and would be better off automated. There are three levels of automation you can set up for yourself:
- Formatting and linting when you save your file
- A script command that runs a chain of processes
- Integrating into your CI/CD workflow
On save
The first recommended setting is having your code linted and formatted whenever you make a change and save the file. This will automatically address any new warnings you might have introduced implementing a new feature.
I'll use VSCode as the example, but similar settings are available for other editors.
- Open User Settings (JSON)
- Add any of the following to the JSON file:
-
"editor.defaultFormatter": "esbenp.prettier-vscode"
- Sets Prettier as the default formatter
-
"editor.formatOnSave": true
- Enables Prettier to format the file when saved
-
"editor.codeActionsOnSave": { "source.fixAll.eslint": true }
- Enables ESLint to lint the file when saved
-
- Save your settings
- Reload to make sure VSCode is correctly configured
Setting up a script
This is important because changes in one file might impact other files, but you won't be made aware of this unless you open said files or have the tools check all files. Having this set up as an easy to run command makes repository-wide checks easier.
In your package.json
, combine the aforementioned CLI commands together into a single, easy to run command with your package manager (this example uses npm
):
"scripts": {
"lint": "npx eslint --cache --config eslint.config.js --fix .",
"format": "npx prettier --cache --config .prettierrc.js --log-level error --write",
"fix": "npm run lint && npm run format"
}
A few details here:
-
lint
will have ESLint scan all files and automatically fix any issues it can, referencing theeslint.config.js
specified after the--config
flag. It will also store a cache file which makes future runs faster as it will only scan files that have changed since the last scan. -
format
will similarly run Prettier on all files in the working directory, refering to the defined config file and saving a cache.--write
flag means it will overwrite any files that require formatting, while--log-level error
means that only error level warnings will be outputted in the console. -
fix
will run the above scripts together
With the above, you would only need to run npm run fix
to have your workspace linted and formatted. It is good to run this once before commiting code to a shared repository.
Integrate with your pre-commit hook
Especially when working with teams, you want to ensure all code going into your remote repository is consistent with everyone else. One guarantee (and recommendation) is to use either of the following pre-commit tool configurations:
This ensures code is always formatted and checked before being committed, which can save a lot of headaches. This is also a great way to get into CI/CD.
To finish
By implementing ESLint and Prettier into your next project, you will have a degree of assurance that your code is consistent and follows modern coding standards. This should hopefully make the development process smoother, as your code will require less mundane maintenance.
In the second part, I will go more in-depth into the configuration of the aforementioned tools, and how to best customize them to suit your needs.
Discussion