views:

1064

answers:

4

Hi, mod_rewrite gurus!

Here is the problem: we have lots of Javascripts and lots of CSS files, which we'd rather be serving minified. Minification is easy: set up the YUI Compressor, run an Ant task, and it spits out minified files, which we save beside the originals.

So we end up with the following directory structure somewhere inside our DocumentRoot:

/
   /js
      /min
         foo-min.js
         bar-min.js
      foo.js
      bar.js
      quux.js
   /css
      ...

Now what we need is that Apache serve files from the min subdirectory, and fallback to serving uncompressed files, if their minified versions are not available. The last issue is the one I cannot solve.

For example: suppose we have a request to example.com/js/foo.js — in this case Apache should send contents of /js/min/foo-min.js. There is no minified quux.js, so request to /js/quux.js returns /js/quux.js itself, not 404. Finally, if there is no /js/fred.js, it should end up with 404.

Actually, I'm setting build scripts in such a way that unminified files are not deployed on the production server, but this configuration still might be useful on an integration server and on development machines.

A: 

Is it possible to change your build scripts? If so, you can configure them to minify the files and give them the same file name, but only when provided the proper flag, e.g. ant productionDeploy instead of ant integrationDeploy. That way the minification process is completely transparent to everything except the build script.

Hank Gay
Yes, it is possible, and I am implementing the script right this way. But having two versions (original and minified) could be really useful in testing integration config to see if minified versions are not broken in any way.
Stepan Stolyarov
+2  A: 

You can use RewriteCond to detect the presence of a minified file:

RewriteCond %{REQUESTURI} ^/js/(.*\.js)
RewriteCond js/min/%1 -f
RewriteRule %1 min/%1 [L]
Ignacio Vazquez-Abrams
Doesn't RewriteCond ... -f work with fully qualified filenames? It never worked for me with relative filenames.
Stepan Stolyarov
Then change that RewriteCond line to "RewriteCond %{DOCUMENT_ROOT}/js/min/%1 -f".
Michael Cramer
+1  A: 

Here is the configuration that finally worked:

/js/.htaccess:

RewriteEngine On

RewriteBase /js

RewriteCond %{REQUEST_URI} ^/js/((.+)\.js)$
RewriteCond %{DOCUMENT_ROOT}/js/min/%2-min.js -f
RewriteRule ^(.+)$ min/%2-min.js [L]

Same for css directory.

Stepan Stolyarov
A: 

thanks for the trick, I gonna try it with yui compressor.