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?