Rich-Harris / butternut

The fast, future-friendly minifier
https://butternut.now.sh
MIT License
1.17k stars 17 forks source link

Bug: Unused variables containing anonymous functions #158

Open loilo opened 7 years ago

loilo commented 7 years ago

This one is a little bit tricky because I can't really tell what's the root cause for this, it's probably related to #134.


The situation: Butternut removes an unused variable (any_value_2 in the examples below) but sometimes keeps its value, an anonymous function.

That's obviously not the right thing to do since a standalone unnamed function isn't valid JavaScript. However, I don't know exactly when the function is actually kept.

Example 1

The function seems to be kept when there's a variable declaration with an assigned function call each before and also after the anonymous function.

Input:

function wrapper () {
  var any_value_1 = any_fn_1()
  var any_value_2 = function () {
    // Really anything
  }
  var any_value_3 = any_fn_2()
}

Output Butternut 0.4.6:

function wrapper(){any_fn_1();function(){};any_fn_2()}

Output UglifyJS 3.0.8:

function wrapper(){any_fn_1(),any_fn_2()}

Example 2

The function also will be kept if its body keeps a reference to a local variable that has been defined before the function (but still inside the wrapper function) and there's a variable declaration with an assigned function call after.

Input:

function wrapper () {
  var any_value_1
  var any_value_2 = function () {
    any_value_1
  }
  var any_value_3 = side_effected()
}

Output Butternut 0.4.6:

function wrapper(){var n;function(){n};side_effected()}

Output UglifyJS 3.0.8:

function wrapper(){side_effected()}
hrdinka commented 7 years ago

In this example the bug is triggered by calling the anonymous function:

Input

(function() {

var v = function() {
    return 1;
}();

})

Output Butternut 0.4.6:

(function(){function(){return 1}()})