How do you automate Javascript minification for your Java web applications?
Round-up post
If you post something new in this thread, edit this post to link to yours.
- Ant
apply
task (using YUI Compressor) - Custom YUI Compressor Ant task
- Maven YUI Compressor plugin
- Granule (for JSP, JSF, Grails, Ant)
- Ant macros for Google Closure compiler
- wro4j (Maven, servlet filters, plain Java, etc)
- ant-yui-compressor (ant task for compressing JS+CSS)
- JAWR
- Minify Maven Plugin
- humpty
- Ant
exec
task using Terser
We are using Ant task to minify js files with YUICompressor during production build and put result into a separated folder. Then we upload those files to a web server.
Here is an example:
<target name="js.minify" depends="js.preprocess">
<apply executable="java" parallel="false">
<fileset dir="." includes="foo.js, bar.js"/>
<arg line="-jar"/>
<arg path="yuicompressor.jar"/>
<srcfile/>
<arg line="-o"/>
<mapper type="glob" from="*.js" to="*-min.js"/>
<targetfile/>
</apply>
</target>
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:
- Keep project web resources (js & css) well organized
- Merge & minify them at run-time (using a simple filter) or build-time (using maven plugin)
- Free and open source: Released under an Apache 2.0 license
- several minification tools supported by wro4j: JsMin, Google Closure compressor, YUI etc
- Very easy to use. Supports Servlet Filter, Plain Java or Spring Configuration
- Javascript and CSS Meta Frameworks Support: CoffeeScript, Less, Sass etc
- Validation: JSLint, CSSLint etc
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 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 safeYahoo compressor can minify all files in a dir with single macro, Closure compiler cannot