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.