The problems with front-end package management

By: James Allardice

Tags:

  • front-end
  • javascript

In this modern age of front-end web development we are lucky to have such a vast multitude of tools available to us. Whether that’s build tools (such as Grunt), unit test frameworks (like QUnit) or code quality tools (static analysers such as JSHint) they are all designed to make the development, deployment and maintenance process easier and faster.

This article concerns one such group of tools: package managers. There’s been a huge increase in interest in these utilities following the massive success of Node and npm, and with good reason. Gone are the days of having to commit multiple copies (one minified, one unminified, conditionally included based on environment) of large JavaScript libraries into your front-end repository.

There are several package management solutions available to front-end developers. A couple of the more popular ones include Bower and Component. Both work really well from a consumer point of view. Most popular packages are available through both tools so it’s quite straightforward to pick one and stick with it, adding a configuration file containing dependencies to your repository and updating your build or deployment scripts to pull them in.

For maintainers of front-end libraries this choice is not so ideal. You want to support the consumers of your library as best you can, and most of them don’t want to be stuck cloning your repository, installing your build tool of choice, figuring out how to get it to produce a single, working file and then committing that to their own repository. It’s not acceptable as a maintainer to make use of package managers during development of your library, but not to support those using your library in the same way.

So you need to publish your library to the package management registries. But which one(s) do you choose? They are all relatively popular, and all require different techniques to publish to. Component forces you to publish to GitHub (not a major concern these days, but restrictive nonetheless) and Bower forces you to commit the production-ready version of your library to the repository.

I spend a lot of time, both here at globaldev and in my personal projects, trying to improve the front-end (mainly JavaScript) development process. A big part of that is keeping the codebase clean and tidy. I do not want built assets in my repository. I do not want third party assets in my repository. It should be the job of your build and deployment tools to remove the need for those. To support other developers with the same ethos I have to make my libraries available through whatever tools they rely upon. The problem is that there is no standardised solution. Some devs want to consume a package through Bower, so you add a bower.json file to your repository. Then someone else wants to use Component, so you add a component.json. Before you know it your nice clean project is littered with configuration files and a bunch of production-ready files that have no place in the repo.

There is a popular module available on npm, Browserify, that can be used to mitigate some of these problems. It allows you to write front-end code as Node-style modules and then bundle them up into a single file. But that single file still needs to be available somewhere as it’s not the responsibility of your consumers to produce a browser-ready build of your package.

This is where the prepublish npm hook comes in. It allows you to add a script that runs before your package is published to the npm registry. This means you can Browserify and minify your script automatically, without having built assets in the repository. This is an excellent step in the right direction and if all of the front-end package managers offered such functionality it would improve the situation significantly. Unfortunately, we are still left with the problem of having to support a wide range of different tools and it’s unlikely that everyone will abandon their chosen setup for npm.

Another viable solution is the excellent CDNJS project. It aims to host as many front-end libraries as possible, rather than just the really popular ones hosted by the Google and Microsoft CDNs. If you’re building a web app this is a great resource. Instead of commiting third-party assets to your repository you can simply link to them on the CDN, removing the need for a package management tool completely. But if you’re building a module (e.g. a JavaScript library) of your own that depends upon others this approach is not possible.

This article may have come across as a bit of rant but I wanted to get across the difficulties surrounding front-end package management. The situation for package consumers is great. I think it’s brilliant that front-end development has all this tooling available now. But it would be even better if there could be a single standard for package publishers that didn’t tie us down to a single platform (GitHub) and doesn’t require us to commit compiled/minified code into our repositories. That may be wishful thinking but the front-end community has come up with some incredible stuff in recent years so this shouldn’t be beyond us.


About the Author

James Allardice

James Allardice is a Senior JavaScript Developer at Venntro. He is passionate about clean, maintainable JavaScript and is regularly on the lookout for ways to improve the JavaScript development process. He's currently interested in JSHint, Grunt, AngularJS and ECMAScript6.