Saturday, January 19, 2013

Integrating Mimosa with Maven

A friend of mine (David) created the Mimosa project to address the inadequacies of existing build tools in the Node.js/Client-side web development space.  Mimosa is now the standard build tool for web projects in our company, Berico Technologies, even though it is officially David's project.

While I love Node.js, there are many cases where it is more appropriate to write a service in Java, particularly when you need the support of a library, or you need a capability not currently supported by Node (e.g.: SPNEGO/Kerberos).  Generally this means you are going to use a tool like Maven or Gradle to manage your dependencies, compilation and testing.

If you're like me, you'll agree that writing the backend in Java does not mean you need to give up all of those client-side development skills in favor of JSP.  This post will show you how to setup Mimosa to work harmoniously with Maven in a standard "webapp" archetype.

Assumptions


Locate (or create a new) Maven Webapp

Find an existing Maven web project you want to integrate Mimosa into, or create a new project using the standard command (follow the instructions):

# Executed in the terminal
mvn archetype:generate -DarchetypeArtifactId=maven-archetype-webapp

Setup Mimosa


Your Maven project structure will look something like this:


Please note that I added the following folders that were not automatically created by Maven when we generated the archetype:

src/main/java
src/test/java
src/test/resources

You will most likely be including these anyway if you're going to build Java components.

Mimosa Configuration Steps

1.  Pick a folder to store uncompiled Mimosa assets.  This is where your frontend application with all of the CoffeeScript, Handlebars, SASS, LESS, Stylus, TypeScript, etc. files will exist.  We also want this folder to not be included in the src/main/java, src/main/resources, and src/main/webapp directories!  Otherwise, the uncompiled assets will be bundled by Maven into the WAR.

2.  For this example, I'm going to choose the src/main/mimosa folder.  Please make that directory:  mkdir src/main/mimosa command if you are in the root of your Maven project.

3.  Change into the newly created Mimosa directory:  cd src/main/mimosa
Instead of creating a new Mimosa project, we are simply going to start from a Mimosa configuration file.  Mimosa has a command called "config" which will simply drop an unmodified config file into your current directory:

mimosa config


4.  Now we need to edit the Mimosa config to deliver assets into the correct directory of our Maven project.  Using a text editor, open the mimosa-config.coffee file.

5.  The important thing to change in the config is the location of the "Watch Directory" to where you want the assets exported after Mimosa compiles them.  In my case, I deploy to a directory called "assets" in my webapp folder (src/main/webapp/assets).  I do this because I want to separate my Mimosa assets from the rest of the Java application, and I simply use some Spring MVC routing magic to redirect calls to "images/*" or "javascripts/*" to "assets/images/*" and "assets/javascripts/*".  

It's important to note that this separation is unnecessary.  When Mimosa performs a "clean" it will only clean files that are currently in watch directory, leaving anything you've placed in the deploy directory alone (please see http://mimosajs.com/commands.html#clean).

6.  Add any other Mimosa configuration options you may need.  One common configuration change I tend to make is to include extensions to the "copy" list to include videos and flash assets.  Here is an example of my config:

# mimosa-config.coffee
exports.config = {
  watch:
    sourceDir: "assets"
    compiledDir: "../webapp/assets"
    javascriptDir: "javascripts"
    exclude: [/[/\\](\.|~)[^/\\]+$/] 
  template:
    outputFileName: "templates"
    helperFiles:["app/template/handlebars-helpers"]
  copy:
    extensions: ["js","css","png","jpg",
      "jpeg","gif","html","eot",
      "svg","ttf","woff","otf",
      "yaml","kml","ico","htc",
     "htm"]
}

7.  Finally, since we did not create a Mimosa project, we will need to create the directory structure Mimosa expects (or what you've configured it to expect).  Here's an example of mine based on the configuration above:

Of course, this assumes you know how to structure your web project.  You may want to play with Mimosa by creating a new project to get a feel of how David prefers to setup his projects.

8.  Now if you call the command mimosa build, the files in the assets directory will be processed, then transfered into your src/main/webapp directory.

Maven Configuration Steps

There are now a couple of things you may want to do in Maven to make the build/test/run process (of both your web and Java components) harmonious.

First, if you want Mimosa to compile and transfer your web assets during the Maven compilation process, add the following configuration to your Maven pom.xml:


<build>
  <plugins>
    <plugin>
     <groupId>org.codehaus.mojo</groupId>
     <artifactId>exec-maven-plugin</artifactId>
     <version>1.2.1</version>
     <executions>
       <execution>
      <id>mimosa-compile</id>
      <phase>compile</phase>
      <goals>
        <goal>exec</goal>
      </goals>
      <configuration>
        <executable>mimosa</executable>
        <workingDirectory>${basedir}/src/main/mimosa</workingDirectory>
        <arguments>
       <argument>build</argument>
       <argument>-mo</argument>
        </arguments>
      </configuration>
       </execution>
     </executions>
    </plugin>
  </plugins>
</build>

Please note the arguments being passed to Mimosa (build -mo).  The -mo means to "minify" and "optimize" the files.  If this is not what you want done, change it to whatever you need.

Finally, if you are doing a lot of frontend work and need to have an auto-refresh capability, using the Maven Jetty Plugin in combination with Mimosa's "watch" facility works quite well:

<plugin>
  <groupId>org.mortbay.jetty</groupId>
  <artifactId>jetty-maven-plugin</artifactId>
  <version>8.1.5.v20120716</version>
  <configuration>
    <contextPath>/my-webapp</contextPath>
    <webApp>
      <contextPath>/my-webapp</contextPath>
    </webApp>
    </configuration>
</plugin>

Now, simply open up two terminals, and in the first:

# From the directory with the mimosa-config.coffee file
mimosa watch

and the second:

# From the root of the project (directory with pom.xml)
mvn jetty:run

And you will have combined live reload of your application served through Jetty.

That's it.

I want to thank David and the TBR team (who did most of the Maven work) for their assistance with the Maven-Mimosa integration.  I hope you find this useful!

No comments:

Post a Comment

Note: Only a member of this blog may post a comment.