DEV Community

Cover image for Angular 14 + Prettier + Husky Setup
Fernando
Fernando

Posted on

Angular 14 + Prettier + Husky Setup

The purpose of this post(and the first one I "write"), is to share in a simple and hopefully useful way how we can implement Prettier and Husky in an Angular 14 application, but before we start you might be wondering what is Prettier, or maybe more specifically WHAT THAT HELL IS HUSKY?

If you have any suggestions and/or something that can enrich this post, I would be very grateful for it, so let me know.

What is Prettier šŸ˜Ž?

Prettier is an popular and opinionated code formatter. It is a tool that helps you enforce consistent code style across your codebase. It is a great tool when you are working with JavaScript, TypeScript, CSS, and other languages, definitely is a great way to keep formatted code consistently across your team.

What is Husky šŸ¶?

Husky: Of course! Let's focus on this impressive tool rather than discussing the charming breed of dogs known as Huskies.

Husky is described as a tool that simplifies Git hooks. It offers pre-commit and pre-push hooks, which are essentially commands you want to execute each time you commit or push changes.

In this post, we'll demonstrate how to set up Husky and Prettier in an Angular 14 application to streamline and automate code formatting and detect potential issues/errors in your code.


Let's get started!


1. Create a new Angular 14 project

Create a new Angular 14 project using the CLI and run the project with the following command (in this case the project name is angular-prettier-husky-setup, you can name it whatever you want):

Make sure you have installed NodeJS version 16 minimum, in order to install the Angular CLI, if you don't have it installed on your operating system, for more details on how to install NodeJS, see this link, as well as the documentation of Angular CLI, for more details on the Angular CLI, and its installation process.



ng new angular-prettier-husky-setup


Enter fullscreen mode Exit fullscreen mode

Feel free to use the package manager of your choice to install the Angular CLI.


2. Install ESlint

Angular provides us with a powerful ESLint that helps us detect and correct errors in our code. Therefore, we are going to install it in the project.

For this, we can refer to the following documentation to find out which version of ESLint it offers:

ng add @angular-eslint/schematics@12 #for angular 12

ng add @angular-eslint/schematics@13 #for angular 13

ng add @angular-eslint/schematics@14 #for angular 14

In this case, when working with Angular 14, we use version 14. Therefore, we are going to install it:



ng add @angular-eslint/schematics@14


Enter fullscreen mode Exit fullscreen mode

This will automatically install the necessary dependencies and also perform the necessary configurations, such as adding the registration of the different Schematics used in the 'schematicCollections' property in 'angular.json', among other adjustments.

angular-eslint/schematics

But let's see what changes were made; let's analyze in detail the modifications made to the files.

.eslintrc.json: This file contains the rules of the linter that we will use to check if the code complies with the established rules, and if not, provide us with feedback about the errors that have occurred.

By default, the .eslintrc.json file is located in the root directory of the project and contains the default configuration.



{
  "root": true,
  "ignorePatterns": ["projects/**/*"],
  "overrides": [
    {
      "files": ["*.ts"],
      "parserOptions": {
        "project": ["tsconfig.json"],
        "createDefaultProgram": true
      },
      "extends": [
        "plugin:@angular-eslint/recommended",
        "plugin:@angular-eslint/template/process-inline-templates"
      ],
      "rules": {
        "@angular-eslint/directive-selector": [
          "error",
          {
            "type": "attribute",
            "prefix": "app",
            "style": "camelCase"
          }
        ],
        "@angular-eslint/component-selector": [
          "error",
          {
            "type": "element",
            "prefix": "app",
            "style": "kebab-case"
          }
        ]
      }
    },
    {
      "files": ["*.html"],
      "extends": ["plugin:@angular-eslint/template/recommended"],
      "rules": {}
    }
  ]
}


Enter fullscreen mode Exit fullscreen mode

angular.json: This file contains the configuration of the Angular application. It is automatically modified to add the registration of the schematics collections and information about the schematics we just installed.

angular.json

package.json: A new script called ng lint was added to execute the Angular linter, along with the update of dependencies.

package.json

With all the changes in place, we can proceed with the next steps.


3. Install Prettier

To perform code error correction, we'll install Prettier as a development dependency in our project. To do this, we'll use the following command:

