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.
String.prototype.toBlob = function() {
try {
let arr = this.split(',')
, mime = arr[0].match(/:(.*?);/)[1]
, bstr = atob(arr[1])
, n = bstr.length
, u8arr = new Uint8Array(n);
while(n--){
u8arr[n] = bstr.charCodeAt(n);
}
return new Blob([u8arr], {type:mime});
}
catch (e) {
console.error(e)
return false
}
}
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
{
"scripts": {
"build": "cross-env BABEL_ENV=production babel src --out-dir build --source-maps"
},
"devDependencies": {
"babel-cli": "^6.26.0",
"babel-preset-env": "^1.7.0",
"babel-preset-minify": "^0.4.3",
"cross-env": "^5.1.6"
}
}
{
"presets": [["env", {"modules": false, "comments": false}]],
"env": {
"production": {
"presets": ["minify"]
}
}
}
To build, run npm run build.
Updating to "babel-cli": "^7.0.0-beta.3" and "babel-preset-env": "^2.0.0-alpha.20" does not seem to help.
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}
Got a similar issue with the while loop in a method.
_findContainer () {
let view = this.view;
while (view) {
if (view.model && view.model.isSettingsContainer) {
break;
}
view = view.parent;
}
return view;
}
_findContainer: function _findContainer() {
for (var a = this.view; a && !(a.model && a.model.isSettingsContainer); )
a = a.parent;
return view
}
_findContainer: function _findContainer() {
for (var a = this.view; a && !(a.model && a.model.isSettingsContainer); )
a = a.parent;
return a
}
"@babel/core": "^7.0.0-beta.49",
"@babel/preset-env": "^7.0.0-beta.49",
"babel-preset-minify": "^0.4.3",
The issue appears to be fixed on the latest master.
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.
This comment relates to previous issues with let and for loops: https://github.com/babel/minify/issues/485#issuecomment-291024057