I’ve previously written about using Make as a command interface for your repository and the other day, I ran into a situation where using Makefiles takes away a real-life annoyance for teams working on NodeJS and other Javascript or TypeScript based projects.
When growing teams work in repositories that use NPM for Yarn for package management, dependency updates will enter the local workspace frequently when the main branch is pulled. Unless you’re religious about running npm install
after every git pull
, updating local dependencies of often omitted and sometimes leads to confusing red herring bugs or in the very least, lost time.
Soon after starting my current job, I introduced Makefiles in our repositories to automate build tasks and starting dependent services like Postgres and Redis containers before bringing up our application server. This put us in a good position to apply a small trick that puts the package dependency problem behind us and automates npm install execution.
The trick involves a “sentinel” target, named for the sentinel file it creates after performing its task which in this case is; running npm install
.
.npm-install.sentinel: package.json package-lock.json
@npm install
@touch .npm-install.sentinel
The .npm-install.sentinel
target depends on package.json
and package-lock.json
(Yarn users would use yarn.lock
instead), meaning that the target only runs if no file named .npm-install.sentinel
exists or if it is older than either package.json
or package-lock.json
, which triggers automatic execution of npm install
when needed.
The next step is to add .npm-install.sentinel
as a prerequisite on all targets that require up-to-date npm dependencies. For example:
start-dev-server: start-db-and-redis .npm-install.sentinel
@npx nodemon
In addition to requiring local services to be started, the added prerequisite will ensure npm install
will be executed (if needed) before nodemon starts the server.
If a local repository update brings in an updated package-lock.json
file, running any make target that depends on .npm-install.sentinel
will trigger a dependency update without you ever having to think about it again.
It’s a small trick, but maybe it’ll help you save your team some time and annoyance. Enjoy.