I was recently asked to work on an internal project for my company using HTML5 and JavaScript. it’s essentially just a technology showcase that we create for clients; we have many of these already completed but when a new technology emerges, we create a new project for it. This particular project wasn’t all that ground breaking on the visual side; it was more about the server and the messaging protocol which I can’t divulge just yet.
This is somewhat new territory for me. I’ve done enough JavaScript back in the day, but haven’t really touched these new JavaScript frameworks. Of course the language changed (with the frameworks) and then there’s the obvious presence of HTML5 and CSS3 into the web that’s definitely upped its game.
That said, I pretty much had no idea what I was getting into. My main expertise now lies in compiled code for enterprise projects (mostly Flex) that has its own automation process. It was efficient and helpful; it made me happy. Now I’m thrown back in a world of ‘archaic’ non-compiled language, or so I thought.
First thing’s first, I needed to seek tooling for this language that could automate the process. In my experience, most JavaScript projects would use Ant to package the project together for deployment. I’ve grown past Ant and have used Maven for most of my Flex projects for around 2 years now. It’s a great automation tool that takes a bit of time to set it up, but it vastly improves the process of compiling, testing and deploying. What I wanted to do is find a Maven plugin that would unit test the code, compress the files, then package it all into a WAR file for easy deployment. Seemed easy enough.
It wasn’t.
Apparently, most JavaScript developers don’t even know what Maven is, let alone unit testing or a continuous integration engine. This frustrated me to no end; how can a developer not know about tools that make the process simpler, more efficient and reduce human error? Googlin’ didn’t offer much help either; there is very little to no documentation about this process, which led me to write this post.
I found a few maven plugins but most of them were severely lacking in documentation, meaning that I was poking and prodding blindly with the hope that the plugin would output something useful. This went on for a few days with little progress until I stumbled upon a plugin called Testlol made by Bodil Stokke. It was well documented and made it easy for me to integrate it into my maven build. This particular plugin runs unit tests through Rhino (a headless java browser), outputs the results, runs JSLint (a code quality tool) and packages everything in a War file. Perfect! I just needed to run Yahoo’s JavaScript compressor through an aptly named plugin before packaging it.
It only took me a few hours to figure it out once I found the Testlol plugin, but I still spent days trying many other undocumented plugins before I arrived to a solution. I couldn’t seem to find an example for a Pom that I could use on my project, as if nobody has ever done it before or at least didn’t blog about it. I asked questions on forums and several IRC JavaScript channels but they all fell on deaf ears. On my third day of trying to figure out this problem, It donned to me why nobody knew about Maven or automation: most JavaScript developers are not developers, they’re “scripters”. After reading some of the IRC logs, it seemed obvious that most do not understand the concept of OOP, design patterns, frameworks or even MVC. I’m not saying *all* of them are like that. I know many great JavaScript developers like my colleague and friend David Padbury; but the truth of the matter is that real developers in the JavaScript world are few and far in between.
That being said, I turned my frustration into an opportunity to help others. Here is the Pom I’ve used on this project. The documentation on each respective plugin are found at the links posted above. Hopefully this will help another developer.
pom.xml
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0
http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>com.company.coldsteel</groupId>
<artifactId>client</artifactId>
<version>1.0-SNAPSHOT</version>
<packaging>war</packaging>
<name>Project ColdSteel</name>
<url></url>
<!-- Extra plugin repositories other than the usual ones under the maven repo -->
<pluginRepositories>
<pluginRepository>
<name>oss.sonatype.org</name>
<id>oss.sonatype.org</id>
<url>http://oss.sonatype.org/content/groups/public</url>
</pluginRepository>
</pluginRepositories>
<!-- the dependencies to get from the server for this to work -->
<dependencies>
<dependency>
<groupId>tv.bodil</groupId>
<artifactId>maven-testlol-plugin</artifactId>
<version>1.2.2</version>
</dependency>
<dependency>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>net.alchim31.maven</groupId>
<artifactId>yuicompressor-maven-plugin</artifactId>
<version>1.1</version>
<executions>
<execution>
<id>compress</id>
<phase>package</phase>
<goals>
<goal>compress</goal>
</goals>
<configuration>
<nosuffix>true</nosuffix>
</configuration>
</execution>
<!-- Skip over JSLint, testlol already does it -->
<execution>
<id>jslint</id>
<phase>install</phase>
<goals>
<goal>jslint</goal>
</goals>
<configuration>
<skip>true</skip>
</configuration>
</execution>
</executions>
</plugin>
<plugin>
<groupId>tv.bodil</groupId>
<artifactId>maven-testlol-plugin</artifactId>
<version>1.2.2</version>
<executions>
<execution>
<phase>test</phase>
<goals>
<goal>test</goal>
</goals>
<configuration>
<!-- path to the javascript folder, more on this later -->
<basePath>src/main/webapp/javascript</basePath>
<!-- path to the test folder, more on this later -->
<testSuite>src/test/javascript/</testSuite>
<globalFiles>
<!-- Files needed to able to run tests -->
<param>src/main/webapp/javascript/jquery/jquery.js</param>
<param>src/main/webapp/javascript/someclass.js</param>
</globalFiles>
</configuration>
</execution>
</executions>
</plugin>
</plugins>
</build>
</project>
From here, you simply need to install Maven, use the command line to change directory to the project and run ‘mvn clean install’. Everything will be then tested, quality controlled, compressed and packaged for you. However, for this to work you project need to adhere to a specific folder structure for it to work. Here’s an example of said structure:

