Deno Projects: Linting + Formatting + Conventional Commits
This is the second of three articles illustrating how to set up a git automation for linting, and formatting files and for composing commit messages with conventional commits.
In the first article we implented the workflow within a node project. Here, we're going to recreate the same workflow but within a deno project.
The steps are pretty similar to those in the previous article, so we're going to wiz through, only drawing attention to the deno-specific differences.
Is there a video I can watch or a repo I can clone?
No video just yet, but here's a link to a demo repo that can be cloned.
What are we building?
We're going to create an automation that kicks in when we git commit
. This automation will use deno to type-check, lint and format staged files, and then it will use gitmoji-cli to help format commits with emojis and conventional commit syntax. If you're allergic to emojis and still want conventional commits, try out commitizen which is a great alternative!
What are the steps?
We'll initialise a deno project with git. We'll install and configure lint-staged and git and that's pretty much all there is to it. Let's begin!
Step 1 - Initialise the project
deno init && git init
In your terminal, create a new directory for your project and cd
into it. Use the deno init && git init
command to initialise a new deno project with git in the current directory.
Step 2 - Install Dependencies
Deno's pretty awesome and it gives us the following out of the box:
All we need to do is install the missing parts of our workflow which is lint-staged.
deno add -D npm:lint-staged
The above command uses deno to install lint-staged from the npm package registry. We'll then see it listed in the imports section within the deno.json
file. Read more about how deno handles 3rd party modules here.
Step 2 - Configure Lint-Staged
const config = {"*.{cjs,mjs,js,ts,jsx,tsx}": (stagedFiles) => [`deno lint ${stagedFiles.join(" ")}`,`deno fmt ${stagedFiles.join(" ")}`,],"*.{css,md,mdx,json}": (stagedFiles) => [`deno fmt ${stagedFiles.join(" ")}`],};export default config;
We'll create our lint-staged configuration file as above at the root of our project. It's really similar to the node-based config file that we created in the previous article. The major difference here though is that we're executing the linting and formatting using the built-in deno commands.
We're using deno's default linting and formatting rules in this example which can be customised within the deno.json file by following the docs.
Step 3 - Configure Git
We're not using husky here as we did in the last article as it's is primarily designed with the structure of a node project in mind. Instead, we're going to use git's native core.hooksPath configuration property which can be used to redefine where hooks are stored. The core.hooksPath
property was introduced with git v2.9.5
with the current release being v2.48.1
. If a more husky-like experience is preferred, please take a look at the deno-hooks library which is inspired by husky (and also uses core.hooksPath under the hood).
First we'll create a directory to store our hooks:
mkdir git-hooks
Then we'll add a new pre-commit
hook script into the directory:
#!/usr/bin/env shdeno check .deno run -A npm:lint-staged
Next we'll add a new task to our deno.json:
{"tasks": {"prepare": "git config --local core.hooksPath git-hooks && cd git-hooks && chmod +x *"}}
And finally, we'll run the prepare
task to update our project's git configuration with the location of our git-hooks directory, and to make all files within the directory executable.
deno task prepare
We now have a pre-commit
hook setup in the repo which will use deno to type-check the whole project, and lint-staged to initiate deno's linting and formatting commands on staged files prior to inputting the commit message.
Step 4 - Configure Gitmoji (optional)
Let's first install gitmoji-cli:
deno add -D npm:gitmoji-cli
Then, let's create our prepare-commit-msg
hook:
#!/usr/bin/env shexec < /dev/ttydeno run -A npm:gitmoji-cli --hook $1 $2
Finally let's run deno task prepare
to make sure all the hook scripts are executable and git is configured correctly.
That's the last setup step completed!
Is That It? Are We Done?
Yes we're done! As with the node setup, we can go ahead and develop as normal and every time we commit our staged files, this automation will kick in!
Super Important - Read This or Everything Will Explode!
It's important to note that when we clone a project down which contains this configuration, we'll need to manually run the prepare task in order for the git directory to be configured to use our hooks. This can be done by chaining the task onto the install command:
deno install && deno task prepare
I hope this has helped and inspired you to learn more about deno and to share your enthusiasm for building with code!