Category Archives: Juicer

Juicer: issues and workarounds

Juicer is a nice tool to merge and minify several CSS files into just one file. Kudos to the guy that created it!

That said, I’ve been bitten several times by it. Here are some of the troubles I experienced and what I did to get things to work for me.

Juicer: embedding images in CSS

Juicer wants to know the –-document-root when embedding images with --force-image-embed or --embed-images data_uri.

Note that I’m talking about image inclusion in a css using relative URLs, I have not checked this for absolute urls because I don’t care: I never use then.

For things to work, the --document-root must be the directory of the css file you are processing.

Again, a clarification is in order: I always process just one css file each time with Juicer, because I make a point of creating a single css file that @imports all css files I want to consolidate. The net effect is that I’m processing several files, but specifying just one in the command line.

I’m making this clear so that you know I just haven’t tested Juicer behavior with --document-root and multiple css files in the command line. Better safe than sorry!

If you notice I’m being defensive, it is because I am. Juicer is great, but I’ve found its ways are not obvious to me and made many assumptions that did not hold.

Fixing relative CSS urls with ant

I run juicer from my project ant tasks, and that can be problematic because there are ant ways and there are Juicer ways, and they collide from time to time.

As point in case, I have to perform text substitution on the generated css file so that relative urls are right: this is due to the fact that Juicer seems to be intended to be run from the webapp root directory if you want correct relative urls in your css.

*But* I have not managed to run the ant task in the webapp root directory. I tried the dir attribute in the exec task, that seemed to be the cure, but that didn’t do what I needed.

Yes, I can bypass ant and run things from the command line. But then I will have ant’s way, the command line way, and will need to duplicate configuration information for ant and batch files (quick, where is the YUI compressor jar in your system/project?). And I hate breaking the DRY (Don’t Repeat Yourself) rule.

Workaround: replace ../WebContent/ with ../, WebContent being the subdirectory relative to my ant build.xml file. This is way simple in ant:

   token="url(../../WebContent/" value="url(../"/>

Juicer is written in Ruby, and Ruby has its ways

Ruby seems not to like ‘:’ or ‘\’ in file names -or Juicer uses that in a bizarre way.

Ok, I know almost nil about Ruby, but I had some bizarre problems with file names. In some cases, the error message I’ve got helped me clearly diagnose the problem.

In other cases, I had no error message, and it took a *lot* of time to identify the problem.

The workaround is avoiding ‘:’ or ‘\’ in file names passed directly or indirectly to Juicer.

Note that this can happen inadvertently. For example, if you execute an ant task in Windows, ant’s ${basedir} can end up being c:\x\y\z.

Workaround: convert all directory and file names to Unix style, which Windows handles correctly, like this:

<pathconvert property="juicer-friendly-input-dir" targetos="unix">
  <path location="${basedir}/WebContent/css"/>

Juicer does not generate a non-minified css: but you can trick it into it

Juicer provides two nices features for CSS: consolidates several css files into one, and minifies the resulting file.

I would love to have a single production time css that is minified, and another one that is not, to help users of my js libraries with customizing the css. But Juicer does not provide a way to generate a non-minified version.

Workaround: specify a fake inexistent .jar file with the --path INEXISTENT_MINIFIER_JAR_TO_GET_NON_MINIFIED_CSS argument. Juicer will generate the consolidated css and will fail with a Unable to access jarfile error…but the consolidated css file with be there.

Yes, ugly, but very useful. I hope they had added a none option to the --minifyer argument that would have the same effect without the rror message, but they did not