我可以从运行Node.js的JavaScript安装一个NPM包吗?

我可以从运行在Node.js中的JavaScript文件安装NPM包吗? 例如,我想要一个脚本,让我们称之为“script.js”,以某种方式(…使用NPM或…)安装通常可通过NPM的包。 在这个例子中,我想安装“FFI”。 (npm install ffi)

确实有可能以编程方式使用npm ,并在文档的旧版本中进行概述。 它已经被从官方文件中删除,但是仍然存在于源代码pipe理中,并有如下陈述:

虽然npm可以通过编程方式使用,但其API只能用于CLI,不能保证其适用于任何其他目的。 如果你想使用npm来可靠地执行一些任务,最安全的做法是用适当的参数调用所需的npm命令。

npm的语义版本是指CLI本身,而不是底层的API。 即使npm的版本表示没有按照semver进行重大更改,内部API也不能保证保持稳定

在原始文档中,以下是提供的代码示例:

var npm = require('npm') npm.load(myConfigObject, function (er) { if (er) return handlError(er) npm.commands.install(['some', 'args'], function (er, data) { if (er) return commandFailed(er) // command succeeded, and data might have some info }) npm.registry.log.on('log', function (message) { ... }) }) 

由于npm存在于node_modules文件夹中,因此可以使用require('npm')像其他模块一样加载它。 要安装一个模块,你需要使用npm.commands.install()

如果你需要查看源代码,那么它也在GitHub上 。 下面是代码的一个完整的工作示例,它相当于运行npm install没有任何命令行参数:

 var npm = require('npm'); npm.load(function(err) { // handle errors // install module ffi npm.commands.install(['ffi'], function(er, data) { // log errors or data }); npm.on('log', function(message) { // log installation progress console.log(message); }); }); 

请注意,安装函数的第一个参数是一个数组。 数组中的每个元素都是npm将尝试安装的模块。

在源代码控制的npm-cli.js文件中可以find更高级的用法。

是。 你可以使用child_process来执行系统命令

 var exec = require('child_process').exec, child; child = exec('npm install ffi', function (error, stdout, stderr) { console.log('stdout: ' + stdout); console.log('stderr: ' + stderr); if (error !== null) { console.log('exec error: ' + error); } }); 

如果你想要输出,你可以使用:

 var child_process = require('child_process'); child_process.execSync("npm install ffi",{stdio:[0,1,2]}); 

这样,您可以像手边一样观看安装,避免出现意外(缓冲区已满等)

它实际上可以有点容易

 var exec = require('child_process').exec; child = exec('npm install ffi').stderr.pipe(process.stderr); 

我有一段时间试图让第一个例子在一个项目目录中工作,在这里张贴,以防其他人发现这一点。 据我所知,NPM仍然可以直接正常工作,但是由于它假定CLI,我们不得不重复一些设置:

 // this must come before load to set your project directory var previous = process.cwd(); process.chdir(project); // this is the part missing from the example above var conf = {'bin-links': false, verbose: true, prefix: project} // this is all mostly the same var cli = require('npm'); cli.load(conf, (err) => { // handle errors if(err) { return reject(err); } // install module cli.commands.install(['ffi'], (er, data) => { process.chdir(previous); if(err) { reject(err); } // log errors or data resolve(data); }); cli.on('log', (message) => { // log installation progress console.log(message); }); });