Tuesday, March 15th, 2005

Using Maven to modularize JavaScript development

Category: Ajax, Builds, Java, JavaScript

<p> A lot of developers ‘poo poo’ any code that is written in JavaScript.

  • “JavaScript isn’t a real programming language”
  • “JavaScript is just about browser hacker scripts”
  • “You can use it to focus(). Big deal.”
  • “JavaScript is for the HTML designers, not for REAL coders”

Giving thought to your JavaScript code

As such, any JavaScript code in a project, doesn’t get the thought that it deserves. Why would you be anal about unit testing your Java code, and ignoring your JavaScript code?

You no longer need too, as we have JsUnit, and other tools.

Dependencies are dependencies

As soon as you stop thinking of your JavaScript code as a bastard step-child, you can apply the same practices that we have in our other worlds (e.g. Java).

One of the problems with Java web applications, is that you can often do a search for files on a developers hard drive, and see MANY of the same files.

For example, you search for struts.jar, and there are 23 instances of it on the file system. Of course, they are not all the same size, since they are various versions (but you don’t know).

We get around that problem by using a tool such as Maven, or Ivy.

Now, we can define our project dependencies, and the correct versions are tracked, and downloaded automatically. Very nice.

WEB-INF/lib == /scripts

Why don’t we do this with JavaScript code? We have the same problem with commonscript.js as we do with struts.jar. So why not manage it?

Maven JS type

Maven has the base framework that we need to make this quite trivial. First, we can just agree on the ‘type’ of dependency. I am using js. Then you can just add dependencies as per normal:

<dependency>
    <groupId>adigio</groupId>
    <artifactId>xhr-test</artifactId>
    <version>0.1</version>
    <type>js</type>
</dependency>

This means that maven will try to grab:

/[groupId]/[type]s/[artifactId]-[version].[type]

or in the example above:

/adigio/jss/xhr-text-0.1.js

from the various repositories that you have setup in your project.properties:

maven.repo.remote=http://adigio.com/maven,http://www.ibiblio.org/maven,http://www.codeczar.com/maven,http://xdoclet.sourceforge.net/repository,http://dist.codehaus.org

NOTE: ‘[type]s’ is hard-coded. There is no way to map “when you see type ‘js’ look in directory ‘scripts’, or something like that. This means that ‘jss’ looks a lil’ silly :).

maven-war-javascript

So, we didn’t have to do anything to get Maven to start grabbing dependencies for us. But, in our projects we don’t just want to grab some JavaScript modules and put them in your local repository. We want to use them :)

Rather than writing some manual goals to handle this, I wrote a Maven plugin which piggy-backs on the war plugin.

The maven-war-javascript-plugin offers a war:js / war:js:copy-scripts goal. This manually looks through your dependencies, and copies any JavaScript modules to your web app (in the scripts directory by default. To change, use the maven.war.javascript.dir property).

However, although you have a goal in which you can kick off this task, in practice you don’t need to use it. The plugin registers itself with the war module, and whenever it is invoked, it sneaks in and does the copy. So, it is a seemless introduction!

Installation

To download and install the plugin, you can simply:

  • Add: http://www.adigio.com/maven to maven.repo.remote
  • Run the commmand: % maven -DartifactId=maven-war-javascript-plugin -DgroupId=adigio -Dversion=0.1 plugin:download

Conclusion

So, now I can take JavaScript more seriously, and can start managing my JS dependencies with the care and loving touch that I do with the immense amount of open source library bloat :)

Related Content:

  • Maven Magic
    Maven is a high-level, intelligent project management, build and deployment tool from the Apache project. There is nothing that Maven does that Ant...
  • Setting Up a Maven Repository
    This article looks at some of the functionality that a maven repository should provide. Criteria for choosing a maven repository are listed. Steps...
  • JavaFX Maven plugin released
    Alex Ruiz has announced the release of the JavaFX Maven plugin to simplify the process of compiling JavaFX...
  • Achieve modularity with an OSGi architecture
    Java architects can overcome complex "big ball of mud" architecture by building a component-based model with a development framework - like OSGi -...
  • Modular vs. Monolithic
    Modular's price is attractive and features have steadily grown, but modular still has advantages for some scenarios....

Posted by Dion Almaer at 9:36 am
5 Comments

+++--
3.1 rating from 11 votes

5 Comments »

Comments feed

How well does Ant work for this sort of thing?

Comment by Rob — March 16, 2005

What about Javascript source code management in maven 2?

Comment by Andrew J. Leer — March 23, 2006

An alternative to using a separate plugin would be to use the default “overlay” behavior for war artifacts (see “Adding external web sources” in the war plugin documentation). So to create a set of javascript files that you would be able to include in other projects using Maven’s dependency handling, you would create a project of type “war” for a webapp that contains only the script files that you want to share. Once you have deployed the resulting war-file to your repository, simply declaring that file as a runtime dependency for another war project will automatically download the war and ‘overlay’ its contents onto contents of your project.

The two restrictions of this method is that you can only include the javascript library as a dependency for other “war” projects, and you cannot control what directory the scripts end up in (it will be whatever directory they were in in the original project).

Comment by Josh Bandur — October 11, 2006

I’m trying to build up a multi-project build structure for JS projects and this sounds like a perfect tool, however I couldn’t get to it:
http://www.adigio.com/maven/ returns 403 Forbidden

Comment by Richard — March 20, 2007

For both runtime discovery of JS-based dependencies in Maven-based WARs and reporting (JSDoc Toolkit, JSLint) in your Maven-based JS projects check out maven-jstools-plugin:

http://dev.abiss.gr/mvn-jstools/

Comment by Manos — October 6, 2007

Leave a comment

You must be logged in to post a comment.