This is the usual structure where you separate out the JavaScript part (main/javascript) from the html (main/webapp) and extra assets (main/resources) which the plugin aggregates together when compiling. The only problem with this is that it makes it very hard to do rapid prototyping since you need to compile it after every change to see it updated in the browser. To increase the efficiency of development, I instead opt to move the’ javascript’ folder and ‘resources’ folder into the ‘webapp’ folder. This way I can work directly from the ‘webapp’ directory and the packager doesn’t care. You can see these changes in the pom above. Here’s what my current directory structure looks like:
One important part of this is the ‘test’ folder; the plugin automatically runs every file within this folder using JSUnit unit testing library. The reports are then compiled and outputted to the prompt as well as a detailed xml report created in the target directory.
Your project is now enterprise ready. You can now integrate this within an automation engine like Teamcity or Hudson and make it compile every time a developer enters code and send an email out if there’s a failure. Just be sure to write lots of test to capture some of the possible bugs within the code base and let the system work its magic.
Copyright © Thinking in Code. All Rights Reserved. Powered by Wordpress
Node.js. That is all.
How about you give a bit more context there Champ? Being an awesome JS developer yourself
Nice post, but just to defend the JavaScript community a little… I’d have to argue that these build processes are very much happening, but just not on Maven. Certainly most people building javascript applications (e.g. more than the odd bit of jQuery sprinkling) have a very good idea about testing (check out vows and tools like zombie.js just to name a couple). It’s fairly easy to automate all this stuff in Rake which is where I imagine most of this work is happening, and there’s a ton of existing tooling that’s easy to plugin into it using Gems.
The field of large client-side JavaScript applications is still fairly young, however there is some great work being done and some smart people pushing it forward. I suggest picking up the book “JavaScript Patterns” which is a great run through how and if traditional OOP apply to JS. Also JavaScript is a very different beast to the languages most of us are familiar with (Java/C#/etc…), and I’d encourage people to first rethink the best way of building complex applications in this new language instead of trying to emulate what we’d be doing on other platforms (I’m talking specifically about the length’s some go to emulating Class/Interface type behaviour).
As you’ve discovered, frameworks for building large single-page app’s are still in their infancy. Almost every library (JSMVC, Backbone, ExtJs, etc) has a different take on what MVC in a client-side application means. Although it can be a frustrating experience building these applications today due to that – it is a fantastic opportunity for us with experience building large and complex front-ends to help guide what practices and techniques evolve.
On a unrelated note, this comment text box is too small.
David, you make some good points. I agree that there are build processes out there (mostly Ant from what I’ve seen), but there still seems to be a lack of documentation and understanding which made my discovery of it fairly difficult.
And yes, the comment box is too small. I’m currently in the process of redesigning my site