2013-12-19 40 views
11

我发现how to install npm packages programmatically和代码工作正常:安装程序一个NPM包提供的版本

var npm = require("npm"); 
npm.load({ 
    loaded: false 
}, function (err) { 
    // catch errors 
    npm.commands.install(["my", "packages", "to", "install"], function (er, data) { 
    // log the error or data 
    }); 
    npm.on("log", function (message) { 
    // log the progress of the installation 
    console.log(message); 
    }); 
}); 

如果我想安装hello-world包的第一个版本,我怎么能做到这一点的的NodeJS侧,使用npm模块?

我知道我可以使用子进程,但我想选择npm模块解决方案。

回答

13

NPM NodeJS API没有很好的记录,但检查代码有帮助。

Here我们发现以下字符串:

install.usage = "npm install" 
       + "\nnpm install <pkg>" 
       + "\nnpm install <pkg>@<tag>" 
       + "\nnpm install <pkg>@<version>" 
       + "\nnpm install <pkg>@<version range>" 
       + "\nnpm install <folder>" 
       + "\nnpm install <tarball file>" 
       + "\nnpm install <tarball url>" 
       + "\nnpm install <git:// url>" 
       + "\nnpm install <github username>/<github project>" 
       + "\n\nCan specify one or more: npm install ./foo.tgz [email protected] /some/folder" 
       + "\nIf no argument is supplied and ./npm-shrinkwrap.json is " 
       + "\npresent, installs dependencies specified in the shrinkwrap." 
       + "\nOtherwise, installs dependencies from ./package.json." 

我的问题是关于版本,所以我们可以这样做:[email protected]安装0.0.1hello-world

var npm = require("npm"); 
npm.load({ 
    loaded: false 
}, function (err) { 
    // catch errors 
    npm.commands.install(["[email protected]"], function (er, data) { 
    // log the error or data 
    }); 
    npm.on("log", function (message) { 
    // log the progress of the installation 
    console.log(message); 
    }); 
}); 

我没有测试,但我相信,我们可以使用install.usage解决方案的任何格式。

我写了一个函数,可以将数组中的dependencies对象转换为可以传递给install函数调用的数组。

dependencies:

{ 
    "hello-world": "0.0.1" 
} 

的函数获取路径package.json文件,并返回字符串的数组。

function createNpmDependenciesArray (packageFilePath) { 
    var p = require(packageFilePath); 
    if (!p.dependencies) return []; 

    var deps = []; 
    for (var mod in p.dependencies) { 
     deps.push(mod + "@" + p.dependencies[mod]); 
    } 

    return deps; 
} 
+0

我刚刚测试了模块@版本方法,它确实有效。 – tremor

+1

这很好,但是,如何以编程方式使用npm安装GLOBALY? –

+0

@cSn检查我发现的代码[这段代码](https://github.com/npm/npm/blob/a362c3f1919987419ed8a37c8defa19d2e6697b0/lib/install.js#L122-L162) - 但是我不知道代码应该如何看起来像......也许你可以问一个问题。 –

1

当我编写具有依赖关系的应用程序时,我使用package.json文件并将其与我的应用程序一起包含在目录中。它看起来可能有点像这样。

{ 
    "name": "MyApp", 
    "description": "My App.", 
    "version": "0.0.1", 
    "dependencies": { 
     "express": "3.4.3", 
     "socket.io": "0.9.16" 
    } 
} 

我认为你可以使用类似的格式从命令行安装NPM。使用package.json,您只需执行npm install -d(假设-d代表“依赖关系”)

您的问题是关于以编程方式执行的。你有没有试过简单地添加第二个参数,如(“npm @ version#”)?

如果我这样做编程我可能会尝试这样的事:

var pjson = require('./package.json'); 

这样我可以保持版本控制和使用的package.json文件的简单性。

我在评论中增加了一些信息,如果你还没有看,那么这里是npm install的文档。 https://npmjs.org/doc/cli/npm-install.html

我一直无法挖掘任何关于您的具体情况的其他具体信息,也许没有方法通过编程方式通过版本进行安装,但这没有任何意义,它必须是可行的。

+0

我想我是不太清楚。假设我想用'3.4.3'版本安装'express'。当调用'install'时,我传递一个表示包名的字符串数组。我可以通过什么来安装'express 3.4.3'? –

+0

更新了我的回答,我认为最好的方法实际上是使用require('./ package.json'); – tremor

+0

请看npm模块是如何工作的。要求'package.json'文件没有帮助。 –

7

,因为我做这种implem的对我的工作LOT我写了一个简单而有效,模块的NodeJS可以轻松处理过程。

Github repository of npmi

npm install npmi 
0

我模块的作者,让做什么,你的想法。 见live-plugin-manager

您可以从NPM,Github或文件夹几乎安装和运行任何软件包。

这里的示例:

import {PluginManager} from "live-plugin-manager"; 

const manager = new PluginManager(); 

async function run() { 
    await manager.install("moment"); 

    const moment = manager.require("moment"); 
    console.log(moment().format()); 

    await manager.uninstall("moment"); 
} 

run(); 

在上面的代码我安装moment包在运行时,加载和执行它。最后我卸载它。

在内部,我不运行npm cli,但实际上下载软件包并在节点VM沙箱中运行。

要安装特定版本只需使用:

await manager.install("moment", "2.20.1");