Asset-Pipeline Epiphany 'Provided'

Posted by David Estes on May 29, 2015

Filed under Grails, Groovy

First off, today we released a new version of :asset-pipeline:2.2.2. This version contains fixes that finally allow your assets to be bundled within binary plugins for grails 2.2.x (something we have had working for grails 3.x but were still fighting with for 2.2.x . This also means you can use webjars. Just add them to your dependencies {} block and you should be able to use webjars at will.

An example is to use webjars:

dependencies {
  provided 'org.webjars:almond:0.2.9'
}

Now you can use that web jar file in your application.js like so:

//=require webjars/almond/0.2.9/almond.js

console.log("My main js file");

Pretty nifty right? Did you notice something odd in how the webjar dependency was included? The provided scope is a scope that basically says this dependency is needed during development runtime and at build time , but useless to me in my WAR file.

Epiphany Moment

Some of you are wondering how in the world this file would not be needed in the production war file. Because that almond.js file is needed. The answer has to do with how asset-pipeline processes all the files on the resolver scan path. All assets that are resolved are copied, bundled, minified, and placed in an assets folder within the WAR file. No processing is EVER done in a production environment!

Beyond just Webjars

This is where things get really awesome. You don't actually ever need your add on processor plugins in production either. i.e. sass-asset-pipeline or less-asset-pipeline. They just sit there and do nothing in production because the files are already converted to their final form. Each of these plugins have dependencies in and of themselves. For example sass-asset-pipeline requires the bulky jruby to run sass processing. Thats over 25MB of space being added to your final WAR alone. What happens if we just change that line:

plugins {
  compile  ':asset-pipeline:2.2.2'
  provided ':sass-asset-pipeline:2.1.1'
}

Now this is available for runtime processing of files while developing in the context of grails run-app. It is also available during the WAR build phase for processing the files. But it is NOT included in your final WAR file. This saves you not only 25+MB of space but frees your WAR of unnecessary runtime dependencies that bloat the jvm as well as removes risks of security vulnerabilities from things like jruby.