使用 npm 安装或更新所需的包,就像 ruby​​gems 的 bundler

Posted

技术标签:

【中文标题】使用 npm 安装或更新所需的包,就像 ruby​​gems 的 bundler【英文标题】:Using npm to install or update required packages just like bundler for rubygems 【发布时间】:2011-06-19 19:21:01 【问题描述】:

我喜欢Bundler,它非常擅长依赖管理。我爱npm,安装节点包很容易!我有一个 nodejs 应用程序,并且希望能够能够指定我的应用程序依赖项并轻松安装/更新它们,无论我在哪里部署我的应用程序。这不是我要发布的库,而是一个成熟的网络应用程序。

我知道npm bundle 命令,但这似乎只是简单地覆盖了安装包的目录。

我习惯于以这种方式使用 bundler:

# Gemfile
gem "rails", "3.0.3"

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

> bundle install

如何使用 npm 实现类似的功能?

【问题讨论】:

我的回答不是你想知道的吗? 【参考方案1】:

从 npm 1.0 开始(如果您按照 README 文件中的步骤操作,现在默认情况下会得到该版本),“捆绑包”不再是一个隔离的东西——它只是“它是如何工作的”。

所以:

    package.json 文件放在项目的根目录中

    在该文件中列出您的部门

     "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" :  "express" : "1.0.0"  
    

    npm install 因为你是在没有参数的情况下调用它,而不是在全局模式下,所以它只会在本地安装你所有的 dep。

    require("express") 开心就好。

【讨论】:

在生产环境中,我强烈建议将本地 your_app/node_modules 目录更改为应用目录之外的符号链接。您不希望每次部署时都必须下载、构建和安装每个依赖项。 好的。如果我忘记更新我的 package.json 怎么办?有什么方法可以强制 NPM 不查找 package.json 而是查找我在代码中使用的包? 这不太正确。 NPM 将在./node_modules/my-project/node_modules 中安装上述my-project 的所有依赖项。我不确定是否有一种方便的方法可以让它在./node_modulesAnyone 中安装所有依赖项? @DanielBeardsley 我不认为 npm 是这样工作的。如果您看到这种行为,并且可以重现它,请在 npm github 页面上发布问题。 同意@DanielBeardsley。即使使用 npm 1.1.70,我也会遭受这种行为的困扰【参考方案2】:

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

这是一个例子package.json


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

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

您和您的团队可以在内部使用版本标签来跟踪依赖项随时间的变化——每次您更改依赖项时,都会更新版本。要查看您安装的版本,请使用npm ls installed

【讨论】:

我认为你不应该引用true,它只是因为字符串是真实值(即!!"false" === true)才起作用。【参考方案3】:

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

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

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

【讨论】:

【参考方案4】:

编辑:这仅适用于 npm 版本

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

你需要三个组件

    存储库中的子目录(即deps/) 上述目录中列出依赖项的package.json 文件 上述目录中的index.js 文件需要您的依赖项

示例

想象express 是你唯一的依赖

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;

【讨论】:

谢谢,这是迄今为止我见过的最好的方法。但是,deps/index.js 中的require('express') 不会只是导入最新的 express 版本,而不一定是我们安装的那个?我是 nodeJS 菜鸟,所以请多多包涵。 不,这就是npm install 的魔力,它将已安装包目录中的符号链接添加到依赖包的正确版本。当需要依赖包时,require('express') 首先检查本地目录并找到指向正确版本 express 的符号链接。【参考方案5】:

您应该阅读 Isaacs(作者 npm)博客中的这两篇文章。我觉得他们真的很好,我相信会告诉你如何实现你的目标:

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

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

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

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

如果你想依赖某些东西 那不在注册表上,你可以做 那。只需这样做:

npm 捆绑安装 http://github.com/whoever/whatever/tarball/master 这将安装该内容 tarball 到包中,然后你 可以将其列为依赖项,并且 当你的时候不会尝试安装它 安装包。

如果你有你的 自己的东西的叉子,并且会 不想改名字。

事实上,你几乎可以运行任何 npm 捆绑包中的命令。看看是什么 在里面,你可以做 npm bundle ls。到 删除一些东西,做 npm bundle rm 事物。而且,当然,您可以安装 多个版本并激活一个 你想要的。

【讨论】:

这很有用,虽然它不是我想要的。也许我需要补充说明。我正在寻找一种方法来自动安装或更新(在目标机器上)我的应用程序在部署时所依赖的 NPM 包。看起来npm bundle 用于将所有依赖项收集到默认目录以外的特定目录中。我可能会想出我自己的解决方案,其性能类似于bundle installbundler for ruby​​) 请注意,因为npm 1.0+ 版,npm bundle 已被删除。相反,只需使用不带包名的 npm install 命令,它将读取 package.json 并下拉所需的包。【参考方案6】:

也使用npm 发布您的应用,并在您的 package.json 文件中列出其依赖项。

当有人使用npm 安装您的包时,npm 将负责解决其依赖关系。

包规格:http://wiki.commonjs.org/wiki/Packages/1.0

【讨论】:

是的,但这是一个非开源网络应用程序。如果您有不涉及发布应用的想法,请编辑您的答案或创建另一个答案。 然后发布一个像“myapp-dependencies”这样的包,您的用户可以在安装您的应用程序之前使用npm 进行安装。我认为 node.js 没有其他 gem 等价物。

以上是关于使用 npm 安装或更新所需的包,就像 ruby​​gems 的 bundler的主要内容,如果未能解决你的问题,请参考以下文章

NPM概述及使用简介

使用ANTD前端开发——开发环境搭建(Windows)

NPM - 如何在不更新或添加 package.json 中描述的包的情况下安装新包

即使安装了 gem,Ruby 也找不到所需的库

无法使用所需的 tumblr_client 运行 ruby​​ 脚本

npm学习之如何安装全局包更新全局安装的包卸载全局安装的包