(Feel free to use your preferred package manager. In this case, and throughout the rest of the post, we'll use npm as the package manager.)



npm install --save-dev prettier


Enter fullscreen mode Exit fullscreen mode

4. Configure Prettier

Let's configure Prettier to perform code error correction. To do this, we'll create a file named .prettierrc in the root of the project directory, and we'll add the following suggested configuration:



{
  "printWidth": 100,
  "tabWidth": 2,
  "tabs": false,
  "singleQuote": true,
  "semicolon": true,
  "quoteProps": "preserve",
  "bracketSpacing": true
}


Enter fullscreen mode Exit fullscreen mode

printWidth: Defines the maximum line width before Prettier will break lines automatically to keep the code within this limit.

tabWidth: Sets the width of a tab, i.e., how many spaces a tab represents.

tabs: A boolean indicating whether tabs should be used instead of spaces..

singleQuote: A boolean specifying whether single quotes should be used instead of double quotes for strings..

semicolon: A boolean indicating whether semicolons should be included at the end of statements.

quoteProps: Defines how Prettier will handle quotes around object property names. In this case, 'preserve' means it will keep the quotes if they are needed for backward compatibility.

bracketSpacing: A boolean indicating whether there should be a space after opening parentheses and before closing parentheses in object literals.


.prettierignore Configuration:

Now we'll create a file in the root of the project called .prettierignore and add the following configuration:



package.json
package-lock.json
yarn.lock
node_modules
dist


Enter fullscreen mode Exit fullscreen mode

5. Install Pretty Quick

Pretty Quick is a tool that combines two popular JavaScript tools: Prettier and ESLint, to format and lint your code efficiently. Prettier takes care of automatically formatting the code, while ESLint is used to perform static code analysis for errors or unwanted practices.

Pretty Quick simplifies the code formatting and linting process by running both tools in parallel. This means you can format and lint your code with a single command or easily integrate it into your development workflow.

Additionally, we only want Prettier to perform error correction on our modified files, instead of ESLint correcting errors in all files of the project. That's why Pretty Quick will also analyze only the modified files in our project. To achieve this, we need to execute the following command to install Pretty Quick as a development dependency in our project:



npm install --save-dev pretty-quick


Enter fullscreen mode Exit fullscreen mode

Once Pretty Quick is installed, we'll add a new script in the package.json file, which will be responsible for correcting errors only in the files that have been staged for commit in Git, using the --staged flag.



{
  "scripts": {
    "pretty-quick": "pretty-quick --staged"
  }
}


Enter fullscreen mode Exit fullscreen mode

6. Install Husky

Alright, now we can finally proceed with installing Husky.
To do this, we need to follow the documentation and execute the following command:



 npx husky-init && npm install


Enter fullscreen mode Exit fullscreen mode

This will create a new directory in the root of the project called .husky, along with all the necessary files for the husky command to work.

By default, inside this folder, you will find a file named pre-commit with the following content:



#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm test


Enter fullscreen mode Exit fullscreen mode

You replace npm test with the command you want to execute. In this case, you replace it with npm run pretty-quick.



#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run pretty-quick


Enter fullscreen mode Exit fullscreen mode

Remember, this command was added to the package.json file in step #2.

Now, we'll add a new file inside the same .husky folder called commit-msg with the following content:



#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run lint


Enter fullscreen mode Exit fullscreen mode

Note: If you're running unit tests in your project, you could add a new file in the same .husky folder called pre-push with the following content:



#!/usr/bin/env sh
. "$(dirname -- "$0")/_/husky.sh"

npm run test


Enter fullscreen mode Exit fullscreen mode

to run unit tests before pushing to the remote branch of your repository where you're working.

For this simple example, we will only use the files .husky/pre-commit and .husky/commit-msg.


7.Testing Prettier + ESLint + Husky

Now that we have the project set up to run pre-commit and commit-msg commands, let's test that everything works correctly.

To do this, let's introduce an error in our application. We'll go to the app.component.html file and modify it as follows:



<h1>Angular 14 + Prettier + Husky</h1>

<div>
  <span> Este es un 



texto que NO debe Ser                                      Valido Para                               Nuestro 



Linter Prettier </span>
</div>


Enter fullscreen mode Exit fullscreen mode

and in the app.component.ts file, we will implement the OnInit lifecycle hook, but we'll leave the content of the lifecycle hook empty so that the linter indicates it as an error.

error-commit

Alright, now it's time to test that everything works correctly. With Husky configured and using the pre-commit and commit-msg hooks, we'll execute the following commands:

  1. We'll add the files to the Git staging area:


git add .


Enter fullscreen mode Exit fullscreen mode

This will allow us to confirm that all files have been staged for commit by Husky.

  1. We'll make the commit:


git commit -m "feat: Added Setup Prettier + ESLint + Husky"


Enter fullscreen mode Exit fullscreen mode

This will format the code according to the rules established in the .prettierrc and .eslintrc.json files. Therefore, the HTML will be validated by Prettier and the .eslintrc.json file by ESLint, resulting in:



<h1>Angular 14 + Prettier + Husky</h1>

<div>
  <span> Este es un texto que NO debe Ser Valido Para Nuestro Linter Prettier </span>
</div>


Enter fullscreen mode Exit fullscreen mode

However, when trying to commit with an error that we intentionally caused for testing purposes, the commit is not completed, and it indicates that the error occurred due to the correction of errors by Prettier and ESLint.

PrettierEslintLinter

This personally seems incredible to me!

Now we proceed to fix the errors.

fix-errors

We will try to create the commit again:

success

And in this case, the commit has been successfully completed, as the error correction has been performed properly, and the code complies with the established linter rules.

Conclusion

Prettier + ESLint + Husky + Git + Git Hooks is a solution to automatically correct errors in an Angular 14 project. In addition to being an alternative to improve/detect error correction manually, these tools, like many others, are just a tool to detect the fire, not extinguish it. Therefore, despite being a great asset for our projects, we must not forget how important and careful we must be when creating incredible solutions/projects, whether they are personal or intended to help others.

Top comments (5)

Collapse
 
davidanibalfernandez profile image
davidanibalfernandez

is working nice to this moment

Collapse
 
xansiety profile image
Fernando

hey david, I really appreciate your comment!

Collapse
 
davidanibalfernandez profile image
davidanibalfernandez

i did it in angular 18.2.2. the only change was the husky version in 9.0. using the husky doc was enough

Collapse
 
jangelodev profile image
JoĆ£o Angelo

Hi Fernando,
Your tips are very useful
Thanks for sharing

Collapse
 
xansiety profile image
Fernando

Thank you so much for giving me a few minutes of your time, reading and commenting!