Monday, July 30, 2012

Are node_modules in git still necessary with npm shrinkwrap?

Are node_modules in git still necessary with npm shrinkwrap?:
I was on an internal discussion with some folks around the management of npm dependencies and whether or not your should check them in. That led to a reference to @mikeal’s great post here. In that post, the recommendation is basically this:
  1. If you are authoring a module, you should not check in your dependencies. You should have a package.json with a liberal versioning policy on dependencies. The main reason stated for this is to distribute integration testing / ensure that the latest versions are really being put to the test. Beyond that I would say it also provides the benefit of developers leveraging the latest and greatest features modules have to offer.
  2. If you are authoring an application, you SHOULD check in your dependencies. The main reason given for this is in order to have predictability in your production environment. package.json only allows you to specify your high level dependency versioning policy. Meaning you can lock down your versions to a specific version, but you cannot with package.json lock down your dependency’s dependencies. This means your environment is unpredictable and you might find out at the last second that one of your child dependencies breaks your app! Not a good thing at all! Because of that the recommendation is to check in all your dependencies thus ensuring there are no surprises at deployment time.

And then came npm shrinkwrap.

In the past year a new awesome (though not necessarily widely known feature) was added to npm to solve the problem identified in 2, “npm shrinkwrap”. When you run “npm shrinkwrap” on your  app, npm generates an npm-shrinkwrap.json that locks down the full transitive closure of all of your dependencies. It essentially locks things down so you get that predictability I was talking about above.
For example here is the example used on the node.js site of an npm-shrinkwrap.json file generated off of a package.json for module A which depends on B which then has a dependency on C.

{
  "name": "A",
  "version": "0.1.0",
  "dependencies": {
    "B": {
      "version": "0.0.1",
      "dependencies": {
        "C": {
          "version": "0.1.0"
        }
      }
    }
  }
}


Works in Azure Websites and other cloud providers

In case you are wondering, if you push an npm-shrinkwrap.json to Windows Azure Websites or to other PAAS providers like Nodejitsu and Heroku, it should work. I verified this for Azure but I am assuming the same for others as npm automatically recognizes the shrinkwrap files presence.

Is it still recommended to check in your dependencies for your app?

With the introduction of shrinkwrap, this raises the question of should you still check in your dependencies? My personal lean is it is no longer necessary if you use shrinkwrap. Thus I follow the following guidelines.
  1. If you are publishing a module, you should not check in your dependencies. You should have a package.json with a liberal versioning policy on dependencies.
  2. If you are publishing an application, you should not don’t need to necessarily check in your dependencies. You can should use an npm- shrinkwrap.json which locks down your dependencies.
Note: A clear exception to 2 is if you are using private forks of modules. In those cases you will need to check in the forked modules somewhere. You still could conceptually have your shrinkwrap file pull those forks from a private repo (npm supports pulling from github repos) so that they are still managed via the shrinkwrap file. Or you could mix and match having just those modules checked in to the main repo and the ones that are not forked pulled via the shrinkwrap file.
Interested in your thoughts and experiences here…


DIGITAL JUICE

No comments:

Post a Comment

Thank's!