views:

972

answers:

8

Hey guys,

Does anyone know of a good way to automatically run certain file types through a processing script on upload? I'm trying to accomplish automatically minifying CSS and Javascript when I upload them to the server, keeping a nice, human-readable version on the local side while keeping a minified one on the server. I'm currently using WinSCP on Windows, which is scriptable to some degree but might not be scriptable enough. I'd probably need some kind of cobbled-together solution, so don't be afraid to suggest something with duct tape in it; however, I do need to do the minification on my local computer and upload the squished file, since I use shared hosting and can't install junk on the server.

Thanks.

+4  A: 

Since you're on shared hosting, I'd just suggest using the YUICompressor, and running your css/js files through it prior to uploading them. Be sure not to lose your original files - it could be a pain making future changes.

You could also place a script on your server that would periodically re-write your css/js files, passing them througha minify-process, and manually invoke this script after doing an upload.

Jonathan Sampson
Read the question. I asked for a way to do that on upload. I know WHAT to use, I just need to know if there's a good way to automate it.
Jarett
I did read your question. And I gave you what I thought to be the best alternative, since I don't think you have an option for doing it automatically on upload.
Jonathan Sampson
Well maybe someone else would know. That's why I asked in the first place.
Jarett
attitude sucks a little here jarrett
redsquare
+2  A: 

Well, to minify CSS is just a couple of regexes.

// (PHP) but should be easily portable to any language
function compressCSS($css) {
    return
        preg_replace(
            array('@\s\s+@','@(\w+:)\s*([\w\s,#]+;?)@'),
            array(' ','$1$2'),
            str_replace(
                array("\r","\n","\t",' {','} ',';}'),
                array('','','','{','}','}'),
                preg_replace('@/\*[^*]*\*+([^/][^*]*\*+)*/@', '', $css)
            )
        )
    ;
}

And Dean Edwards's Javascript packer has been ported to PHP, Perl, .NET and WSH, so if you're using any of those technologies, you could actually have it running on your own server. ...Just remember to cache the results!

nickf
Apparently the OP is downvoting us for not telling him how to do it automatically on upload. Since I think you offered a valid solution, I'll offset his downvote with an upvote.
Jonathan Sampson
How dare I downvote answers that don't answer my question!
Jarett
@Jarett Sometimes our questions are best answered with alternatives.
Jonathan Sampson
Not when the answer misses the point of the question entirely. If I'd asked for the best minifier, my question would have been closed immediately as a duplicate.
Jarett
well, my point was that you could run it on your server... how much more automagic do you want?
nickf
+1  A: 

I like Minify. It supports compressing and trimming html, javascript and css on the fly.

It is quite flexible, an can be integrated into existing apps.

Some of the more advanced features is combining multiple javascript files into one, same for css. It has multiple ways of defining which files to combine, which is usefull for testing purposes. This way you do not have to modify the settings every time.

Dykam
This might be good. It seems more stupid-proof than the solution I was thinking about.
Jarett
It is really foolproof. I added more info.
Dykam
+5  A: 

I recommend creating a makefile to solve this particular problem, here's a quick and dirty makefile I'm using for a site of mine:

PUBDIR=../../static/js/
OUTDIR=./build/
COMPRESSOR=../yui/build/yuicompressor-2.4.2.jar
ARGS=
VPATH=${OUTDIR}
INST_TARGETS=${OUTDIR}jgblue.js

jgblue.js: combined.js
    java -jar ${COMPRESSOR} ${ARGS} ${OUTDIR}$< -o ${OUTDIR}$@

combined.js: main.js listview.js tabs.js
    cat $^ > ${OUTDIR}$@

.PHONY: install

install:
    cp ${INST_TARGETS} ${PUBDIR}

Then all you have to type is:

make && make install

First it takes all of your development files and concatenates them into a single file, then the concatenated file gets compressed and copied into your public directory. I'm using YUICompressor for compression, it works quite well.

Bill Casarin
Hot dog. That might be worth piddling around with Cygwin for.
Jarett
What I ended up doing (since I'm on Windows) is writing a Powershell script that watches the directory for changes with the PSEventing snap-in, then runs it through the appropriate minifier depending on the file extension.
Jarett
+1  A: 

I suggest compressing (by all means in some automated way) on your development machine and testing it there before uploading to your live server. Fundamentally changing your JavaScript as the last stage of your deployment process is an obvious risk for introducing errors.

Tim Down
That's one reason why I want it to automatically minify on upload: so I'm always testing with what will be the actual production file.
Jarett
A: 

Realy cool solution whice make serving js and css automagically like a dream.

Check: http://code.google.com/p/minify/

Features

  • Combines and minifies multiple CSS or JavaScript files into a single download
    • Uses an enhanced port of Douglas Crockford's JSMin library and custom classes to minify CSS and HTML
    • Caches server-side (files/apc/memcache) to avoid doing unnecessary work
    • Responds with an HTTP 304 (Not Modified) response when the browser has an up-to-date cache copy
    • Most modules are lazy-loaded as needed (304 responses use minimal code)
    • Automatically rewrites relative URIs in combined CSS files to point to valid locations
    • With caching enabled, Minify is capable of handling hundreds of requests per second on a moderately powerful server.
    • Content-Encoding: gzip, based on request headers. Caching allows it so serve gzipped files faster than Apache's mod_deflate option!
    • Test cases for most components
    • Easy integration of 3rd-party minifiers
    • Separate utility classes for HTTP encoding and cache control enter code here
funktioneer
+1  A: 

I just wrote this minfier script in python. Like Bills solution, it uses the YUI compressor, but will work in a make-less environment. It assumes that the raw (unminifie) files will be in /some/path/src/, and that the minified versions should go in /some/path/. It also assumes that the yuicompressor jar file is in the current folder:

import os, glob
from subprocess import Popen,PIPE

def RunCommand( cmd, show_output  ):
    p = Popen(cmd, shell=True,stdout=PIPE,stderr=PIPE)
    for line in p.stdout:
     if show_output:
      print line


    outerr = "\n".join(p.stderr.readlines() ) 

    if len(outerr) > 0:
     print "ERROR: " + outerr
     sys.exit()

    code = p.wait()   
    if ( code > 0 ):
     print ("ERROR CODE: %i" % code )
     sys.exit()



compresser = "yuicompressor-2.4.2.jar"
dirs = [ "../wwwroot/css/", "../wwwroot/JavaScript/"]

extensions = ["*.js", "*.css" ]

for dir in dirs:
    src = dir + "/src/"
    for ext in extensions:  
     for path in glob.glob( os.path.join( src, ext)):
      file = os.path.basename(path)
      src_file = os.path.normpath( src + "/" +  file )
      dest_file = os.path.normpath( dir + "/" + file )
      if not os.path.isfile(dest_file) or os.path.getmtime(src_file) > os.path.getmtime(dest_file):
       print "minifying %s..." % (dest_file) 
       command = "java -jar %s %s -o %s" % ( compresser, src_file, dest_file )
       RunCommand(command, True)
Tristan Havelick
A: 

There's an even lighter solution for both (JS and CSS) so you can "minify on the fly". You should be able to port it easily to any language (it's currently in PHP). It's really a fragment and an integral part of the PHP Fat-Free Framework. Follow this link and have a look at my code. It's just a single function. Don't look for bells and whistles like combining files, base-X encoding, shortening of variables or even gzip-encoding (although that can be added easily).

Fat-Free Minify

stillstanding