How to make a script run when using NPM commands?

Viewed 1114

Trying to bind a script called license-checker to npm commands following these instructions I came up with this snippet in my package.json

{
  "scripts": {
    "postinstall": "license-checker --json --out license-list.json",
    "poststart": "license-checker --json --out license-list.json"
  },

Doesn't work. Running the command manually does generate the licence-list.json file, but not when installing a package (npm i package-name --save). Why not?

Note: I'm trying to run this script when (1) installing a new package into the project, and also when (2) building the project for deployment. However there's nothing about build in the docs: can I use start or poststart for that as I tried to or if not, what can I use instead?

3 Answers

As per the npm documentation (https://docs.npmjs.com/misc/scripts), the postinstall script is invoked when the package is installed so the postinstall script will invoke when you call

npm install

It won't be called when you invoke

npm i package-name --save

Maybe you can do the check once the package is installed.

Edit: If the purpose of this is to check what is being added to package.json maybe doing a pre-commit check/hooks will be a better idea aka using something like https://www.npmjs.com/package/husky

You can try out hook-scripts.

From docs :

If you want to run a specific script at a specific lifecycle event for ALL packages, then you can use a hook script.

Place an executable file at node_modules/.hooks/{eventname}, and it’ll get run for all packages when they are going through that point in the package lifecycle for any packages installed in that root.

Hook scripts are run exactly the same way as package.json scripts. That is, they are in a separate child process, with the env described above.

Edit

Example:

I tried this on Windows 10, Node 12.18.0 and NPM 6.14.4

  1. I created a bat file at node_modules/.hooks/ having content:
call node -e "console.log('Hello, I got executed from .hooks folder.')"
  1. Then ran npm i ng-bootstrap --save

Hook script got executed. Check screenshot below. enter image description here

Note : As pointed by @RobC, This script will be executed for each of the transitive dependencies of the package being installed.

I dont tryed but, you can use a build script there you can use your commands by the way you aimed. by using the && operator. For example:

"build": "npm run compile && npm run theme:build && npm run webpack:admin",

In your case like that:

"postinstall": "license-checker --json --out license-list.json",
"poststart": "license-checker --json --out license-list.json"
"build": "npm run poststart && npm run postinstall && npm run newpocket -save",

this is not exactly what you wanted but a manner for making it.

Related