node.script query for installed packages
Hi,
is there a way to query node.script for installed NPM packages?
I tried to send the command `script npm ls -g` following this post on SO, but this does not seem to work.
Does anyone know how to do that simply (that is, preferably, without parsing node_modules folder files manually) ?
Is there a specific need to query globally installed packages? My hunch is that the command failed due to a permission issue given the -g
flag?
Hi Florian,
actually I am rather after local packages, though I guess it could be useful to have a way to query global ones too.
Are you saying that the command script npm ls
should work ?
I don't see that here, but I may be missing something ... all I have when I send this message is a dict like this:
{
"args" : [ "ls", "--scripts-prepend-node-path=true" ],
"status" : "completed"
}
Hi Vincent,
yeah ok I get it. I assumed you were having issues with the -g
which would fails bc the Node / NPM binaries do not have the permissions to access the globally installed packages, but as your patch shows, locally this works just fine.
I guess your FR is that npm
commands somehow output stdout
and stderr
, which is currently not exposed to the patch. I'll file that as a FR.
In the meantime - you could write a tiny wrapper script that uses child_process
and sets up the necessary communication via max-api
into your patch. Should work but depending on what you are trying to achieve it might be overkill? Do you just want to check if a certain package is installed or perform more complex tasks on the dependency tree returned by npm
?
Hi Florian,
Thanks, yes indeed, I wished the npm output would be exposed to the patch.
The general idea is to check for required packages and to run npm install
only if necessary on a patcher startup. Ideally, this would include package version checking.
Is there any easier way that I am missing for this purpose?
Hi Vincent,
ok makes sense. Would it make sense for you to include that as part of your script, rather than a separate npm
task?
If so there are a few options.
You can just try to
require
orimport
the package and wrap it with atry/catch
however, that won't give you any version informationrun
npm ls
from within your script usingchild_process
which allows you to capture, process the output and decide within the scope of your script what to do.
For the second you could do something like the following. Code is synchronous but can be adapted for async execution:
const { execSync } = require("child_process");
try {
execSync("npm ls --json", { cwd: __dirname, stdio: ["ignore", "pipe", "ignore"] });
// npm ls exited with a 0 exit code - should be all ok
} catch (err) {
// NPM failed with a non-zero exit code - err.status
// Given the --json flag the stdout of the error is in JSON format
const output = JSON.parse(err.stdout.toString("utf-8").trim());
// More info on the output is present in
// output.problems, which is an array of strings describing the issues
// output.error.summary which is a summary text of the issues present
console.error(output.error.summary);
}
As an aside - isnpm ci
might be a better match for your requirements where you'd like to ensure that the content of node_modules
matches and satisfies what's in the package-lock.json
?