使用npm来安装或更新必需的软件包,就像rubygems的bundler


88

我爱Bundler,它非常擅长于依赖管理。我喜欢npm,安装节点软件包很容易!我有一个nodejs应用,并且希望能够指定我的应用依赖项,并在我将其部署任何地方时轻松地安装/更新它们。这不是我要发布的库,而是功能完善的网络应用。

我知道该npm bundle命令,但这似乎只是覆盖安装软件包的目录。

我习惯以这种方式使用捆绑器:

# Gemfile
gem "rails", "3.0.3"

仅在主机上不安装rails v3.0.3和任何其他必需的gem时,才在主机上安装它

> bundle install

如何使用npm实现类似目的?


我的答案不是您想知道的吗?
阿尔弗雷德·

Answers:


147

从npm 1.0开始(如果您按照README文件中的步骤进行操作,现在默认情况下会得到此内容),“捆绑包”不再是一个孤立的东西,而是“它是如何工作的”。

所以:

  1. package.json文件放在项目的根目录中
  2. 在该文件中列出您的部门

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
    
  3. npm install 由于您是在不使用args且不在全局模式下调用此函数的,因此它将仅在本地安装所有dep。

  4. require("express") 而且要快乐。

2
在生产中,我强烈建议将本地your_app/node_modules目录更改为应用程序目录之外的符号链接。您不需要每次部署时都必须下载,构建和安装每个依赖项。
Daniel Beardsley

好。如果我忘记更新package.json怎么办?有什么方法可以迫使NPM不在package.json中寻找而是在我的代码中使用的软件包?
Pono

4
这不是很正确。NPM将上面安装了所有的依赖my-project./node_modules/my-project/node_modules。我不确定是否有方便的方法可以在./node_modules 任何人中安装所有依赖项?
Daniel Beardsley

@DanielBeardsley我不认为npm是这样工作的。如果您看到这种行为,并且可以重现,请在npm github页面上发布问题。
isaacs 2011年

2
同意@DanielBeardsley。即使使用npm 1.1.70,我也会遭受该行为的困扰
13年

10

编辑:这仅适用于<1.0的npm版本


很难弄清楚这一点,但是NPM使这成为可能

您需要三个组成部分

  1. 存储库中的子目录(即deps/
  2. 一个package.json在上述目录中的文件,列出了相关
  3. index.js上述目录中的文件,需要你的依赖

想象一下,表达是您唯一的依赖

deps / package.json

注意:每次修改依赖项时,请增加版本号

{
  "name": "myapp_dependencies",
  "version": "0.0.1",
  "engines": {
    "node": "0.4.1"
  },
  "dependencies":{
    "express": "2.0.0beta2"
  }
}

deps / index.js

export.modules = {
  express: require('express')
  //add more
}

现在,您应该可以使用npm安装依赖项。您甚至可以将其纳入部署过程

cd deps
npm install

然后,在您的应用程序代码中,您可以访问特定版本的express,如下所示:

var express = require('myapp_dependencies').express;

谢谢,这是到目前为止我所见过的最好的方法。但是,require('express')inps / index.js中的代码不是仅导入最新的Express版本,而不一定是我们安装的版本吗?我是一个nodeJS新手,请耐心等待。
adamJLev 2011年

不,这是的魔力npm install,它将已安装软件包目录中的符号链接添加到相关软件包的正确版本。当需要依赖包时,require('express')首先检查本地目录,然后找到指向正确版本的express的符号链接。
Daniel Beardsley

5

您应该阅读Isaacs(作者npm)博客中的这两篇文章。我认为它们确实很棒,我相信会告诉您如何实现自己的目标:

  1. http://blog.izs.me/post/1675072029/10-cool-things-you-probably-didnt-realize-npm-could-do
  2. http://foohack.com/2010/08/intro-to-npm/

我相信链接#1(点#11)解释了这一点:

11:将所有依赖项捆绑到包本身中

使用npm bundle命令时,npm会将所有依赖项放入包中的node_modules文件夹中。但这并不止于此。

如果要依赖注册表以外的内容,则可以这样做。只是这样做:

npm bundle install http://github.com/whoever/whatever/tarball/master 这将把tarball的内容安装到bundle中,然后您可以将其作为依赖项列出,并且在以下情况下不会尝试安装您的软件包已安装。

如果您有自己的东西叉,这也很方便,并且不希望更改名称。

实际上,您几乎可以在捆绑软件中运行任何npm命令。要查看其中的内容,可以执行npm bundle ls。要删除某些内容,请执行npm bundle rm内容。而且,当然,您可以安装多个版本并激活所需的版本。


这很有用,尽管它不是我想要的。也许我需要补充说明。我正在寻找一种自动(在目标计算机上)安装或更新我的应用程序所依赖的NPM软件包的方法。看来npm bundle是用来将所有依赖项收集到默认目录以外的特定目录中的。我可能会想出自己的解决方案,该解决方案的性能类似于bundle installbundler红宝石)
Daniel Beardsley

1
npm版本1.0+开始,仅npm bundle删除了一条注释。相反,只使用npm install不带包名称的命令,它将读取package.json并下拉所需的包。
亚瑟·马尔森

2

从Npm 1.1.2版本开始,有一个新命令npm shrinkwrap可以创建一个npm-shrinkwrapped.json文件,类似于Gemfile.lock。做一个重要的是要防止软件腐烂(请参阅Bundler的原理)。尤其是Nodejs拥有如此快速发展的社区。

虽然bundle installGemfile.lock自动npm install创建npm-shrinkwrapped.json,但不会创建(但会在存在时使用它)。因此,您需要记住使用npm shrinkwrap

阅读完整指南,网址http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/


2

在我看来,最简单的解决方法是使用一个package.json文件与private设置标志(添加到故宫就在上个月)true。这样,您可以运行npm installnpm bundle获取项目的依赖项,但可以防止任何人意外发布您的非公开项目。

这是一个例子package.json

{
"name": "yourProject"
,"version": "1.0.0"
,"dependencies": { "express" : ">=2.1.0" }
,"private": true
}

运行npm install将安装express在本地系统上,如果它不存在; npm publish由于导致运行出错"private": true

您和您的团队可以在内部使用version标记跟踪随时间变化的依赖关系-每次更改依赖关系时,请提高版本。要查看已安装的版本,请使用npm ls installed


我认为您不应该引用true它,因为字符串是真实值(即!!"false" === true),所以它只能工作。
卡米洛·马丁

1

同时发布您的应用程序npm,并在package.json文件中列出其依赖项。

当有人用来npm安装您的软件包时,npm将负责解决其依赖性。

套件规格:http//wiki.commonjs.org/wiki/Packages/1.0


是的,但这是非开源Web应用程序。如果您的想法与发布应用程序无关,请编辑您的答案或创建另一个答案。
丹尼尔·比尔兹利

1
然后发布诸如“ myapp-dependencies”之类的软件包,您的用户可以npm在安装您的应用之前使用该软件包进行安装。我认为gemnode.js 没有其他等效项。
Dan Grossman
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.