Monday, July 23, 2012

Dependency

The Java world has Maven and Ivy.  Tools meant to untangle dependency webs, to get you what you need, when you need it and put it where you want it.  I've seen a few attempts over the years to adapt Maven to handle javascript dependencies.  They were abandoned unfinished.  I haven't looked much in the last year.

Javascript development is immature.  Like Java 10 years ago, you generally need to manage the resources manually.  It's up to you to juggle version control, version numbers and untangle the web of dependency.  Once you have your libraries in their proper versions and understand what order you need them in, there are tools to help you execute what you decide/know.  RequireJS, yepnode.js, and Grunt interest me the most so far, but they all have different priorities and all get involved late in the dependency management problem. They help you execute deployment and development, but only after you have manually resolved all your dependencies.

Programmatic resolution is hard. To do it well requires organized public repositories, which require standardized naming, versioning, and dependency declaration. Not to mention bandwidth. The person and/or organization that takes it upon themselves to get this rolling in the javascript world has a lot of work cut out for them. But plenty of reward as well.

Ender does programmatic resolution, and it's package.json could probably be made to do more, but it only seems to run just one level deep, when a deep, tangled dependency web is the inevitable reality of any modular application development. It also neglects script loading, test running, support for app code, and stands as a competitor to other frameworks, not a complement.

Dependency management in the javascript world is harder than Java because javascript doesn't require compilation. Compilation funnels all Java devs through a common build step, making a natural insertion point for a dependency management tool. Javascript lacks that chokepoint. Testing, linting, minimizing, concatenating--all of these have some potential but are still inconsistently used or only used in production deployment, not development. And both deployment and development themselves often are embedded within build/deploy processes for whatever other platforms are being used to build the server side of the web app. Any javascript build process ultimately needs to work as a subprocess of those builds.

Javascript/HTML5 as a platform is still wild, untamed by the build tools and processes that smooth out other application development environments.  What i would really love to have in taming it is a dependency management tool that works with these features:

  • Repository support - public would be great, easy tools or conventions for private ones are acceptable. CDNs only get us part-way there; wheel authors need to be able to post libraries.
  • Standards for declaring dependency info - to optimize performance and untangle the web this should support/require:
    • library name and version
    • CDN URLs for the library
    • global variables exposed by the library
    • the libraries dependencies
      • name
      • version (range)
      • when needed (execution, document-ready, window-load, optional, etc)
    • license/copyright info
  • Conditional script loading (for polyfills)
  • Easy, declarative switching between development (test and lint, but no minimization or concatenation) and deployment (minimize and maybe concatenate)
  • Plugins for easy integrating with other build tools (Ant/Maven/etc)
Support for non-browser javascript and things like passing modules into each other (to avoid global exposure) are bonuses.  I don't care about them currently, but other people will.

A large portion of the code seems to be out there.  Grunt build process, Ender dependency resolution, yepnope script loading, and you're already well on your way. If you build it, they will come. Well, i certainly will! I'd built it myself, but there are only so many hours in a day.


#javascript