UglifyJs - 缩小的变形变量在运行时恢复其原始名称

时间:2018-04-20 10:12:57

标签: javascript fabricjs create-react-app uglifyjs

在我的代码库中,我有这个与fabric.js交互的自定义​​代码:

export function cropToCircle(object) {
    let minDim = Math.min(object.width, object.height);
    window.lastMinDim = minDim;
    return object.set('clipTo', ctx => {
        if (typeof minDim === 'undefined') minDim = window.lastMinDim || 1000;
        ctx.arc(0, 0, minDim / 2, 0, Math.PI * 2, true);
    });
}

uglify.js将它缩小为这个字符串,我在这里给它做了美化:

function s(e) {
    var t = Math.min(e.width, e.height);
    return window.lastMinDim = t, e.set('clipTo', function (e) {
        'undefined' === typeof t && (t = window.lastMinDim || 1e3), e.arc(0, 0, t / 2, 0, 2 * Math.PI, !0);
    });
}

在运行时,这个缩小的代码在大多数调用中运行良好。但有一个是由Fabric canvas.renderAll()触发的,其中我收到错误“参考错误:e未定义”。 在执行e.set('clipTo')的回调期间出现错误。

令人惊奇的是,如果我签入调试器,我会看到回调是作为一个片段运行的,其中输入参数被称为ctx而不是e。这是屏幕截图:

ctx is back

显然,如果解释器将输入参数重命名为ctx,则正文中的e没有定义;但它就像浏览器“知道”原来e被称为ctx,这对我没有任何意义,除非Fabric(在整个地方使用ctx)以某种方式影响该片段的执行。

这已在Chrome 65和Firefox 59中得到验证。

为了避免ctx的出现,我试图以各种方式尝试改变源代码中的某些内容:

  • 在源代码
  • 中将ctx重命名为context
  • 将回调提取为分离的命名函数

但仍然没有快乐。

有人可以解释为什么浏览器会重命名此回调的输入变量吗?

1 个答案:

答案 0 :(得分:1)

这是一次非常可重复的事故。从来没有见过这样的事情,显然,似乎没有其他任何人可以谈论它。

我找到的解决方案是在缩小过程中保护参数名称boolean init = true; layoutBottomSheet.addOnLayoutChangeListener(new View.OnLayoutChangeListener() { @Override public void onLayoutChange(View view, int i, int i1, int i2, int i3, int i4, int i5, int i6, int i7) { if(init)hideBottomSheet(); init=false; } }); 不被破坏。

相关的UglifyJS配置为:

ctx

创建以下缩小/美化代码:

  mangle: {
    except: ['ctx'],
  },

这样浏览器仍然用function s(e) { var t = Math.min(e.width, e.height); return window.lastMinDim = t, e.set('clipTo', function (ctx) { 'undefined' === typeof t && (t = window.lastMinDim || 1e3), ctx.arc(0, 0, t / 2, 0, 2 * Math.PI, !0); }); } 覆盖输入参数名称,但在这种情况下,函数体在执行期间仍然有意义。