Search code examples
javascriptjqueryyuiyui-compressor

YUI Compressor dropping semicolons in javascript


I'm using the following line to create a comrpessed version of a js with yuicompressor:

java -jar /home2/java/yuicompressor-2.4.2.jar --type js /home/site/libs/javascript/photos_functions.js >/home/site/libs/javascript/photos_functions-min.js

But for some reason, yui seems to be mis placing semicolons (;) all over the place. I've only started noticing it. It appears to be an occurance after using a jquery ajax function $ajax({});

What it seems to do is remove the semicolon, then add it to the next } (weird).

Anyone else seen this or no a way/option to fix it?

Example Before:

function photo_load_vs_breakdown(photo_id,page) {

    display_white_box('photo_vs_box');

    url =  SITEURL + "/libs/ajax/vs_mode_breakdown.php";
    params = 'photo_id='+photo_id+'&page='+page;



    $.ajax({ 
        url: url,
        cache:false, 
        type: 'POST',
        data: params,
        dataType: 'json',
        success: function(data) {

            if(page == 0){
                $('#photo_vs_box_contents').html(data.content);
            }
            else{

                newpage = page + 1;
                $('#vs_mode_wins').append(data.wins_append);
                $('#vs_mode_losses').append(data.lose_append);
                $('#vs_load_more').attr('onclick','photo_load_vs_breakdown('+photo_id+','+newpage+')');
                if(data.disable_vs_load_more == 'yes'){
                    $('#vs_load_more').attr('disabled','disabled');
                }

            }

        }
    }); 
}

Example After:

function photo_load_vs_breakdown(a,b){display_white_box("photo_vs_box");url=SITEURL+"/libs/ajax/vs_mode_breakdown.php";params="photo_id="+a+"&page="+b;$.ajax({url:url,cache:false,type:"POST",data:params,dataType:"json",success:function(c){if(b==0){$("#photo_vs_box_contents").html(c.content)}else{newpage=b+1;$("#vs_mode_wins").append(c.wins_append);$("#vs_mode_losses").append(c.lose_append);$("#vs_load_more").attr("onclick","photo_load_vs_breakdown("+a+","+newpage+")");if(c.disable_vs_load_more=="yes"){$("#vs_load_more").attr("disabled","disabled")}}}})};

Notice the location of the semi colon on the end.


Solution

  • What the YUI compressor seems to be doing here is not exactly misplacing or moving your semicolon but actually dropping the semicolons after the last expression in functions, and adding a single semicolon to the end of your code (to avoid problems when you concatenate two or more scripts together).

    For example this code:

    function x() { a(); b(); c(); }
    function y() { a(); b(); c(); }
    

    would get compressed to this code:

    function x(){a();b();c()}function y(){a();b();c()};
    

    Note that every last semicolon was removed in both functions but only one semicolon after the second function was added.

    See the Online JavaScript/CSS Compression Using YUI Compressor for some quick experiments. Also compare it with UglifyJS, another tool for JavaScript minification, which for this example outputs:

    function x(){a(),b(),c()}function y(){a(),b(),c()}
    

    See: UglifyJS readme for more options. (There is also a more advanced UglifyJS2 being developed.)