Locate the package.json file from the npm script that executes on preinstallation

So I need to read package.json before installing a new package through npm.

Why read package.json in the first place?

I use npm for CSS components that are individually versioned and may have interdependencies. (Javascript not delivered)

Finding Version Conflicts for Multiple Dependencies I need to determine when package A requires package C@1.0.0 and package B requires package C@2.0.0 and handle it.

Npm (since version 3) addresses these issues by inserting a conflicting module deeper inside the tree. Now you get both versions of the same module. CSS has a global namespace, and mixin (in the case of Sasss) rewrites each other and breaks your CSS.

This flat dependency issue is nicely described on the npm blog: http://blog.npmjs.org/post/101775448305/npm-and-front-end-packaging

Without even considering our specific use case, it seems strange to me that you do not have access to package.json scripts in preinstall and postinstall . They seem to be just for this use case.

What i tried

My package.json package that I am installing is as follows:

 { "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script", }, "author": "TODO", "license": "MIT" } 

Inside this some-script package, I run:

 console.log( process.cwd() ); console.log( __dirname ); 

Then I run:

 ~/path/to/folder $ npm i testmodule 

This will lead to:

 $ npm i testmodule > testmodule@0.3.6 preinstall /path/to/folder/node_modules/.staging/testmodule-5cc9d333 > some-script /path/to/folder/node_modules/.staging/test-module-5cc9d333 /path/to/folder/node_modules/.staging/test-module-5cc9d333/node_modules/some-script 

Now I fully understand that I can’t access the root where npm i was running, because my script was executed by the npm subprocess and had a completely different root.

Then I thought that npm root should keep track of where the actual root was for me, and passed it as a parameter to my script from inside the package.json test module:

 { "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script \"$(npm root)\"", }, "author": "TODO", "license": "MIT" } 

Unfortunately, this also defaults to the intermediate path:

 /path/to/folder/node_modules/.staging/testmodule-5cc9d333/node_modules 

I registered a registry problem , but I did not hope that they could get to it in time. Also my script should work with older npm installations.

At the same time, I came up with something like this inside some-script :

 let pgkPath = process.cwd().split('/node_modules/')[0]; 

This will return /path/to/folder/ , which is correct, but makes the assumption that no one starts npm i inside a folder, by the way called node_modules ... It seems to be hacked.

Question

How can I access the path to package.json from inside an npm script that runs through preinstall? Does this seem to me not too outrageous to ask?

+8
source share
1 answer

I don't understand your use case completely, but to answer your specific question about finding the parent package.json from the preinstall script:

Pass $(cd .. && npm prefix) as an argument to your script, then load ./package.json .

npm prefix will return the closest parent directory containing the package.json file, which when called from the .. directory should return the parent path of the npm package.

 { "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script \"$(cd .. && npm prefix)\"", }, "author": "TODO", "license": "MIT" } 
+2
source share

All Articles