DEV Community

Ajith Kumar P M
Ajith Kumar P M

Posted on • Edited on

How to Add Pre/post-Commit Hooks to Your Node.js Project

As the project grows larger it's critical for the whole team to follow certain code quality and security standards. One way to ensure that is by using "git hooks".

Git hooks are scripts that run automatically every time a particular event occurs in a Git repository.

Numerous git hook managers are available for Node.js. Husky, pre-commit, and Lefthook are a few examples of such tools. We opted for Lefthook for this tutorial due to its capability to execute scripts concurrently and its simplicity.

So let's start!

Before each commit(pre-commit) we need to ensure the following.

  • No credentials leak: To ensure no secrets are accidentally exposed in the source.
  • No lint errors: The committed code does not contain any lint errors (eslint).
  • No formatting inconsistencies: The committed code should follow the organization's code formatting standards(prettier or pretty-quick).
  • No type errors: There shouldn't be any typescript errors.

And on each pre-push we need to ensure the following

  • No vulnerable packages: npm audit or pnpm audit --audit-level high
  • Standardized branch-names: we can usevalidate-branch-name

Apart from these we also need to enforce standards for all our commit messages(commit-lint).

GitLeaks

install gitleaks in your machine gitleaks

add the following changes to your package.json

{
   "scripts":{
+      "gitleaks": "gitleaks detect -v"
    }

}
Enter fullscreen mode Exit fullscreen mode

Eslint

install and configure eslint with

npm init @eslint/config
Enter fullscreen mode Exit fullscreen mode

add the following changes to your package.json

{
   "scripts":{
+      "lint": "eslint --ignore-path .gitignore \"{src,tests}/**/*.+(ts|js|tsx)\"",
    }

}
Enter fullscreen mode Exit fullscreen mode

Typecheck

{
   "scripts":{
+      "typecheck": "tsc --noEmit",
    }

}
Enter fullscreen mode Exit fullscreen mode

Prettier for code formatting

npm install --save-dev --save-exact prettier
Enter fullscreen mode Exit fullscreen mode

Package.json

{
   "scripts":{
+      "format": "prettier --ignore-path .prettierignore --write \"**/*.+(js|ts|json|tsx|mdx)\" --log-level silent",
    }

}
Enter fullscreen mode Exit fullscreen mode

Branch name validations

npm i validate-branch-name -D
Enter fullscreen mode Exit fullscreen mode

Package.json

{
   "validate-branch-name": {
        "pattern": "^(feat|fix|hotfix|release|test|experimental)/.+$",
        "errorMsg": "Branch name validation failed"
    },

}
Enter fullscreen mode Exit fullscreen mode

Commit lint for standardized commit messages

npm i @commitlint/cli -D
npm i @commitlint/config-conventional -D
Enter fullscreen mode Exit fullscreen mode

create the file commitlint.config.js at the root

module.exports = {
    extends: ['@commitlint/config-conventional'], // => @commitlint/config-conventional
};
Enter fullscreen mode Exit fullscreen mode

create the file .lefthook/commit-msg/commitlint.sh

echo $(head -n1 $1) | npx commitlint --color
Enter fullscreen mode Exit fullscreen mode

Lefthook as githooks manager

// install lefthook
npm install lefthook --save-dev
Enter fullscreen mode Exit fullscreen mode
# create a lefthook.yml file in the root
pre-commit:
  parallel: true
  commands:
    lint:
      glob: '*.{js,ts,jsx,tsx}' # glob filter for list of files
      run: npm run lint
    format:
      run: npm run format 
    types:
      glob: '*.{js,ts, jsx, tsx}'
      run: npm run typecheck
    gitLeaks:
      run: npm run gitleaks
pre-push:
  parallel: true
  commands:
    branchName:
      run: npx validate-branch-name
    packages-audit:
      tags: frontend security
      run: npm audit
commit-msg:
  parallel: true
  scripts:
    "commitlint.sh":
      runner: bash
Enter fullscreen mode Exit fullscreen mode

package.json

{
   "scripts":{
+     "prepare": "lefthook install",
    }
}
Enter fullscreen mode Exit fullscreen mode

Run lefthook install and try making your first commit.

Top comments (1)

Collapse
 
bakti_menanga_09ae0d81332 profile image
Bakti Menanga

Can you share full source code in git or GitLab?