I\'m interested in hearing how you prefer to automate Javascript minification for your Java web apps. Here are a few aspects I\'m particularly interested in:
If you post something new in this thread, edit this post to link to yours.
I think one of the best and right tool for the job is wro4j Check out https://github.com/wro4j/wro4j
It does everything you need:
Can run in debug as well as production modes. Just specify all the files it should handle/pre-process and it does the rest.
You can simply include merged, minified and compressed resource like this:
<script type="text/javascript" src="wro/all.js"></script>
I'm really surprised no one mentioned JAWR - https://j-a-w-r.github.io
It's pretty mature and supports all standard features that are to be expected, and a bit more. Here is how it holds against the OP's excellent criteria.
How does it integrate? Is it part of your build tool, a servlet filter, a standalone program post-processing the WAR file, or something else?
It originally did the processing/heavy-lifting at application startup and serving was based on a servlet. Starting with 3.x they added support for integrating at build time.
Support for JSP and Facelets is provided through a custom JSP tag library to import processed resources. In addition to that, a JS resources loader is implemented which supports loading the resources from static HTML pages.
Is it easy to enable and disable? It's very unfunny to try and debug a minified script, but it's also useful for a developer to be able to test that the minification doesn't break anything.
A debug=on
option is available to use before application startup, and a custom GET
parameter can be specified at individual requests in production to toggle debug mode selectively at runtime for said request.
Which minifier does it use?
For JS it supports YUI Compressor and JSMin, for CSS I'm not sure.
Does it lack any features that you can think of?
SASS
support comes to mind. That said, it does support LESS
.
I have written ant macros for Google Closure compiler and Yahoo compressor and include this file in different web projects.
<?xml version="1.0" encoding="UTF-8"?>
<!-- CSS and JS minifier. -->
<!DOCTYPE project>
<project name="minifier" basedir=".">
<property name="gc" value="compiler-r1592.jar" />
<property name="yc" value="yuicompressor-2.4.6.jar" />
<!-- Compress single js with Google Closure compiler -->
<macrodef name="gc-js">
<attribute name="dir" />
<attribute name="src" />
<sequential>
<java jar="${gc}" fork="true">
<!--
- - compilation_level WHITESPACE_ONLY | SIMPLE_OPTIMIZATIONS | ADVANCED_OPTIMIZATIONS
Specifies the compilation level to use. Default: SIMPLE_OPTIMIZATIONS
- - warning_level QUIET | DEFAULT | VERBOSE
Specifies the warning level to use.
-->
<arg line="--js=@{dir}/@{src}.js" />
<arg line="--js_output_file=@{dir}/@{src}-min-gc.js" />
</java>
</sequential>
</macrodef>
<!-- Compress single js with Yahoo compressor -->
<macrodef name="yc-js">
<attribute name="dir" />
<attribute name="src" />
<sequential>
<java jar="${yc}" fork="true">
<arg value="@{dir}/@{src}.js" />
<arg line="-o" />
<arg value="@{dir}/@{src}-min-yc.js" />
</java>
</sequential>
</macrodef>
<!-- Compress all js in directory with Yahoo compressor -->
<macrodef name="yc-js-all">
<attribute name="dir" />
<sequential>
<apply executable="java" parallel="false">
<fileset dir="@{dir}" includes="*.js" excludes="*-min*.js" />
<arg line="-jar" />
<arg path="${yc}" />
<srcfile />
<arg line="-o" />
<mapper type="glob" from="*.js" to="@{dir}/*-min-yc.js" />
<targetfile />
</apply>
</sequential>
</macrodef>
<!-- Compress all css in directory with Yahoo compressor -->
<macrodef name="yc-css-all">
<attribute name="dir" default="${build.css.dir}" />
<sequential>
<apply executable="java" parallel="false">
<fileset dir="@{dir}" includes="*.css" excludes="*-min*.css" />
<arg line="-jar" />
<arg path="${yc}" />
<arg line="-v --line-break 0" />
<srcfile />
<arg line="-o" />
<mapper type="glob" from="*.css" to="@{dir}/*-min.css" />
<targetfile />
</apply>
</sequential>
</macrodef>
</project>
Integration: <import file="build-minifier.xml" />
in your build.xml, then invoke as usual ant tasks: <gc-js dir="${build.js.dir}" src="prototype" />
<yc-js-all dir="${build.js.dir}" />
Choice of two minifiers: Google Closure compiler and Yahoo compressor, you should download them manually and place near the xml file
Minifiers skip already compressed files (ending with -min*
)
Usually I make three versions of script: uncompressed (e.g. prototype.js
) for debugging, compressed with closure compiler (prototype-min-gc.js
) for production server, compressed with Yahoo (prototype-min-yc.js
) for troubleshooting because closure compiler uses risky optimizations and sometimes produces invalid compressed file and Yahoo compressor is more safe
Yahoo compressor can minify all files in a dir with single macro, Closure compiler cannot
This worked for me: https://bitbucket.org/m6_russell_francis/yui-compressor-ant-task/wiki/Home
<!-- minimize all static *.css & *.js content -->
<target name="static-content-minify">
<taskdef name="yuicompressor"
classname="com.metrosix.yuicompressor.anttask.YuiCompressorTask">
<classpath>
<pathelement location="${jar.yui.compressor}"/>
<pathelement location="${jar.yui.anttask.compressor}" />
</classpath>
</taskdef>
<yuicompressor todir="${build.static.content.min}" charset="utf-8"
preserveallsemicolons="true" munge="true" >
<fileset dir="${src.static.content}">
<include name="**/*.css"/>
<include name="**/*.js"/>
</fileset>
</yuicompressor>
</target>