amdclean icon indicating copy to clipboard operation
amdclean copied to clipboard

Enabling aggressive optimizations breaks modules with define("foo", foo)

Open gustavderdrache opened this issue 11 years ago • 2 comments

Given a module like D3, which has the following UMD stanza:

if (typeof define === "function" && define.amd) define(d3);
else if (typeof module === "object" && module.exports) module.exports = d3;
this.d3 = d3;

amdclean will, if aggressive optimizations are enabled and two modules refer to it, break the d3 identifier by overwriting it:

  if (true)
    _d3_ = d3 = function () {
      return typeof d3 === 'function' ? d3() : d3;
    }();

You can see the issue by entering the following example into the amdclean page:

// d3 UMD stanza
(function () {
  var d3 = {};

  if (typeof define === "function" && define.amd) define('d3', d3);
  else if (typeof module === "object" && module.exports) module.exports = d3;
  this.d3 = d3;
}());

// modules become candidates for hoisting
define('foo', ['d3'], function (d3) {
  reference(d3);
});

define('bar', ['d3'], function (d3) {
  reference(d3);
});

I've disabled aggressive optimizations to avoid the issue, but it seems a shame to lose the benefits over an edge case like this.

gustavderdrache avatar Feb 23 '15 17:02 gustavderdrache

Can you test to see if this is still an issue with AMDclean 2.6.0?

gfranko avatar Apr 02 '15 07:04 gfranko

Unfortunately, it is. If it helps any, I was able to narrow down the test case:

(function () {
  var foo;

  define('foo', {});
})()

The rewritten output clobbers the local foo instead of the module variable it probably intended to:

;(function() {
var foo;
(function () {
  var foo;
  foo = {};
}());
}());

gustavderdrache avatar Apr 02 '15 15:04 gustavderdrache