So I need to read the package.json
before installing a new package via npm.
Why reading package.json in the first place?
Well I am looking for version conflicts for a bunch of dependencies. I need to detect when package A
requires package C@1.0.0
and package B
requires package C@2.0.0
and deal with it. The reason I do that for is because those packages contain CSS (which has a global namespace) and would just overwrite each other. This is for scoped private packages and not for wider use. It strikes me as odd that you don't have access to the package.json
in preinstall and postinstall scripts. They seem to be just for that use case.
What I tried
My package.json
of the package I'm installing looks like this:
{ "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script", }, "author": "TODO", "license": "MIT" }
Inside that some-script
package I run:
console.log( process.cwd() ); console.log( __dirname );
I then run:
~/path/to/folder $ npm i testmodule
This will result in:
$ 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 totally get that I can't really access the root of where npm i
was ran because my script was run by a subprocess of npm and has an entirely different root.
I then thought npm root
should keep track where the actual root was for me and passed that as a parameter to my script from inside the testmodule package.json:
{ "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script \"$(npm root)\"", }, "author": "TODO", "license": "MIT" }
Unfortunately that also defaults back to a staging path:
/path/to/folder/node_modules/.staging/testmodule-5cc9d333/node_modules
I filed an issue with the registry but not holding my hopes up for them to get to that in time. Also my script needs to work on older npm installations.
In the meantime I came up with something like that inside my some-script
:
let pgkPath = process.cwd().split('/node_modules/')[0];
That will return /path/to/folder/
which is correct but it makes the assumption no-one runs an npm i
inside a folder incidentally named node_modules
... Seems hacky.
Question
How can I access the path to the package.json from inside an npm script that is run via preinstall? To me that seems like something not too outrageous to ask for?
1 Answers
Answers 1
I don't understand your use-case entirely, but to answer your specific question of finding a parent package.json
from a preinstall script:
Pass $(cd .. && npm prefix)
as an argument to your script, then load ./package.json
.
npm prefix
will return the closest parent directory to contain a package.json
file, which when invoked from the ..
directory, should return the parent npm package's path.
{ "name": "testmodule", "version": "0.3.6", "description": "TODO", "scripts": { "preinstall": "npm i some-script && some-script \"$(cd .. && npm prefix)\"", }, "author": "TODO", "license": "MIT" }
0 comments:
Post a Comment