Engineering Better Javascript

This is the first in a series of articles exploring a divergent idea for engineering better Javascript using ideas from the Maven build system.

Just a few years ago Javascript became used extensibly enough to warrant automated builds. It went from a language which was embedded sparingly in HTML pages to validate forms, make interactive menus, and disable right clicking, to the central language of the biggest social applications today. Not only is it used in the browser, but increasingly it is used on the server as well.

In these short few years, the need for a build system has arisen. The most popular systems today are Rake, Make and Ant; and recently Jake was introduced. These systems are declarative and task based, and can generally perform any build that is thrown at them with varying levels of complexity. In the simplest case, they concatenate scripts and replace tokens, download a compressor/test framework and other dependencies, run a compression/optimization routine, execute tests, and create a distribution package.

So what's the problem? If every Javascript library requires the same build steps, why should they all have their own slightly-different declarative build script? What happened to DRY? Why can't there be a build system which performs all these steps and allows for customization and extension when necessary, but is zero-config in the general case? It turns out that in Java land there are such systems, including Maven and Gradle. And in Maven's case, there is a plugin which extends it to Javascript.

A few years ago I created a Javascript application that had several library dependencies, and a supporting library for it that also had several of the same dependencies. Having spent a long stint in Java land, building several projects using Ant and eventually porting them to Maven, I had come to love what Maven offered even if it was slightly painful in the beginning. So naturally I wanted to go back to life without the pain of manual transitive dependency management and repetitive build scripts. This is when I found and began using (and contributing to) the Maven Javascript plugin.

Everyone knows the bad things about Maven, myself included. XML based project models are a nightmare. Plugin creation is way harder than it should be, thanks to Plexus. Project creation requires verbose command line arguments. The entire Internet must be downloaded the first time you build a project. There are plenty of less obvious ones, but I'll spare you, dear non-believers. But believe you me, I know Maven can be painful.

Despite this pain, there are some redeeming ideas which I think can be salvaged and used toward the betterment of Javascript development. The key ideas, I believe, are: the build lifecycle with plugins and project archetypes, and transitive dependency management with version ranges and a distributed repository architecture.

Over the coming weeks I will post a series of articles covering these ideas in more depth, and exploring what I see as a good solution to some of the woes of Javascript development. Stay tuned.