Javascript web app and Java server, build all in Maven or use Grunt for web app?

We are doing a web application with AngularJS and we like the idea of using Bower for Dependency Management and Grunt for building, running tests etc. (Yeoman)

The server is done with Java using Maven, so of course we would like with a simple mvn install build everything (web application + server)

So what approach you took and why?

1) Treat them as two different applications, which in fact they are. So using different building methods/tools is acceptable.

2) Forget about Grunt Bower, use Maven plugins to build, run tests, manage dependencies for the web application. If that is the case, which ones?

3) Use Maven exec plugin to call Grunt to build the front-end webapp. I see this more as a hack than a solution.

4) Other.

Approach easier to integrate with Jenkins is a plus.

Thanks in advance!


Solution 1:

After working with about every asset pipeline tool in the Java toolkit for a while I have come to a few conclusions:

Java Based Tooling

There are a handful of tools out there but the most popular are JAWR and Wro4J. The biggest problem with both of these is that they are mostly Rhino based (WRO4J now has some Node support) and Rhino is dog slow compared to Node based tools. You also have to consider that the JavaScript tooling is rapidly maturing so you should be looking for tools that can move quickly.

  • WRO4J - Support is great, Maven AND Eclipse integration are great the list of plugins is extensive and the framework is flexible enough that with some elbow grease you can write a plugin for whatever you need. If you're confined to a Java based asset pipeline this is for sure the way to go. The issue with Wro4j is that it is slow ( even when it kicks off Node processes ) relative to Node based tools.
    To give some real world numbers compiling and concatenating 25 asset bundles containing LESS, CSS CoffeeScript and JavaScript takes about ~35s when using Rhino and ~15s using Wro4j's Node support on a 2013 iMac with 16G of RAM. Using Grunt+Node takes about 2s on my puny MacBook Air.

  • JAWR - The integrations and feature list are pretty good but the docs aren't great and writing your own plugins can be a little tricky. When I originally wrote this post JAWR was in the middle of a 4 year hiatus but is now back under active development as of Jan 2014. If you choose to investigate Java Tools this is worth investigation.

Node Based Tooling (integrated with Ant/Maven Builds)

  • Grunt - It's easy, has a fantastic plugin ecosystem and the community is massive. If there is something you need to do you can bet there is a plugin for it - possibly even one written by the creators of grunt. The major criticisms of Grunt are that it is configuration driven which makes for a very setup easy but is not the "Node Way." It's also worth mentioning that Grunt tasks are not easily composable so for a complex JavaScript build pipeline Grunt may not be ideal.

  • Gulp - Gulp is the fast growing alternative to Grunt. Its concurrent by default and uses streams to avoid temporary writes to the file system which can considerably speed up your build. Gulp is very idiomatic and has an emphasis on code > configuration and while this gives you a lot of power it's is not ideal for teams that don't have a core competency in JavaScript.

The only potential hang up for JavaScript based tooling is that you will have to have Node, npm and grunt-cli/gulp on any machine that needs to do the compilation. If you don't have access to your CI machines or are not using artifact based deploys this may be a hard sell.

Integrating this into your Maven project is pretty easy and you have quite a few options. You can use the Maven ant-run plugin, you can run an ant exec task and call it from Maven or best of all you can just use the maven exec task.
Below is the code to integrate this into the Maven lifecycle using the exec plugin if this is helpful to anybody.

    <plugin>
      <groupId>org.codehaus.mojo</groupId>
      <artifactId>exec-maven-plugin</artifactId>
      <version>1.2.1</version>
      <executions>
        <execution>
          <phase>prepare-package</phase>
          <goals>
            <goal>exec</goal>
          </goals>
        </execution>
      </executions>
      <configuration>
        <executable>grunt</executable>
      </configuration>
    </plugin>

Solution 2:

For anyone still looking for more information on this topic, one of the creators of Yeoman has a good article (written a few months after this question was originally asked) that expands on the original answer with a bit more detail:

  • Making Maven Grunt

Solution 3:

Then there's also the frontend-maven-plugin: https://stackoverflow.com/a/19600777/320399 It downloads Node and NPM for you (locally to your project), downloads Grunt via that NPM (run by that Node) and then runs Grunt (via that Node). It's self-bootstrapping, and you don't need Node installed on the machine to build the project. Just one command; mvn install.

Solution 4:

You might want to checkout http://jhipster.github.io/ : it's a Yeoman generator, that generates an application which has Maven, Grunt and Bower all working together.

It's a bit like your third option, but everything is configured for you, which isn't that easy. It's also generating the basic AngularJS and Java REST services for you.