7

I'm having problems following the 'official' recommendation to check in all external dependencies into git (article http://www.mikealrogers.com/posts/nodemodules-in-git.html linked fron FAQ)

  1. How do you make sure that not only top-level dependencies are checked-in? Most npm modules do currently not follow the recommendation. They all have their node_modules in .gitignore . Just Deleting their .gitignore seems risky.

  2. For compiled module the article recommends to check-in only the sources and run 'npm rebuild' and deploy time. Unfortunately 'npm rebuild' does not do a 'clean make' for all modules (despite bugfix https://github.com/isaacs/npm/issues/1872 being included in npm version 1.0.106 i'm using). This means that I have to prevent compile targets from being checked in (otherwise i would have object code compiled for the developer machine on the production machine without being overwritten by npm rebuild). But: how do i do this? Unfortunately the modules don't have a common compile output directory, so just git-ignoring "node_modules//build" and "/node_modules//out/" (as mentioned in this good article eng.yammer.com/blog/2012/1/4/managing-nodejs-dependencies-and-deployments-at-yammer.html won't help in every case.

Short version: how do you make sure that production servers use the exact same version of all dependent modules as you use during development?

dknaus
  • 1,133
  • 12
  • 16
  • I posted a script over at http://stackoverflow.com/questions/11351784/npm-clean-modules/13957364#13957364 which may help. – theGecko Dec 19 '12 at 23:00

2 Answers2

4

UPDATE: there is now npm shrinkwrap which solves the problem of locking down exact dependency versions, even of dependencies' dependencies! More info here.

Checking in node_modules can be problematic, as the environment it's running on may differ from user to user - so what is compiled on some environment may not work on another. Plus it would fill up your changelogs and repositories with 3rd party code. Which I take it is the conslusion you've come to with your short version of the question, so let me address that.

Short version: how do you make sure that production servers use the exact same version of all dependent modules as you use during development?

Inside your package.json, there will be dependencies: {}, if it is not there, then add it. To accomplish what you want, add your dependencies as the key, and their exact versions as the value. E.g. dependencies: { docpad: '2.5.0', mocha: '1.1.0' }

However, generally (it depends on the author) upgrades to the revision number (the x.x.X number) are just bugfixes and safe. You can allow minor changes by doing dependencies: { docpad: '2.5.x', mocha: '1.1.x' } which saves you from having to update your package.json and do a release everytime there is a bugfix release. You can even do things like 2.x if you wish.

This is the solution I've come to use for all of my modules, as it ensures that even 6 months later or whatever the module will still work - whereas doing something like >= 2.0.0 means when v3 of a dependency comes out, your module will probably be unusable at that time. Ensuring you stick to specific versions "guarantees" stability over time.

For reference you can see how I've done it in my open-source node.js modules here

balupton
  • 47,113
  • 32
  • 131
  • 182
  • Thanks. I'm already setting distinct versions in package.json like you described. But this only relates to my top-level dependencies. I can't get control over the dependencies of the dependencies. – dknaus Feb 10 '12 at 12:16
  • Ohhhhh right... A few times what I have done to combat that is make the change to the dependency and file a pull request, and in the meantime publish your own flavor of it until it is officially merged. E.g. change `docpad` to `docpad-bal` or something, and reference your own flavor in the original project. When it is merged unpublish it. – balupton Feb 10 '12 at 12:42
  • Added a reference to the just released npm shrinkwrap which solves that issue you were talking about @user1194821 – balupton Feb 27 '12 at 22:50
1

About the .gitignore of your dependencies (in "node_modules"), npm 1.1 ignores the .gitignore files, so that they are not installed;

npm 1.1 will exclude .gitignore files from the things it installs. 
npm 1.0 did not have this feature, so you have to be careful about that. 
Deleting them recursively is fine: 
    find node_modules -name .gitignore | xargs rm 
But, in npm 1.1, you never have to do this, because it excludes them 
from the install automatically. 

That's coming from the chief himself (Isaac), and it's here and seems to cover pretty much everything. The "extraneous" problem I have must be something silly I've done, I'll try a clean setup.

mna
  • 22,989
  • 6
  • 46
  • 49