Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do you automate Javascript minification for your Java web applications?

People also ask

How do you do Minification in JavaScript?

To minify JavaScript, try UglifyJS. The Closure Compiler is also very effective. You can create a build process that uses these tools to minify and rename the development files and save them to a production directory.

How do I minify JavaScript online?

Use your JS URL to compress. Click on the URL button, Enter URL and Submit. Users can also minify JS File by uploading the file. Minify JS Online works well on Windows, MAC, Linux, Chrome, Firefox, Edge, and Safari.

What is Minification in web development?

Minification is the process of minimizing code and markup in your web pages and script files. It's one of the main methods used to reduce load times and bandwidth usage on websites. Minification dramatically improves site speed and accessibility, directly translating into a better user experience.


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 safe

  • Yahoo compressor can minify all files in a dir with single macro, Closure compiler cannot


I tried two ways:

  1. using a servlet filter. When in production mode, the filter is activated and it compress any data bounded to URL like *.css or *.js
  2. using maven and yuicompressor-maven-plugin; the compression is perfomed una-tantum, (when assembling the production war)

Of course the latter solution is better since it does not consume resources at runtime (my webapp is using google app engine) and it doesn't complicate your application code. So assume this latter case in the following answers:

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?

using maven

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.

you activate it only when assemblying the final war; in development mode you see the uncompressed version of your resources

Does it work transparently, or does it have any side effects (apart from the ones inherent in minification) that I have to consider in my day-to-day work?

absolutely

Which minifier does it use?

YUI compressor

Does it lack any features that you can think of?

no, it is very complete and easy to use

What do you like about it?

it is integrated with my favourite tool (maven) and the plugin is in the central repository (a good maven citizen)


I think you need a compression library, for example Granule tag.

http://code.google.com/p/granule/

It gzip and combine javascripts wrapped by g:compress tag using different methods, also has Ant task as well

code sample is:

<g:compress>
  <script type="text/javascript" src="common.js"/>
  <script type="text/javascript" src="closure/goog/base.js"/>
  <script>
       goog.require('goog.dom');
       goog.require('goog.date');
       goog.require('goog.ui.DatePicker');
  </script>
  <script type="text/javascript">
      var dp = new goog.ui.DatePicker();
      dp.render(document.getElementById('datepicker'));
  </script>
</g:compress>
...


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.