Execute script after package installation - node.js

Now, I there is postinstall to run a script after
npm install
However, I am looking for a way to run a script after installing a single package
npm install jquery --save
Is this possible? If so, does this work on Windows and is there a way to get the name of the installed package (jquery in the given example)?

I'm don't see this on the package.json features.
It is therefore possible to do in the prestart for instance but jquery won't be in the devDependencies that way:
{
...
"devDependencies": {
"bower": "1.3.x",
"uglifyjs": "2.4.10",
... your other dependencies
},
"scripts": {
"prestart": "npm install jquery##.#.# ; <yourcommand> ; npm install",
...
}
}

Related

npm-force-resolutions not working when installing a new package

I'm using the scripts section of the package.json to force resolutions:
"preinstall": "npx npm-force-resolutions"
in the resolutions section, I have entered graceful-fs with a specified version:
"resolutions": {
"graceful-fs": "^4.2.4",
},
When i run npm i everything is installed correctly, the set versions are taken in to account. But later on when I install an additional module, e.g. npm i random-package, my set versions are being thrown away and I endup with graceful-fs#1.2.3 and other low versions in some dependencies.
If I clear the node_modules folder and run npm i again, everything is alright again.
I also tried setting the resolution more specific, like
"resolutions": {
"glob/**/graceful-fs": "^4.2.4",
},
but this doesn't help.
I also tried:
adding the module as dependency, devDependency or peerDependency
using a shrinkwrap and overriding it there
but no luck.
what am I missing?
The best solution for me to automate this was modifying preinstall script as above:
"preinstall": "npm install --package-lock-only --ignore-scripts && npx npm-force-resolutions",
Best way is to change the preinstall script to this:
"preinstall": "([ ! -f package-lock.json ] && npm install --package-lock-only --ignore-scripts --no-audit); npx npm-force-resolutions"
This will only run npm install to create your initial package-lock.json when it does not exist yet.
This is much faster than always running both (npm + npx).
As of npm 8.3.0, you can also use npm's override:
{
"overrides": {
"graceful-fs": "^4.2.4"
}
}
in the resolutions section, you must fix version
"resolutions": {
"graceful-fs": "4.2.4",
},
Hi #NthDegree the only way which worked for me was to first run the normal npm install and then add the packages-lock.json file to git. After doing that when you add "preinstall": "npx npm-force-resolutions", it always updates the dependency resolution to the version mentioned.
I am not sure if adding packages-lock.json file to git is good or bad but by using this method the CI/CD pipeline works as well.
If all of the above answers don't work and you still get sh: npm-force-resolutions: command not found
try the following:
Just change:
"preinstall": "npx npm-force-resolutions"
To:
"preinstall": "npx force-resolutions"
npx force-resolutions does not run when no package-lock.json is detected, and allows the next command inline to be executed as normal
Credit to: https://github.com/rogeriochaves/npm-force-resolutions/issues/10#issuecomment-885458937

running 'npm install' from shell also runs the 'prepublish' script

This is a SSCCE.
Given the following package.json file:
{
"name": "foo",
"version": "1.0.0",
"description": "",
"scripts": {
"prepublish": "echo \"pre-publish script called\""
},
"devDependencies": {
},
"dependencies": {
"lodash": "^4.10.0"
}
}
Running: npm install from the shell, results in the prepublish script also being executed:
$ npm install
> foo#1.0.0 prepublish /tmp/so
> echo "pre-publish script called"
pre-publish script called
npm WARN foo#1.0.0 No description
npm WARN foo#1.0.0 No repository field.
npm WARN foo#1.0.0 No license field.
If the prepublish script gets renamed to e.g. prepublis it is no longer executed with npm install. Problem is, I need the prepublish script as I typically perform static type analysis and Mocha tests prior to publishing to npm.
Is this a bug or a feature and how do I get around it? There should be no need to run my Mocha tests when I simply wish to install the package.json dependencies.
My environment is:
$ npm --version && node --version
3.9.5
v6.2.2
As I said it's not a bug (although everyone wants this functionality to be fixed), but there is a solution. Check out https://www.npmjs.com/package/in-publish to help with this very situation.
Solution summary
(from the in-publish package page)
npm install --save in-publish
Then in package.json:
"scripts": {
"prepublish": "in-publish && thing-I-dont-want-on-dev-install || not-in-publish"
}
You can also use not-in-install and in-install instead of in-publish
"scripts": {
"prepublish": "not-in-install && thing-I-dont-want-on-dev-install || in-install"
}

