version compress css js with maven

One problem in release is the user still caches our resources that our new look/feel can not be presented unless user hard refresh the browser.

To overcome this, several ways:

1. append a query string(like UUID) to the resource

This is good if you want to user download a fresh copy each request. If we randomize the query string with every request, this will defeat caching entirely. This is rarely/never desirable for a production application’s CSS.

Add a <%@ page import=”java.util.UUID” %> to the head of jsp and append the uuid to the resource by adding:

<script type=”text/javascript” language=”javascript” src=”dir/gwt_whatever.nocache.js?<%=UUID.randomUUID().toString()%>“></script>

2. use a new name each build

The yuicompressor-maven-plugin has a <suffix> option to let you add suffix to the resource after compression.

3.append a query String (like build date) to the resource

This is actually the way i used. The good part is it still keeps the file name, user could still get a new version for the each release. To achieve this.

3.1 add a property in the pom. This way we have a timestamp var available.

		<timestamp>${maven.build.timestamp}</timestamp>
		<maven.build.timestamp.format>yyyy-MM-dd</maven.build.timestamp.format>

3.2 add resource in the war plugin to filter the web.xml so that we could replace variables

<webResources>
    <!--compressed resources, see yuicompressor-maven-plugin below for detail-->
    <resource>
        <directory>${project.build.directory}/min</directory>
    </resource>
    <!--this is to replace the ${...} with our maven properties. For example the timestamp property replacement in the web.xml-->
    <resource>
        <directory>${basedir}/src/main/webapp/WEB-INF</directory>
        <filtering>true</filtering>
        <targetPath>WEB-INF</targetPath>
        <includes>
            <include>**/web.xml</include>
        </includes>
    </resource>
</webResources>

For the yuicompress maven plugin config:

			
<plugin>
    <groupId>net.alchim31.maven</groupId>
    <artifactId>yuicompressor-maven-plugin</artifactId>
    <version>1.5.1</version>
    <executions>
        <execution>
            <goals>
                <goal>compress</goal>
            </goals>
        </execution>
    </executions>
    <configuration>
        <nosuffix>true</nosuffix>
        <excludes>
            <exclude>**/*.min.js</exclude>
            <exclude>**/jquery*.js</exclude>
            <exclude>**/angular*.js</exclude>
            <exclude>**/*.min.css</exclude>
            <exclude>**/jquery*.css</exclude>
        </excludes>
        <!--maven war plugin will overwrite the file we compressed, so we add a 'webappDirectory' here to put them into the /min directory and
					    then in the maven-war-plugin define this /min directory as a <resource> to make sure they could be included-->
        <webappDirectory>${project.build.directory}/min</webappDirectory>
    </configuration>
</plugin>

3.3 Add an init-param in the web.xml. Note the ${timestamp} will be replaced by the maven time stamp because of the filtering config we have in 3.2 and the property definition in 3.1

  <context-param>
    <param-name>buildTimeStamp</param-name>
    <param-value>${timestamp}</param-value>
  </context-param>

3.4 now the ‘buildTimeStamp’ is available for us in the jsp context, we just need to include it:

<link rel="stylesheet"
href="/css/whatever.css?build=<c:out value='${initParam.buildTimeStamp}'/>"
type="text/css">

 

Advertisements

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s