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

Minify does not properly define variables for while loops: #966

Open KamalAman opened 5 years ago

KamalAman commented 5 years ago

Describe the bug arr is undefined in the minified code

To Reproduce

function getNDArray(size) {
  const arr = [];

  while (size) {
    size -= 1;
    arr.push([]);
  }

  return arr;
}

module.exports = getNDArray;

Actual Output

function getNDArray(a) {
  for (var b = []; a;)a -= 1, b.push([]); 
  return arr
} 
module.exports = getNDArray;

Expected Output

function getNDArray(a) {
 var b = [];
  for (a) a -= 1, b.push([]); 
  return b
} 
module.exports = getNDArray;

Configuration

"@babel/cli": "7.6.4", "@babel/core": "7.6.4", "babel-preset-minify": "0.5.1", babelrc:

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "modules": "commonjs",
      }
    ],
    "@babel/preset-react",
    ["minify", { "builtIns": false }]
  ]
}

Switching the while loop to a for loop fixes the symptoms of the problem.

skirtles-code commented 4 years ago

I ran into the same problem.

There are two plugins involved here. simplify is the one that rewrites the while to a for and mangle then incorrectly renames the identifier.

Personally I turned off simplify:

["minify", {
  "builtIns": false,
  "simplify": false
}]

Alternatively, you could turn off mangle:

["minify", {
  "builtIns": false,
  "mangle": false
}]

You can target just a single identifier, though that seems much too fragile to me:

["minify", {
  "builtIns": false,
  "mangle": {
    "exclude": {"arr": true}
  }
}]