Skip to content

Linting files with Git pre commit hooks

Rob Knight edited this page Oct 2, 2022 · 3 revisions

Using git hooks with Husky and Lint-staged

(Note: These instructions are included here as a reference and will not be necessary if cloning the repo directly and running npm install, as the repo has already been configured to install this setup automatically. This reference is here should we ever need to set this up again.)

Using Husky and lint-staged, we can automatically lint our files when we make a commit. If our code is not up to snuff, we will not be able to commit until it's fixed. This will ensure we are all on the same page in terms of coding standards and Best Practices.

For WordPress development, we utilize the WordPress Coding Standards and have several scripts in our package.json that leverage its utility. Using Husky and lint-staged we can run linting scripts against staged files only. Additionally, popular linters like Prettier and ESLint can also be run against staged files.

Our repo uses Prettier in conjunction with @wordpress/prettier-config which enforces WordPress development standards with Prettier.

Add new dev dependencies and initialize

Let's add some new dev dependencies to our package.json.

npm install --save-dev husky lint-staged prettier @wordpress/perttier-config

Once these are installed we need to do some initializing and configuring.

husky-init

husky-init is a one-time command to quickly initialize a project with Husky. It will create a new .husky/ directory that will handle git hooks. This script has been added to the package.json file so that it will automatically run upon the npm install command; however, if not running npx husky-init will take care of this for you.

We will now create a pre-commit hook to interact with lint-staged. The command below will add the test script that we have previously defined in our package.json to the hook.

npx husky add .husky/pre-commit "npm test"
git add .husky/pre-commit && git commit -m "Adding husky pre-commit hook"

There should now be a new file in .husky/pre-commit that looks similar to this:

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

npm test

Once this hook is created, anytime a developer issues a git commit -m "my cool commit message" command, the pre-commit hook will run first. It can be configured to "fail" or to "fix." The current setup leans toward "fail." At this point it will run our dummy script npm test.

lint-staged setup

Lint-staged can be configured in a number of ways and in setting up this workflow, we explored several of them. For this example we're going to add a new file called lint-staged.config.js to the root of our project.

This new file is where we will define the scripts to be run on different file types when Husky calls lint-staged.

touch lint-staged.config.js

This will create an empty js file. Open it in your code editor and paste the code below:

module.exports = {
    '*.{css,scss}': 'npm run prettier:write',
    '*.js': 'npm run format',
    '*.php': 'composer lint-fix',
};

The lint-staged config file is used to run scripts on staged files. As described above, both package.json scripts and command line scripts can be run. In this example, css and scss files are run against a package.json script called prettier:write, which invokes the Prettier fix; the js files are run against the wp-scripts format script, which invokes javascript and yaml fix; and php files are run against a composer script that invokes PHPCodeSniffer fix.

Now, each time a developer issues a commit and associated message, the Husky hook will fire and run the lint-staged scripts on the staged files.

Again, depending upon the configuration of the scripts, they can be set to automatically fix errors and continue or to identify errors with a warning and fail, giving the developer the opportunity to fix them theirselves.