combine javascript files at deployment in python
Question: I'm trying to reduce the number of scripts included in our website and we use
buildout to handle deployments. Has anybody successfully implemented a method
of combining and compressing scripts with buildout?


Answer: Here's a Python script I made that I use with all my heavy JavaScript
projects. I'm using YUICompressor, but you can change the code to use another
compressor.

    
    
    import os, os.path, shutil
    
    YUI_COMPRESSOR = 'yuicompressor-2.4.2.jar'
    
    def compress(in_files, out_file, in_type='js', verbose=False,
                 temp_file='.temp'):
        temp = open(temp_file, 'w')
        for f in in_files:
            fh = open(f)
            data = fh.read() + '\n'
            fh.close()
    
            temp.write(data)
    
            print ' + %s' % f
        temp.close()
    
        options = ['-o "%s"' % out_file,
                   '--type %s' % in_type]
    
        if verbose:
            options.append('-v')
    
        os.system('java -jar "%s" %s "%s"' % (YUI_COMPRESSOR,
                                              ' '.join(options),
                                              temp_file))
    
        org_size = os.path.getsize(temp_file)
        new_size = os.path.getsize(out_file)
    
        print '=> %s' % out_file
        print 'Original: %.2f kB' % (org_size / 1024.0)
        print 'Compressed: %.2f kB' % (new_size / 1024.0)
        print 'Reduction: %.1f%%' % (float(org_size - new_size) / org_size * 100)
        print ''
    
        #os.remove(temp_file)
    

I use it like this (the below is just a code snippet, and assumes that the
`compress` function exists in the current namespace):

    
    
    SCRIPTS = [
        'app/js/libs/EventSource.js',
        'app/js/libs/Hash.js',
        'app/js/libs/JSON.js',
        'app/js/libs/ServiceClient.js',
        'app/js/libs/jquery.hash.js',
        'app/js/libs/Application.js',
        'app/js/intro.js',
        'app/js/jquery-extras.js',
        'app/js/settings.js',
        'app/js/api.js',
        'app/js/game.js',
        'app/js/user.js',
        'app/js/pages.intro.js',
        'app/js/pages.home.js',
        'app/js/pages.log-in.js',
        'app/js/pages.log-out.js',
        'app/js/pages.new-command.js',
        'app/js/pages.new-frame.js',
        'app/js/pages.not-found.js',
        'app/js/pages.register.js',
        'app/js/pages.outro.js',
        'app/js/outro.js',
        ]
    SCRIPTS_OUT_DEBUG = 'app/js/multifarce.js'
    SCRIPTS_OUT = 'app/js/multifarce.min.js'
    
    STYLESHEETS = [
        'app/media/style.css',
        ]
    STYLESHEETS_OUT = 'app/media/style.min.css'
    
    def main():
        print 'Compressing JavaScript...'
        compress(SCRIPTS, SCRIPTS_OUT, 'js', False, SCRIPTS_OUT_DEBUG)
    
        print 'Compressing CSS...'
        compress(STYLESHEETS, STYLESHEETS_OUT, 'css')
    
    if __name__ == '__main__':
        main()
    

