Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Running npm `postinstall` script after the original `npm install` finishes? (Maybe by using a Node trick?)

Tags:

I'm trying to create an npm module that has a postinstall script that will modify the user's package.json and re-install packages. I'm almost there, but the problem I'm having is that the npm CLI runs my postinstall script too early.

Is there a way, maybe by using Node or system level trick, to wait for the whole npm install process to exit before my script runs? Like when npm calls my postinstall script, at that time I can register another script to run after npm install finishes?

What do I mean by "too early"? For example, after yarn install, the yarn.lock file will not accurately reflect the package.json if my script interferes with yarn install. However, if my script waits for yarn install to completely finish and then runs another yarn install, the yarn.lock file will be accurate and further yarn install commands will output "Already up-to-date".

like image 499
M.K. Safi Avatar asked May 09 '17 00:05

M.K. Safi


People also ask

How do I run a script after NPM install?

You can easily run scripts using npm by adding them to the "scripts" field in package. json and run them with npm run <script-name> . Run npm run to see available scripts. Binaries of locally install packages are made available in the PATH , so you can run them by name instead of pointing to node_modules/.

Where is the postInstall script?

The working directory for the postInstall script is / (root), which means if you include a command like mkdir mylibrary to create a folder, when you later need to refer to that folder, it'll be available at /mylibrary .

What is postInstall?

The postinstall script creates the backout package using the information provided by the other scripts. Since the pkgmk and pkgtrans commands do not require the package database, they can be executed within a package installation.


1 Answers

Considering tampering directly with the package.json is bad practice, because Devs will no longer be in control of the packages they have installed, or even their project name.

Therefore, packages should instead request the Dev to change the package.json during installation and offer a method to enable Devs for a dry-run of the changes that will be made.

TLDR; make sure to give full consent to the Dev for any tampering of the package.json.

That's why I think alternative methods are better than using a postinstall script. The most minimal solution I have come up with:

myinstall.js

const exec = require('child_process').exec; exec('npm run install').on('exit', () => exec('npm run mypostinstall')); 

package.json

"scripts": {   "myinstall": "node myinstall.js",   "mypostinstall": "echo \"myPostinstall called\"" }, 

Set the mypostinstall script equal to the postinstall.

Note: in the example above there is no error handling, no text is displayed and there is no actual write to the package.json. It is pure for illustration on how to do execute code after npm install. The reason no text is being displayed is due calling exec, for which a new process is called with it's "personal" stdout. Alternatively use fork, more info can be found here at the node documentation.

I have attempted to call npm install instead of npm run myinstall by setting "install": "node myinstall.js". However now the exec('npm run install')will recursively call itself.

like image 85
jervtub Avatar answered Mar 04 '23 20:03

jervtub