Installing an automatic build process for your projects is very common today and best practice. In the java world Maven is a very popular build tool and has proven its matureness over the years. In this blog post we will show you the benefits of a Maven build and how we can utilize them for javascript projects. Finally we present two maven archetypes for creating ready to go fully mavenized javascript projects for your first steps.
Automatic build process, what is it all about ?
Installing a maven build process will bring various benefits for your daily development. But what are these benefits and what are they good for ?
Running your tests automatically
Having a large testbase for your javascript code is a good and necessary requirement of being able to handle modifications on your code base like refactorings. Furthermore, tests will strengthen your confidence in your own code. But the full benefit of existing tests can be utilized best if they are run automatically on a regular base.
Generating code documentation
Documenting your code is another good practices for developing. If you develop some kind of javascript library you want to document the api to make it useable by your targeted audience. The generation of your api documentation should be part of the build process.
Running static code analysis
Static code analysis will help you to find potential problems in your code. Bugs might be identified and breaking code conventions can be detected early.
Compression of js and css files
For deploying your javascript to the runtime environment (e.g. a webserver) a good performance tuning trick is to use compressed versions of javascript and css files. Most of the common javascript libraries (like jQuery) are providing a development and a production version of their javascript files, improving loading times in the production environment. So the javascript and css files provided by ourself should be available in a compressed version as well.
Aggregated collection of your project documentation
Having automatically running tests, created api documentation and code analysis tools we have to deal with a lot of informations these tools providing us. So we would like to have a single point of entry to see the result of all the automatically running tools.
Continuous integration
The big advantage of having an automatic build process is the ability to do continuous integration. Having a continuous integration server like hudson your are able to run a complete build including tests, code analysis etc automatically on a separate machine. Whenever a developer is checking in some code, a complete build is started on the continuous integration server and feedback about that build is published immediately. So the most recent status of the project is visible at any time.
Introducing Maven to the javascript world
Mavenizing a javascript project is not much different than doing a regular java project.
Like in java projects the source files of your javascript project should be provided in a similar folder structure like this:
. |-- pom.xml `-- src |-- main | `-- javascript | `-- quickstart.js `-- test `-- javascript `-- quickstartTest.js
We have two different source folders, one for the productive code and one for the tests only.
The pom.xml file contains all the maven configurations which are necessary to meet our goals defined in the last section.
Since javascript source files are not supported in maven in the first place we have to add the new javascript source folders as a maven resource:
... src/main/javascript true ...
Since the javascript folder is now a declared resource location, the content is automatically copied to the generated maven artefact. Furthermore you can now use the maven filtering mechanism to alter the finally generated javascript file as you wish. For instance here you can insert license header to each of your source files, if you want.
At this point we are able to produce a maven artefact, a jar-file, which contains the javascript source files. For integrating all the remaining tasks like test execution or compression we have to rely on different maven plugins to do so.
Behavior driven testing with Jasmine
For javascript there are some good testing frameworks with different approaches available. With Jasmine you can write your tests in a behavior driven way. Your test implementations are more readable and it makes just more fun to write them.
Here is a little example to get the initial idea:
describe('The quickstart object',function() { it('adds two numbers',function() { var result = DE_AKQUINET.quickstart.addNumbers(1, 4); expect(result).toBe(5); }); });
To include the automatically execution of your jasmine tests the jasmine-maven-plugin is provided.
Your written javascript test files are located into the maven like folderstructure:
src/test/javascript
additional javascript files (f.i. needed javascript libraries like jQuery) will be placed under
src/test/javascript/lib
The following plugin-entries in your pom.xml is all you need to activate the automatic test execution:
... com.github.searls jasmine-maven-plugin 1.0.1-beta-6 generateManualRunner resources testResources test preparePackage src/main/javascript src/test/javascript lib/jquery-1.4.4.min.js ...
After that the tests are executed by default:
$ mvn install ... [INFO] Executing Jasmine Tests [INFO] ------------------------------------------------------- J A S M I N E T E S T S ------------------------------------------------------- [INFO] describe The quickstart object it adds two numbers [INFO] Results: 1 specs, 0 failures ...
The result of your jasmine test execution can be found under:
target/jasmine/ |-- ManualSpecRunner.html |-- SpecRunner.html |-- TEST-jasmine.xml
Here you can find a JUnit like xml (TEST-jasmine.xml) file with the testresults for further processing through other tools like a CI server.
Additionally there are two HTML test runners generated: one for test-driving locally in your browser (SpecRunner.html), and one to run as part of the build (ManualSpecRunner.html). Opening the latter one into your favorite browser will execute all the tests right away inside a real browser.
Compression of js and css files with yuicompressor-maven-plugin
To created compressed versions of your javascript and css files the yuicompressor-maven-plugin is used.
To activate automatically creation of compressed versions of your javascript and css files the following plugin configuration must be present in your pom.xml file.
... net.alchim31.maven yuicompressor-maven-plugin 1.1 compress-js compress ...
Finally your generated target maven artefact is containing the following files:
target/classes/ |-- quickstart-min.js `-- quickstart.js
Jslint and Jsdoc with maven-jstools-plugin
With the help of jsdoc you can easily create your own separated documentation about your code quite similar to javadoc.
... /** * Adds two numbers ... * @param number1 first number * @param number2 second number * @return the sum of the two numbers */ addNumbers : function(number1, number2) { return number1 + number2; } ...
Your api documentation is put into the comments of your methods. After the automatically generation during the build process a html document is created:
A very well known code analysis tool for javascript is jslint. Its a code quality tool which looks for potential problems in your javascript code. For jslint we would like to have a seamless integration into the build process as well.
To integrate jsdoc and jslint into the build process the maven-jstools-plugin is used.
This plugin has to be configured inside your reporting section of your pom file. After that jslint and jsdoc is executed and a report is generated containing the results.
... gr.abiss.mvn.plugins maven-jstools-plugin 0.7 src/main/javascript true true jslint jsdoc ...
After calling
$ mvn site
you will find the generated documentation under:
target/site/index.html
Here you have access to the generated reports of jslint and jsdoc.
The whole thing
After the configuration the complete pom.xml is looking like that
4.0.0 de.akquinet.javascript quickstart 1.0 Javascript quickstart akquinet A.G. http://www.akquinet.de/en src/main/javascript true com.github.searls jasmine-maven-plugin 1.0.1-beta-6 generateManualRunner resources testResources test preparePackage src/main/javascript src/test/javascript org.apache.maven.plugins maven-source-plugin 2.1.2 attach-sources jar net.alchim31.maven yuicompressor-maven-plugin 1.1 compress-js compress gr.abiss.mvn.plugins maven-jstools-plugin 0.7 src/main/javascript true true jslint jsdoc org.apache.maven.plugins maven-surefire-report-plugin 2.6
Javascript Archetypes
To avoid writing such long pom files we are providing two maven archetypes which are creating ready to go skeletons for your very own javascript project.
javascript-quickstart
The quickstart archetype creates a simple javascript application. To use this archetype just call:
mvn archetype:generate \ -DarchetypeArtifactId=javascript-quickstart \ -DarchetypeGroupId=de.akquinet.javascript.archetypes \ -DarchetypeVersion=1.0.0 \ -DgroupId=your.company \ -DartifactId=javascript-quickstart-application
After running the archetype the following content is created:
javascript-quickstart-application/ |-- pom.xml |-- src | |-- main | | `-- javascript | | `-- quickstart.js | `-- test | `-- javascript | `-- quickstartTest.js
This is a very simple Javascript project which is including a jasmine test, running jslint, jsdoc and compressions.
javascript-jqueryplugin
The jqueryplugin archetype creates a simple jquery plugin implementation which is a good starting point for your very own jquery plugins. The skeleton code obeys the rules of developing good jquery plugins. For further information check the jquery plugin authoring guide.
mvn archetype:generate \ -DarchetypeArtifactId=javascript-jqueryplugin \ -DarchetypeGroupId=de.akquinet.javascript.archetypes \ -DarchetypeVersion=1.0.0 \ -DgroupId=your.company \ -DartifactId=javascript-jqueryplugin
The created content should be similar to this:
|-- pom.xml |-- src | |-- main | | `-- javascript | | `-- jquery.helloworld.plugin.js | `-- test | `-- javascript | |-- helloworldPluginTest.js | `-- lib | `-- jquery-1.4.4.min.js
This example jQuery plugin is simply modifying the DOM by adding some “hello world” message to it. Additionally you will find a jasmine testcase for this plugin. Furthermore there is a fully configured build process which is running the jasmine test, jslint, jsdoc and compressions.
Conclusion
We showed how to utilize the power and benefit of bringing maven to the javascript world. With the help of three additional maven plugins we were able to create an build process which does the following steps automatically:
- Execution of your javascript tests
- Generating code documentation based on jsdoc
- Running static code analysis
- Perform compression of js and css files
- Be ready for easy integration of your favorite continuous integration server like hudson
After that, we also introduced two very handy maven archetypes to give you a quick and easy start into the world of maven and javascript.
Great Article, thank you so much!
I want to learn how to create a similar maven archetype for my enterprise. Could you please share / link to a good learning resource to create an archetype from an existing project?
Thank you for a great article.
I’m a little confused with surefire plugin at the end of artifact. It is not explained, and from what I found on internet, it’s for Java tests. Has it some purpose or it shouldn’t be there?
Thank you!! Great post.. I am working on Angular JS project and was in need of similar instructions.
Great article, thanks.
You have a little error in your maven-jstools-plugin:
The “reportSets” tag has to be in the “configuration” tag.
Very nice article!
Very nice article. Do you have a recommendation for how to include such a generated artefact containing JavaScript files as a dependency e.g. for a war-Artefact (which must be extracted somehow so that it get included into the webapp as a web-resource) ?
Hi, great article. I have a question, how can I mix several javascript files into one?. What plugin allows me to do this?.
Hi,
I just find some other promising plugin collection for javascript handling. The idea of merging different javascript files into one is one of the mentioned features. I did not find the time to play around with it so far, so no experience here on my side. But If you would like just have a look into
http://mojo.codehaus.org/javascript-maven-tools/javascript-maven-plugin/
Bye
Daniel
Promissing but looks like @CodeHaus doesn’t mantain it very actively 🙁
Fantastic article! Pretty awesome stuff! Well done
Thank you for this! It’s one of the best write-ups I’ve seen on how to do a build for the front end. And the Archetypes are a generous gift!
Question… are there many situations when you would want to ONLY build the front-end, or would you usually run this at the same time that you build the back end?
Also, where or how would I set my preferences for how JSlint or any of the other plugins function?