babel / minify

:scissors: An ES6+ aware minifier based on the Babel toolchain (beta)
https://babeljs.io/repl
MIT License
4.39k stars 225 forks source link

Unminified variable name used unexpectedly #866

Open Juribiyan opened 6 years ago

Juribiyan commented 6 years ago

minify unless you turn mangle off replaces the original variable names with one-letter names. But under some curcumstances it forgets to use the minified variable name and uses the unmodified variable name instead which leads to a ReferenceError since it's not defined.

To Reproduce

See configuration below. This does not occur in REPL.

Actual Output

String.prototype.toBlob = function() {
  try {
    for (var a = this.split(','), b = a[0].match(/:(.*?);/)[1], c = atob(a[1]), d = c.length, e = new Uint8Array(d); d--;) 
      e[d] = c.charCodeAt(d);
    return new Blob([u8arr], { type: mime }) 
  } 
  catch (a) {
    return console.error(a), !1 } 
}

This obviously produces a ReferenceError: u8arr is not defined.

Expected Output

Here's an actual ouput produced long time ago by "babel-cli": "6.18.0", "babel-preset-latest": "6.16.0" and "babel-preset-babili": "0.0.9"

String.prototype.toBlob = function() {
  try {
    for (var a = this.split(','), b = a[0].match(/:(.*?);/)[1], d = atob(a[1]), g = d.length, h = new Uint8Array(g); g--;) 
      h[g] = d.charCodeAt(g);
    return new Blob([h], {
      type: b
    })
  } catch (a) {
    return console.error(a), !1
  }
};

Configuration

To build, run npm run build.

Juribiyan commented 6 years ago

Updating to "babel-cli": "^7.0.0-beta.3" and "babel-preset-env": "^2.0.0-alpha.20" does not seem to help.

Cyp commented 6 years ago

Reduced testcase Doesn't trigger with var instead of let, and doesn't trigger without env or simplify.

function baz() {
    let foo = 42;
    while (bar) {
    }
    return foo;
}

Actual

"use strict";function baz(){for(;bar;);return foo}

Expected

"use strict";function baz(){for(;bar;);return 42}
nyk0r commented 6 years ago

Got a similar issue with the while loop in a method.

Source

_findContainer () {
    let view = this.view;
    while (view) {
        if (view.model && view.model.isSettingsContainer) {
            break;
        }
        view = view.parent;
    }
    return view;
}

Result

_findContainer: function _findContainer() {
    for (var a = this.view; a && !(a.model && a.model.isSettingsContainer); )
        a = a.parent;
    return view
}

Expected

_findContainer: function _findContainer() {
    for (var a = this.view; a && !(a.model && a.model.isSettingsContainer); )
        a = a.parent;
    return a
}

Environment

"@babel/core": "^7.0.0-beta.49",
"@babel/preset-env": "^7.0.0-beta.49",
"babel-preset-minify": "^0.4.3",
pmdartus commented 6 years ago

The issue appears to be fixed on the latest master.

Cyp commented 6 years ago

I can still reproduce the problem with my reduced testcase with latest master of babel and babel/minify, although the non-reduced testcases seem to be correct, now.

davidbonnet commented 6 years ago

This comment relates to previous issues with let and for loops: https://github.com/babel/minify/issues/485#issuecomment-291024057