Unobtrusive Way to Combine and Compress JavaScript/CSS for Java/Spring/Maven Applications

Unobtrusive way to combine and compress javascript/css for java/spring/maven applications?

A solution that has worked for me is using the maven-minify-plugin (groupId is com.samaxes.maven) but only when building for production. Use a build property to specify if you are in development mode or not. Link to plugin

You can then have something like this (I don't know freemarker so I am just pasting some JSP code but I am sure it can easily be converted):

<c:choose>
<c:when test="${developmentMode}">
<link rel="stylesheet" type="text/css" href="<c:url value="/css/custom1.css"/>"/>
<link rel="stylesheet" type="text/css" href="<c:url value="/css/custom2.css"/>"/>
<link rel="stylesheet" type="text/css" href="<c:url value="/css/another1.css"/>"/>
<link rel="stylesheet" type="text/css" href="<c:url value="/css/another2.css"/>"/>
<script type="text/javascript" src="<c:url value="/js/mylibrary.js"/>"></script>
<script type="text/javascript" src="<c:url value="/js/more.js"/>"></script>
<script type="text/javascript" src="<c:url value="/js/util.js"/>"></script>
<script type="text/javascript" src="<c:url value="/js/whatever.js"/>"></script>
<script type="text/javascript" src="<c:url value="/js/more.js"/>"></script>
</c:when>
<c:otherwise>
<link rel="stylesheet" type="text/css" href="<c:url value="/css/minified.css"/>"/>
<script type="text/javascript" src="<c:url value="/js/minified.js"/>"></script>
</c:otherwise>
</c:choose>

This way non-minified/combined JS/css is used while in development and the minified css only used when building for production.

EDIT: As requested here is the code to expose Spring-defined beans on the ServletContext:

<bean class="org.springframework.web.context.support.ServletContextAttributeExporter">
<property name="attributes">
<map>
<!-- Obviously this can be changed to read from properties file -->
<entry key="developmentMode" value="false" />
</map>
</property>
</bean>

Managing HTML resources (CSS, JS files) in Spring MVC

Short answer: surely. But I think the real question is "how?" :)

Spring MVC is the base that Grails built on, so it can do what Grails can do. Grails-resources is just an utility that Grails make to help developing works easier. If you want to do the same in Spring, you must do some work.

Firstly, Spring MVC has a way to expose resources (reference, Chapter 17.15.6, "Configuring Serving of Resources"); for example:

<mvc:resources mapping="/images/**" location="/images/"/>

The above line expose every files in [Web folder]/images/ as resource and can be requested by web browsers.

Second, to embed the resource into HTMLs as easy like Grails, you must combine Spring with some other view technologies, like sitemesh, freemarker/velocity/JSP... (which Grails do behind the scene for you). Instead of grails tag, now you have freemarker's or Velocity's macros. But I would recommend writing some of your own custom macros, since the built-in one is not always good.

I have used both Grails and Spring MVC. I appreciate Grails' effort to make developer life easier, but with Spring things are a bit different. With Spring, you'll get to write some more code, make some more choices (in Grails they were chosen for you as "default", and is "invisible" if you don't want to customize). As the pay-off, you are forced to be more awared with the under-lying mechanism, which is a good thing.

I have used sitemesh for layout, and freemarker as a HTML-rendering engine for several web projects, and they works pretty well.


UPDATE:

I want to make clear that mvc:resources is not the full answer to your problem. It's just the part of exposing the web resources out for browsers to get. With Grails, this is already made by default, but it's not true for Spring. You must specify that the content in folder 'images' are resources, and they can be accessed by the url http://your-domain-name/context-name/images/image-name . As saying, Spring is a lot more explicit than Grails.

Another thing is template engine. Library Sitemesh is a popular choice when working with Spring (it's also the default for Grails), so it isn't a lot different (mostly it's about syntax). The main purpose of template engine is to "fill in" your htmls with dynamic data, and I'm going to show you... a bit of it.

Please be aware that, to make a tutorial that fulfill your example is exceed the scope of an answer. Also, Spring enable many relevant solutions, which means different developers may have different way of organization/ config. But to give you a feeling, I'll make a quick example (I'm using freemarker to make this example):

In file: common.ftl, I have:

<#macro commonInclude>
<script type="text/javascript" src="${rc.getContextUrl('/js/jquery.js')}"></script>
<link rel="stylesheet" type="text/css" href="${rc.getContextUrl('css/main.css')}" />
</#macro>

With a little more config, then in view files I can call:

<@common.commonInclude />

And it will render the code you want.

As you see, the main difference is their syntax. Grails allow a cleaner style, while Spring give you a more "explicit" style which will benefit if you want to customize things.

  • Bonus: If you are looking for a replacement for Grails layout, take a quick search for "Spring and Sitemesh" and you may find it.


Related Topics



Leave a reply



Submit