Installing NPM packages with child_process
- Node.js Version: 12.17.0
- OS: Windows 10
- Scope (install, code, runtime, meta, other?): Code
- Module (and version) (if relevant): Child_Process
I made a function to ensure that NPM packages are installed. If a package isn't installed, I use child_process to install it.
const childProcess = require("child_process");
function ensureDependencies(dependencies) {
return new Promise((res) => {
try {
for (let i of dependencies) {
require(i);
}
res();
} catch(e) {
childProcess.exec(`npm i -s ${dependencies.join(" ")}`, async () => {
res();
});
}
});
}
ensureDependencies(["discord.js", "express"]).then(() => {
const discord = require("discord.js");
const express = require("express");
});
When the packages are already installed, it just continues. When they aren't installed, child_process installs them, without any errors. But when I try to require them, I get a module not found error. When I stop my process and start it again, the packages are installed.
Is there any way to "refresh" the node_modules or whatever? I don't want to restart the process after child_process installed the dependencies.
I also tried deleting the cache, like this, after the child_process exec is compleat.
for (let i of dependencies) {
delete require.cache[require.resolve(i)];
}
That also doesn't work.
It's been almost two weeks. Is this a bug or am I doing something wrong?
Can you please share the error with something like this?
childProcess.exec(`npm i -s ${dependencies.join(" ")}`, async (error) => {
if(error) {
console.log('error is:' , error);
//or
throw error;
}
res();
});
I believe it would help the community to understand the source of your issue.
Another question: Have you considered using a package json file instead of joining all the dependencies in the command line? You might be hitting the limit of the command line arguments.
Hello. I don't get any errors, and the packages install just fine, but node can't find it until I stop and then start the process.
And yes, I thought of putting the packages in the package.json, but it's for a package that maybe require dependencies, bases on which parts you use. That's why I want to install the packages with child_process.
Ok, I've reconstructed the issue. It seems funny because I've dealt with module reloading in the past, but the module was never loaded so I believe this brings us to some kind of edge case.
const childp = require('child_process')
const {resolve} = require('path')
const package = 'rimraf'
try {
const found = require(package)
console.log('found', found)
} catch (e) {
childp.execSync(`npm i ${package}`)
console.log('installed')
}
console.log('require.cache:', require.cache[package]) // undefined
console.log(require.resolve(package, {paths: [resolve(__dirname, 'node_modules')]})) //💥 shoule be regular require goes 💥
Edit: For those looking to help here when running the script do something along the lines of rm -rf node_modules; node [script_name]
You're trying to do the same as https://github.com/nodejs/node/issues/31803, which AFAIK is not currently possible due to the internal caching.
The strange thing is that it works sometimes, but other times it doesn't work. Is there a way to clear the internal caching or something like that?
It doesn't seem to be about the cache. npm install spawned in child process appeared not to actually install any packages into node_modules, nor updating package.json
We encountered the same situation, the following example can reproduce the problem.
const { execSync } = require('child_process');
function resolveSilent(id) {
try {
return require.resolve(id);
} catch (e) {
return undefined;
}
}
const pkgName = 'add';
const resolveBefore = resolveSilent(pkgName);
console.log('Resolve before: ', resolveBefore);
if (!resolveBefore) {
const stdout = execSync(`npm i -D ${pkgName}`, { encoding: 'utf8' });
console.log('stdout: ', stdout);
console.log('Resolve after: ', resolveSilent(pkgName));
}
I tried the same but with dynamic imports and arrived to the same problem. Has anybody found a way to deal with the cache before attempting the 2nd import/require?
It seems there has been no activity on this issue for a while, and it is being closed in 30 days. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.
It seems there has been no activity on this issue for a while, and it is being closed. If you believe this issue should remain open, please leave a comment. If you need further assistance or have questions, you can also search for similar issues on Stack Overflow. Make sure to look at the README file for the most updated links.