Bundle your devDependencies and chill

Recently I have been writing a bunch of node libraries. I always use the same workflow and I’m pretty happy with it. It needs some devDependencies for linting, building, testing and so on. They are all shared between my libraries. Perfect!


As a good developer — good meaning lazy — I made a custom Yeoman generator to scaffold any new library and install those devDependencies. Everything was great until I had to maintain all those kids.

Well ok, a bunch of services help to do that. My favorite one is Greenkeeper which watches for dependency updates and sends you a nice pull request. I can finally chill and watch the last season of Mr Robot!

Wait, what? 10 pull requests?!

Yes. per day. Well, node community is uber active, dependencies bump their version all the time. If you apply the following formula: modules × dependencies. You end up computing the degree of hell you are in!

You have two choices: either discard some updates, or take’em all. But you will still have to deal with them. You’ll be condemned to see that annoying blue dot on your Github’s notification bell repeatedly whispering:

Hey bro, welcome to dependency management hell!

Meta packages

… to the rescue! They are not new. In fact, they are actually pretty old. If you are familiar with some Linux distributions and their package manager, you’ve been seeing them quite often. Even some Node projects are using them (i.e. Babel presets).

Meta packages are just a collection of dependencies bundled together. They allow to significantly decrease the complexity of your project dependencies. So instead of having to manage all of them you’ll end up with one. That’s code factorization, but for packages.

Control

A meta package gives you more control on your dependency management.

You basically handle all your dependencies in one place. You are the only one deciding when to release a new version. You take control on what needs to be updated urgently or what can be deferred. You take control on the update pace your projects will have.

If your workflow evolves regularly, you can add or remove dependencies without having to propagate those updates in all your projects. Simply update your meta-package. That’s it!

Abstraction

You can even add a layer of abstraction in order to simplify the usage of some dependencies. For instance, I always use ava and nyc together. My meta package exports a test binary script which executes nyc ava. In my projects I then use test. If one day I change the way I’m running tests, I will only have to update my meta package. Simple.

You can see an example of it here: https://github.com/ngryman/meta-dev/blob/master/package.json#L15.

Ok, how?

Easy! Create a new Node project and simply put all your usual devDependencies in dependencies so they get installed in your parent project. Done.

With npm >=3 all dependencies are flattened. Binaries and libraries are available directly in the parent project. So you don’t have anything more to do.

Here is an example of my bundle: https://github.com/ngryman/meta-dev.

Hope this helps a few buddies out there!