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

Javascript UglifyJs-缩小的损坏变量在运行时恢复其原始名称,javascript,fabricjs,create-react-app,uglifyjs,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') minD

在我的代码库中,我有一个与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.renderal()
触发的,我在其中得到一个错误“Reference error:e未定义”。 该错误出现在执行
e.set('clipTo')
的回调期间

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

显然,如果解释器将输入参数重命名为
ctx
,则主体内的
e
没有定义;但这就像浏览器“知道”原来叫
e
的是
ctx
,这对我来说没有任何意义,除非Fabric(到处都使用
ctx
)对这个代码段的执行有某种影响

这在Chrome 65和Firefox 59中都得到了验证

为了避免出现
ctx
,我尝试了我能想象到的各种方法来更改源代码中的某些内容:

  • 在源代码中将
    ctx
    重命名为
    context
  • 将回调提取到一个单独的命名函数中
但仍然没有快乐


有人能解释一下为什么浏览器要重命名这个回调的输入变量吗?

这是一个很明显的意外。从来没有见过这样的事情,而且,很明显,似乎没有其他人对此有什么可说的

我找到的解决方案是在缩小过程中保护参数名
ctx

相关的UglifyJS配置为:

  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);
    });
}

这样,浏览器仍然会使用
ctx
覆盖输入参数名称,但在这种情况下,函数体在其执行过程中仍然有意义。

将其重命名,以缩短此变量的名称。I这种情况下,
ctx
是一个局部变量。在这种情况下,缩微器可以安全地重命名它。我问的是在执行过程中重命名变量,而不是在缩微过程中。请仔细阅读我的问题。