NPM install doesn't trigger babel build if dependencies not coming from NPM

For example, if in my package.json, i have this:
"dependencies": {
"cacheman": "2.1.0" }
it works and it will trigger the building script inside cacheman when I do npm install.
however, if i do this:
"dependencies": {
"cacheman": "https://github.com/cayasso/cacheman.git" }
it won't work. npm install will not trigger the build process for cacheman.
why is that?
The script you are referring is pre-publish script which runs before publishing the npm module to npm registry. Check here package.json#L9
Extract shown here
"scripts": {
"test": "make test",
"prepublish": "make"
}
When you install it from github there is no publish step so the script is not run.
If you want to install from github only and have the script run, you can add it as postinstall script of cacheman (you will have to fork the repo to make changes if you are not owner of cacheman).
"scripts": {
"test": "make test",
"prepublish": "make",
"postinstall": "make"//Added postinstall
}
Check examples in npm scripts documentation for more details.

How to run `npm install && bower install` before `sbt compile` for Heroku Deployment?

I am working on a Playframework project which has front-end codes in sub-directory ./ui and managed by Grunt using https://github.com/tuplejump/play-yeoman
Currently I used https://github.com/heroku/heroku-buildpack-multi and set
https://github.com/heroku/heroku-buildpack-nodejs.git
https://github.com/heroku/heroku-buildpack-scala.git
in the .buildpacks file.
And set
{
"name": "scala-grunt",
"dependencies": {
"grunt-cli": "0.1.13"
},
"devDependencies": {
"grunt": "~0.4.5"
},
"version": "0.1.0",
"engines": {
"node": "~0.10.21"
}
}
in the package.json file of root directory.
However, when I pushed the code base to heroku it will throw an exception Fatal error: Unable to find local grunt. I think that is because sbt doesn't to run npm install && bower install in the ./ui directory.
Does anyone have ideas about how to run a command npm install && bower install before sbt compile in heroku?
Check out https://docs.npmjs.com/misc/scripts. There are a couple keywords you can use to run bower and grunt at different times. Check out the preinstall and postinstall keyword.
For an example, here is my script section from my package.json file that I use a lot.
"scripts": {
"start": "node lib/app.js",
"postinstall": "bower install --allow-root",
"test": "grunt"
}
This command solved for me:
heroku buildpacks:set https://github.com/heroku/heroku-buildpack-multi.git

How can I invoke npm on heroku command line (to install bower components)?

Bower is for client side Javascript what npm is for the server side and reads a component.json file to recognize dependencies that should be fetched at deploy time so I'd be happy it heroku would run it at slug compilation time.
Unfortunately I can not invoke npm or bower from a heroku console or one-off command (heroku run "npm help") (heroku run bash -> npm help) as it's possible with ruby's rake. I've put npm and node (latest/x versions) in my package.json but in the engines section, not the dependencies.
I think this could be solved by customizing the node buildpack but I consider this a little too heavy task just for activating something so obvious.
You can also setup a postintall command, something like this in your package.json
"dependencies": {
"bower": "0.6.x"
},
"scripts": {
"postinstall": "./node_modules/bower/bin/bower install"
}
Then npm install will also install bower dependencies.
Pros : one command to rule them all.
Cons : you unnecessarily embed bower as a dependency.
You can use run like this:
heroku run npm install git://github.com/webjay/kaiseki
You should declare NPM dependencies in the package.json file
All you install from shell will be deleted on exit shell. You are in a cloned instance.
You can use bower directly like this
"dependencies": {
"bower": "^1.7.9"
},
"scripts": {
"postinstall": "sudo bower install --allow-root "
}

Resources