TL;DR: Is there a way to have npm install
run automatically before running any npm script if your package.json
has been modified?
Problem Scenario
You pull or checkout a branch that updated package.json
. You run npm run my-script
. my-script
depends on a package that has newly been added to package.json
. my-script
fails. You wonder why. Before flipping over your desk you run npm install
just to be sure. my-script
runs successfully. You don't need a new desk.
I know that build / task runner tools like gradle
make sure that your dependencies are up-to-date before running a task. I has always been a (minor) pain point that npm
doesn't do it. I stumbled over two solutions that I don't particluarly like.
Non-Ideal Solution: make
Instead of relying on npm scripts in your package.json
to run commands you use make
and make use of its integrated dependency tracking with the following trick:
# Smart install: Only executes if package.json's
# modification date is later than node_module's
node_modules: package.json
npm install
@rm -f node_modules/.modified
@touch -m node_modules/.modified
install: node_modules
Source: https://mattandre.ws/2016/05/make-for-hipsters/
The problem is that you know have to rely on make
to run scripts and lose certain advantages of npm scripts such as conveniently referring to other scripts and running scripts in parallel (npm-run-all
). It's also harder to work with others if they don't know make
or have problems running it (Windows). It's an archaic tool outside of the node/npm ecosystem and too costly just for this smart install advantage.
Non-Ideal Solution: Git hook
Another way is to add a post-merge
git hook.
The problem is that this solution is local to the repository and can't be easily shared. npm install
will only be run automatically on git merges. When you change package.json
in any other way you still have to remember running npm install
. Admittedly, that's a minor point in practice. Nonetheless, it would be nice to never have to think about running npm install
at all when you want to run a script.
Source: https://davidwalsh.name/git-hook-npm-install-package-json-modified
Ideal Solution
I'd like to define my package.json
in a way similar to:
{
"scripts": {
"pre-run": "npm-smart-install",
"my-script": "…"
},
"dependencies": {
"npm-smart-install": "1.0.0"
}
}
npm-smart-install
is a hypothetical npm package that I wish existed. pre-run
is a hypothetical npm-scripts lifecycle hook. When I run npm run my-script
and package.json
has been modified since the last run of any script, run npm install
before running my-script
.
To repeat: Is there a way to have npm install
run automatically before running any npm script if your package.json
has been modified without relying on tools outside the npm ecosystem?
package.json
upon the first install and then use it in subsequent installs to check if the file changed. This looks like it does something similar. – Darnednpm install
before any script? If everything is there with the correct version then it won't do anything. – DarnedtmpDir
provided byfs
– Spangle