UglifyJs - 缩小的损坏变量在运行时恢复其原始名称
UglifyJs - minified mangled variable recovers at runtime its original name
在我的代码库中,我有与 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()
触发,我在其中收到错误 "Reference Error: e is not defined"。
在执行 e.set('clipTo')
.
的回调期间出现错误
令人惊奇的是,如果我检查调试器,我会看到回调被 运行 作为一个片段,其中输入参数被称为 ctx
而不是 e
.这是屏幕截图:
显然如果输入参数被解释器重命名为ctx
,那么body里面的e
就没有定义;但它就像浏览器 "knows" 最初调用 e
ctx
,这对我来说没有任何意义,除非 Fabric(到处使用 ctx
)以某种方式影响了这段代码的执行。
这在 Chrome 65 和 Firefox 59 中都得到验证。
我已经尽我所能地尝试更改源代码中的某些内容,以避免出现 ctx
:
- 在源代码中将
ctx
重命名为context
- 将回调提取到单独的命名函数中
但还是不开心
谁能解释为什么浏览器要重命名此回调的输入变量?
这是一个非常值得纪念的事故。从未见过这样的事情,而且显然没有其他人对此有任何看法。
我找到的解决方案是保护参数名称 ctx
在缩小过程中不被破坏。
相关的 UglifyJS 配置是:
mangle: {
except: ['ctx'],
},
创建以下 minified/prettified 代码:
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
覆盖输入参数名称,但在这种情况下,函数体在执行期间仍然有意义。
在我的代码库中,我有与 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()
触发,我在其中收到错误 "Reference Error: e is not defined"。
在执行 e.set('clipTo')
.
令人惊奇的是,如果我检查调试器,我会看到回调被 运行 作为一个片段,其中输入参数被称为 ctx
而不是 e
.这是屏幕截图:
显然如果输入参数被解释器重命名为ctx
,那么body里面的e
就没有定义;但它就像浏览器 "knows" 最初调用 e
ctx
,这对我来说没有任何意义,除非 Fabric(到处使用 ctx
)以某种方式影响了这段代码的执行。
这在 Chrome 65 和 Firefox 59 中都得到验证。
我已经尽我所能地尝试更改源代码中的某些内容,以避免出现 ctx
:
- 在源代码中将
ctx
重命名为context
- 将回调提取到单独的命名函数中
但还是不开心
谁能解释为什么浏览器要重命名此回调的输入变量?
这是一个非常值得纪念的事故。从未见过这样的事情,而且显然没有其他人对此有任何看法。
我找到的解决方案是保护参数名称 ctx
在缩小过程中不被破坏。
相关的 UglifyJS 配置是:
mangle: {
except: ['ctx'],
},
创建以下 minified/prettified 代码:
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
覆盖输入参数名称,但在这种情况下,函数体在执行期间仍然有意义。