Introduction
When creating Laravel+Livewire projects, especially for teams, pre-commit hooks come in handy by ensuring everyone on the team follows the same formatting standards and adheres to some level of code quality. In this blog-post we will use:
- husky: Sets up pre-commit hooks
- prettier: To format
*.css
,*.js
and*.blade
files. - @shufo/prettier-plugin-blade: A prettier plugin for formatting
*blade
files - laravel/pint: to format PHP files like classes, traits, etc.
- larastan: does PHP static analysis.
Installation
Assuming you are creating a project from scratch, let us begin the set-up.
Create a new project, I will name mine
livewire-precommits-demo
:$ composer create-project laravel/laravel livewire-precommits-demo
Open the project, initialize git and make the first commit:
$ cd livewire-precommits-demo $ git init $ git add -A $ git commit -m "First of many"
Install
husky
,prettier
, and@shufo/prettier-plugin-blade
as dev dependencies:$ npm i -D husky prettier @shufo/prettier-plugin-blade
Add Laravel Pint:
$ composer require laravel/pint --dev
To test it out in action:
$ ./vendor/bin/pint
Install Larastan:
$ composer require larastan/larastan:^2.0 --dev
Create a
phpstan.neon
file in the root of the project with this:includes: - vendor/larastan/larastan/extension.neon parameters: paths: - app/ # Level 9 is the highest level level: 5 # ignoreErrors: # - '#PHPDoc tag @var#' # # excludePaths: # - ./*/*/FileToBeExcluded.php # # checkMissingIterableValueType: false
To test if it works:
$ ./vendor/bin/phpstan analyse
We have installed everything we need, now we can create a commit to track these changes:
$ git add -A && git commit -m "Added linting and formatting packages"
Set Up Pre-Commit Hook
We have all the packages needed for static analysis and code formatting so now let us create a pre-commit hook that runs them before every commit:
First we should install husky’s Git hooks
$ npx husky install
Create a file under the
.husky
directory calledpre-commit
, in full (.husky/pre-commit
), and add the following content:#!/usr/bin/env sh . "$(dirname -- "$0")/_/husky.sh" # Format resources # https://stackoverflow.com/a/6879568 # https://stackoverflow.com/a/1587952 ./node_modules/.bin/prettier --ignore-unknown --write $(git diff --name-only --diff-filter=ACMR HEAD -- '*.blade.php') ./node_modules/.bin/prettier resources/**/*.js resources/**/*.css --write # Format php classes ./vendor/bin/pint && git add -A # Do static analysis ./vendor/bin/phpstan analyse --memory-limit=2G
Let us break down this command:
/node_modules/.bin/prettier --ignore-unknown --write $(git diff --name-only --diff-filter=ACMR HEAD -- '*.blade.php')
--ignore-unknown
prevents the command from returning a non-zero result if no match is found in our filter--write
tells prettier to write the formatting changes to the respective files--diff-filter=ACMR HEAD
matches files that have either been Added, Copied, Modified, or Renamed.HEAD
adds to this filter by matching files that have gone through either of the aforementioned changes, whether they have been stagged for commit or not. If this is not the desired behaviour this resource should come in handy
Make the
.husky/pre-commit
executable:$ chmod +x .husky/pre-commit
Now when we do a commit, the pre-commit hook should run
Commit our changes:
$ git add -A $ git commit -m "Added pre-commit hook"
Congratulations! Now linting and static analysis is done before every commit. There’s one more thing we can do to help new team members install the pre-commit hook:
Update
package.json
and the following script. It runs right after one runsnpm install
:{ "scripts": { ... "prepare": "husky install && git add .husky/pre-commit" } }
Now an
npm install
should trigger the installation of the pre-commit hooks, or one can just runnpm run prepare
.