Minify: Replace well-defined variable with undefined in for statement

Created on 27 Jun 2018  路  7Comments  路  Source: babel/minify

Context

I use Vue.js, and when I replace process.env.NODE_ENV with 'production', and minify my bundle with babel-preset-minify the resulting code is broken in this function actuallySetSelected, and more precisely the i < l expression in the for statement is replaced with i < undefined.

Steps to reproduce

I use:

  • @babel/core v7.0.0-beta.51;
  • babel-preset-minify v0.4.3.

With this config for babel-preset-minify:

{
  evaluate: true,
  simplify: true,
  mergeVars: true,

  removeUndefined: false,
  deadcode: false,
  booleans: false,
  builtIns: false,
  consecutiveAdds: false,
  flipComparisons: false,
  guards: false,
  infinity: false,
  mangle: false,
  memberExpressions: false,
  numericLiterals: false,
  propertyLiterals: false,
  regexpConstructors: false,
  replace: false,
  simplifyComparisons: false,
  typeConstructors: false,
  undefinedToVoid: false
}

I've simplified the test case:

Input

function test () {
  if (false) return
  var i
  for (var l=1; i < l; i++) {}
}

Expected output

function test(){if(true)for(var i,l=1;i<l;i++);}

Actual output

function test(){if(true)for(var i,l=1;i<undefined;i++);}

It seems I've managed to reduce it to an interaction between those three plugins:

You can pull this repo to test it for yourself.

needs info

Most helpful comment

@trevor-bliss and I just ran into the same issue.

All 7 comments

The latest master minifies it to

function test () {
  for(var a;a<1;a++);
}

which looks like the correct output. Can you confirm if there is a mistake in the input?

That's very surprising, I didn't make a mistake in the input, if you want to reproduce with 0.4.3, I encourage you to pull this repo, and run npm i && npm start && cat build/dest.js, it produces the buggy output referenced in my bug report.

I tried to pull and build the latest master of babel-preset-minify and link it in the test case, it produces the same buggy output.

To add a bit more context, I have this bug on macOS 10.13.5 and node 10.2.1.

I think I run into the same problem. Here's a simple way to reproduce it: In a empty directory create a file called main.js:

function sum(list) {
        if (list.length === 0) return;
        var result = 0;
        for (var i = 0, len = list.length; i < len; i++)
                result += list[i];
    return result;
}

Then install babel-minify via npm i babel-minify (which installs [email protected] as of this writing) and run ./node_modules/.bin/minify main.js which will produce the following output:

function sum(a){if(0!==a.length){for(var b=0,c=0,d=a.length;c<void 0;c++)b+=a[c];return b}}

This is not equivalent to the original code because the condition i < len of the original loop has been minified to c<void 0, which is always false and the loop never runs.

I run the above steps on a x86_64 linux machine with node-8.11.3.

@redneb out of curisity and since @boopathi doesn't seem to be able to reproduce, could you try reproducing the test case I linked in my bug report? Here is the link https://github.com/tex0l/bug-report-babel. You just need to clone the repo and run npm i && npm start && cat build/dest.js, then check if you have something that looks like function test(){if(true)for(var i,l=1;i<undefined;i++);}

By the way, I've worked around the bug by setting to false one of the following options in the preset:

{
  evaluate: true,
  simplify: true,
  mergeVars: true
}

I also ran into the same problem... Running Vuejs code through babel-minify produces broken output when NODE_ENV = 'production'.

I can also reproduce the bug with @tex0l 's test case. Well done simplifying the test-case !

I noticed version 0.5.0 just got out, I updated the test case here: https://github.com/tex0l/bug-report-babel

@boopathi : the bug still exists in the latest version.

@trevor-bliss and I just ran into the same issue.

Was this page helpful?
0 / 5 - 0 ratings