使用 npm 安装或更新所需的包,就像用于 rubygems 的 bundler 一样

我喜欢 邦德勒,它非常适合依赖管理。我喜欢 Npm,安装节点包很容易!我有一个 nodejs 应用程序,并希望是 能够指定我的应用程序的依赖关系,并轻松地安装/更新它们无论我部署我的应用程序。这不是我要发布的图书馆,而是一个成熟的网络应用程序。

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

我习惯于这样使用 bundler:

# Gemfile
gem "rails", "3.0.3"

只有在 Rails v3.0.3和任何其他必需的 gem 尚不存在的情况下,才在主机上安装它

> bundle install

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

95281 次浏览

Publish your app with npm as well, and list its dependencies in your package.json file.

When someone uses npm to install your package, npm will take care of resolving its dependencies.

Packages spec: http://wiki.commonjs.org/wiki/Packages/1.0

You should read these two articles from Isaacs(author npm) blog. I think they are really good, and I believe tell you how to achieve your goal:

  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/

I believe link #1(point #11) explains this:

11: Bundle all your dependencies into the package itself

When you use the npm bundle command, npm will put all your dependencies into the node_modules folder in your package. But it doesn’t stop there.

If you want to depend on something that’s not on the registry, you can do that. Just do this:

npm bundle install http://github.com/whoever/whatever/tarball/master This will install the contents of that tarball into the bundle, and then you can list it as a dependency, and it won’t try to install it when your package gets installed.

This also is handy if you have your own fork of something, and would prefer not to change the name.

In fact, you can run almost any npm command at the bundle. To see what’s inside, you can do npm bundle ls. To remove something, do npm bundle rm thing. And, of course, you can install multiple versions and activate the one you want.

Edit: This only applies to npm versions < 1.0


It was quite difficult to figure this out, but NPM makes this possible.

You need three components

  1. A subdirectory in your repository (i.e. deps/)
  2. A package.json file in the above directory that lists dependencies
  3. An index.js file in the above directory that requires your dependencies

Example

Imagine that express is your only dependency

deps/package.json

note: Increment the version # each time you modify the dependencies

{
"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
}

Now you should be able to install your dependencies using npm. You could even make this part of your deployment process

cd deps
npm install

Then within your app code you can get access to your specific version of express like this:

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

It seems to me that the simplest solution is to use a package.json file with the private flag (added to npm just last month) set to true. That way, you can run npm install or npm bundle to grab your project's dependencies, but you prevent anyone from accidentally publishing your non-public project.

Here's an example package.json:

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

Running npm install will install express on the local system if it doesn't already exist; running npm publish gives an error because of the "private": true.

You and your team can use the version tag internally to track dependency changes over time—each time you change a dependency, bump the version. To see which version you've installed, use npm ls installed.

As of npm 1.0 (which is now what you get by default if you follow the steps in the README file), "bundle" is no longer a segregated thing -- it's just "how it works".

So:

  1. Put a package.json file in the root of your project
  2. List your deps in that file

    { "name" : "my-project"
    , "version" : "1.0.0"
    , "dependencies" : { "express" : "1.0.0" } }
    
  3. npm install Since you're calling this with no args, and not in global mode, it'll just install all your deps locally.

  4. require("express") and be happy.

As of Npm version 1.1.2 , there's a new command npm shrinkwrap which creates an npm-shrinkwrapped.json file, analogous to Gemfile.lock. It's important to make one, to prevent software rot (see Bundler's rationale). Particularly as Nodejs has such a fast moving community.

While bundle install creates a Gemfile.lock automatically, npm install won't create npm-shrinkwrapped.json (but will use it when it exists). Hence you need to remember to use npm shrinkwrap.

Read a full guide at http://blog.nodejs.org/2012/02/27/managing-node-js-dependencies-with-shrinkwrap/