Blob.js icon indicating copy to clipboard operation
Blob.js copied to clipboard

YUI compression broken

Open eddiefletchernz opened this issue 10 years ago • 9 comments

The following two snippets are located in the same function:

if (view.Blob && view.URL) {
        try {
            new Blob;
            return;
        } catch (e) {}
    }
view.Blob = function Blob(blobParts, options) {
        var type = options ? (options.type || "") : "";
        var builder = new BlobBuilder();
        if (blobParts) {
            for (var i = 0, len = blobParts.length; i < len; i++) {
                builder.append(blobParts[i]);
            }
        }
        return builder.getBlob(type);
    };

When run through a minification tool (I am using the latest YUI), the first function (which checks for the presence of Blob in the browser) is compressed as:

if(a.Blob&&a.URL){try{new d;return}catch(c){}}

This is correct minification, as further down the file, a named function "Blob" is defined in the local scope (and is minified to the name "d")

Because "new Blob" is minified as "new d", an error will occur regardless of the browser's Blob support, thereby overwriting it with the shim instead of using the native implementation.

You can run an online version of the YUI compressor here: http://refresh-sf.com/yui/

To fix this issue, change:

view.Blob = function Blob(blobParts, options) {

to:

view.Blob = function (blobParts, options) {

I don't know if this will break anything else though. As far as I can tell it still works when you change this.

eddiefletchernz avatar Jul 01 '14 22:07 eddiefletchernz

FYI: That is NOT correct minification. In fact, if there were any real issue on that, the non-minimized code would cause some problem as well. At run time "Blob" is checked from the global scope since the polyfill isn't yet created and therefore any minificator should take that into account.

My advice, switch to a more robust and well tested minification tool.

diegocr avatar Jul 19 '14 20:07 diegocr

Please file a bug with the YUI compressor and link it here if you want to resolve the root issue. I will revert to the previous named function code once this issue is fixed upstream with YUI.

eligrey avatar Jul 19 '14 23:07 eligrey

https://github.com/yui/yuicompressor/issues/155

I think there's no need to revert d71ed78, though.

diegocr avatar Jul 19 '14 23:07 diegocr

Ok, thanks. I've subscribed to that issue.

eligrey avatar Jul 20 '14 20:07 eligrey

Because YUICompressor is implemented by compiling all JavaScript provided down to an AST (using Mozilla Rhino), there's no way to prevent YUICompressor from minifying browser-implementation objects like Blob short of using a parser hint, as mentioned in yui/yuicompressor#155. Some other JS compression engines do not actually compile the JS themselves, so they may not have this problem.

tml avatar Jul 30 '14 22:07 tml

Sounds like Rhino's AST representation is broken or YUI's handling of it, imo. The first Blob it runs into would be a different variable and scope from the next Blob.

eligrey avatar Jul 30 '14 22:07 eligrey

It's no different than the AST of any other javascript engine; node or spidermonkey would do the same things in this case.

tml avatar Jul 30 '14 23:07 tml

For this code as posted on https://github.com/yui/yuicompressor/issues/155

(function(view) {

    alert(typeof Test);

    view.test = function Test() {
        console.log(Test);
    };
})(this);

This is the relevant part of the AST representation:

"type" : "UnaryExpression",
"operator" : "typeof",
"argument" : {
    ...
    "type" : "Identifier",
    "name" : "Test"
},
...
"type" : "FunctionExpression",
"id" : {
    "loc" : null,
    "type" : "Identifier",
    "name" : "Test"
},

So, i highly doubt that's a bug on Rhino, but rather on YUICompressor wrongly interpreting the data.

diegocr avatar Jul 30 '14 23:07 diegocr

close?

jimmywarting avatar Apr 17 '19 22:04 jimmywarting