6

I'm using a shared hosting plan on Hostgator. As such I can't run any java from the command line.

Is there any pure PHP minifiers out there that I can use? Minify uses YUICompressor.jar in the background so that won't work.

Anyone know of something that uses just PHP to minify javascript that I can run from the command line? I would also like it to shrink variable names.

qwertymk
  • 34,200
  • 28
  • 121
  • 184

4 Answers4

3

You could use the google js minifier. Here's a python script which uses it to compress a bunch of javascript files with it:

import httplib
import simplejson as json
import urllib
import sys

def combine_js(js_files, minify=False):
    files = list(js_files) # create a copy which we can modify
    if not minify:
        code = []
        for path in files:
            f = open(path, 'r')
            code.append(f.read())
            f.close()
        return '\n\n'.join(code)

    def _minify(code):
        params = urllib.urlencode([
            ('js_code', code),
            ('compilation_level', 'SIMPLE_OPTIMIZATIONS'),
            ('output_format', 'json'),
            ('output_info', 'compiled_code'),
            ('output_info', 'errors'),
            ('output_info', 'warnings'),
        ])

        headers = {'Content-type': "application/x-www-form-urlencoded"}
        conn = httplib.HTTPConnection('closure-compiler.appspot.com')
        conn.request('POST', '/compile', params, headers)
        response = conn.getresponse()
        data = json.loads(response.read())
        conn.close()
        if not data.get('compiledCode'):
            print >>sys.stderr, 'WARNING: Did not get any code from google js compiler.'
            print >>sys.stderr, data
            print >>sys.stderr
            print >>sys.stderr, 'Using unminified code'
            return None
        return data.get('compiledCode')

    # Minify code in chunks to avoid the size limit
    chunks = []
    code = ''
    while len(files):
        path = files[0]
        f = open(path, 'r')
        data = f.read()
        f.close()
        # Check if we reach the size limit
        if len(code + data) >= 1000000:
            res = _minify(code)
            if res is None:
                # Fallback to unminified code
                return combine_js(js_files)
            chunks.append(res)
            code = ''
            continue
        code += data
        del files[0]
    if code:
        res = _minify(code)
        if res is None:
            # Fallback to unminified code
            return combine_js(js_files)
        chunks.append(res)
    return '\n\n'.join(chunks).strip()

if __name__ == '__main__':
    print combine_js(sys.argv[1:], True)

Usage: python filename.py path/to/your/*.js > minified.js


In case you are using an ancient python version and do not have simplejson installed on your system, here's how you can get the script to work with a local simplejson version (run those commands via SSH):

cd
wget http://pypi.python.org/packages/source/s/simplejson/simplejson-2.3.2.tar.gz
tar xzf simplejson-2.3.2.tar.gz
export PYTHONPATH=$HOME/simplejson-2.3.2/
ThiefMaster
  • 310,957
  • 84
  • 592
  • 636
  • It's from one of my website that runs in production. I just removed some stuff around it and added the standalone `__main__` block. I did not test *that* version but the original script. – ThiefMaster Feb 19 '12 at 17:56
  • Ah, just fixed the syntax error. It was just a `,` that didn't belong at its place. The error you get means you are using an old python version. You need at least 2.6 to run it (which is already pretty old, 2.7 is recent!) – ThiefMaster Feb 19 '12 at 17:58
  • I'm still getting this error, File "python.py", line 11 with open(path, 'r') as f: ^ SyntaxError: invalid syntax. Any workaround? – qwertymk Feb 19 '12 at 18:01
  • Does it help if I'll only be running one file through at a time? – qwertymk Feb 19 '12 at 18:03
  • No. I just changed it to not use `with`; it might now work with older python versions. – ThiefMaster Feb 19 '12 at 18:07
  • Almost the same error, not it's pointing to the `:`, would it help if I pass in the entire js code as a command line arg? – qwertymk Feb 19 '12 at 18:10
  • let us [continue this discussion in chat](http://chat.stackoverflow.com/rooms/7917/discussion-between-thiefmaster-and-qwertymk) – ThiefMaster Feb 19 '12 at 18:11
  • http://stackoverflow.com/questions/2604841/importerror-no-module-named-simplejson > for the simplejson issue – Meetai.com Oct 24 '12 at 01:06
1

Minify's default is not YUIC, but a native PHP port of JSMin plus bug fixes.

Other native PHP Javascript compressors I've come across:

  • JSqueeze (untested, but looks powerful)
  • JShrink (untested, but a simple token-remover design, like JSMin)
  • JSMin+ (does not preserve /*! comments, mangles conditional comments)
Steve Clay
  • 8,671
  • 2
  • 42
  • 48
1

If you consider other javascript minifiers/compressors, take a look at a PHP port of dean edward's packer: http://joliclic.free.fr/php/javascript-packer/en/

There is an online demo available so you can test it online (highly recommended before you try to install it on your own server). I quick online test gave me back a correct working minified javascript file. It should get the job done.

Cecil Zorg
  • 1,478
  • 13
  • 15
0

Find an online web based JS minifier, and query their <form> through PHP with cURL or file_get_contents or similar. I suppose you may have to ask the online service for permission before using their service in this way.

Vitamin
  • 1,526
  • 1
  • 13
  • 27