The following code snippets help configuring the automatic process of merging, compressing and uniquely naming CSS and JS files. The current git revision hash is used as the unique identifier. The benefit: Uniquely named assets can be configured with a Never expire
policy. Any asset updates will result in a new filename and only then the client has to fetch the assets again.
The buildnumber-maven-plugin is capable to extract the current git hash version of the project. A property named gitHash
is available in the pom file and during resource filtering.
... <build> ... <plugin> <groupId>org.codehaus.mojo</groupId> <artifactId>buildnumber-maven-plugin</artifactId> <executions> <execution> <id>git-hash</id> <phase>generate-resources</phase> <goals> <goal>create</goal> </goals> <configuration> <format>{0}</format> <items> <item>scmVersion</item> </items> <buildNumberPropertyName>gitHash</buildNumberPropertyName> </configuration> </execution> </executions> </plugin> ... </build> ...
Requests for resources should be kept at a minimum and also the overall size should be small to actually deliver a fast page loading time. The minify-maven-plugin does both, merging and compressing/optimizing. The final filenames for the CSS and/or JS files are enriched with the gitHash
property.
... <build> ... <plugin> <groupId>com.samaxes.maven</groupId> <artifactId>minify-maven-plugin</artifactId> <executions> <execution> <id>default-minify</id> <configuration> <jsEngine>CLOSURE</jsEngine> <cssSourceDir>resources/css</cssSourceDir> <cssSourceFiles> <cssSourceFile>style-1.css</cssSourceFile> <cssSourceFile>style-2.css</cssSourceFile> </cssSourceFiles> <cssFinalFile>style-${gitHash}.css</cssFinalFile> <jsSourceDir>resources/js</jsSourceDir> <jsSourceFiles> <jsSourceFile>script-1.js</jsSourceFile> <jsSourceFile>script-2.js</jsSourceFile> </jsSourceFiles> <jsFinalFile>script-${gitHash}.js</jsFinalFile> </configuration> <goals> <goal>minify</goal> </goals> </execution> </executions> </plugin> ... </build> ...
To exclude all asset files but the style-xxx.min.css
and the script-xxx.min.js
, the unwanted files have to be listed as warSourceExcludes
in the maven-war-plugin.
... <build> ... <plugin> <groupId>org.apache.maven.plugins</groupId> <artifactId>maven-war-plugin</artifactId> <configuration> <warSourceExcludes>**/style-1.css,**/style-2.css,**/style-${gitHash}.css,**/script-1.js,**/script-2.js,**/script-${gitHash}.js</warSourceExcludes> </configuration> </plugin> ... </build> ...
A proxy for static files to serve assets without using the Tomcat/GlassFish/… resources would be even better.
As the git hash is needed to reference the CSS and JS files, the gitHash
property can be used as a filter replacement in a properties file in src/main/resources
with the content git_hash=${gitHash}
. The actual filtering has to be activated in the resources section of the pom
file.
... <build> ... <resources> <resource> <directory>src/main/java</directory> </resource> <resource> <directory>src/main/resources</directory> <filtering>true</filtering> <includes> <include>**/*.properties</include> </includes> </resource> </resources> ... </build> ...
Depending on the web framework, that git_hash
value has to be made available as a template parameter. For example, the spring framework provides the @PropertySource
annotation to load properties in theEnvironment
scope, which can then be read in a HandlerInterceptor
.
The generated style-xxx.min.css
and the script-xxx.min.js
can be referenced in a template file using thatgit_hash
parameter.
<link href="path/to/style-${git_hash}.min.css" rel="stylesheet"> <script type="text/javascript" src="path/to/script-${git_hash}.min.js"></script>