TL;DR: Is there a way to have npm install
run automatically before running any npm script if your package.json
has been modified?
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.
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.
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
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?
npm ci will install packages based on package-lock. json file and if the file does not exist or does not match the packages specified in the package. json it will throw an error and fail.
I found that npm init had automatically added dependencies based on installed packages and that there was no need to run the second command.
By default, npm install will install all modules listed as dependencies in package. json .
You can add dependencies to a package. json file from the command line or by manually editing the package.
Okay so I'm done with the package. Here it is. You can use it exactly the same way you specified in your ideal scenario. Just npm install install-changed
and add it to a custom script, like pre-run
in your example. It should figure out whether or not it needs to npm install
and does so if it needs to.
{ "scripts": { "pre-run": "install-changed", "my-script": "…" },
You can also do this programatically but I don't think you're going to need this.
let installChanged = require('install-changed') let isModified = installChanged.watchPackage()
The function above does exactly the same thing, additonally it also returns a boolean value which you might find useful.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With