我们最近从10.15.3升级到了节点12.2。函数的下面部分在10.15.3中工作正常,而在升级到12.2后开始解析不同,并引发“无效的销毁分配目标”语法错误。
未定义:1 (function(['context']){
SyntaxError:无效的销毁分配目标
功能:
function recompile(context) {
var previous = {values: context.previous};
previous.argnames = previous.values.map(function cmpArgNames(_, i) { return 'previous' + i });
previous.funcalls = previous.values.map(function cmpFunCalls(f, i) {
var args = (f.length === 1 ? '(recv)' : '(recv, args, context.storage)');
return previous.argnames[i] + args;
});
var future = {values: context.future};
future.argnames = future.values.map(function(_, i) { return 'future' + i });
future.funcalls = future.values.map(function(f, i) {
var args = (f.length === 2 ? '(recv, rval)' : '(recv, args, rval, context.storage)');
return future.argnames[i] + args;
});
var source = require('util').format(
' (function(%s) { \n return function(recv, args) { \n try{%s;}catch(e){logProbeErrorMessage(e, recv, context.target, true);} \n var rval = context.target.apply(recv, args); \n try{%s;}catch(e){logProbeErrorMessage(e, recv, context.target, null, true);} \n return rval; \n }; \n }) \n' ,
['context'].concat(previous.argnames).concat(future.argnames),
previous.funcalls.join(';\n'), future.funcalls.join(';\n'));
var args = [context].concat(previous.values).concat(future.values);
return eval(source).apply(null, args);
}
下面的“源代码”功能代码解析方式不同,并导致错误。
var source = require('util').format(
' (function(%s) { \n return function(recv, args) { \n try{%s;}catch(e){logProbeErrorMessage(e, recv, context.target, true);} \n var rval = context.target.apply(recv, args); \n try{%s;}catch(e){logProbeErrorMessage(e, recv, context.target, null, true);} \n return rval; \n }; \n }) \n' ,
['context'].concat(previous.argnames).concat(future.argnames),
previous.funcalls.join(';\n'), future.funcalls.join(';\n'));
下面是源变量的解析字符串:
10.15.3:
”
(function(context) {
return function(recv, args) {
try{;}catch(e){logProbeErrorMessage(e, recv, context.target, true);}
var rval = context.target.apply(recv, args);
try{;}catch(e){logProbeErrorMessage(e, recv, context.target, null, true);}
return rval;
};
})
”
12.2.0:
”
(function([ 'context' ]) {
return function(recv, args) {
try{;}catch(e){logProbeErrorMessage(e, recv, context.target, true);}
var rval = context.target.apply(recv, args);
try{;}catch(e){logProbeErrorMessage(e, recv, context.target, null, true);}
return rval;
};
})
”
我们可以区分出具有破坏性赋值的撇号(')保留在字符串中,这在12.2.0中引起了问题。 12.2.0发生了什么变化,我们该如何解决? 我希望在任何节点版本中输出都是相同的。
答案 0 :(得分:1)
基本上,您的问题可以简化为以下问题。 为什么在节点<= 11.x
require('util').format('test(%s)',['context'])
返回
test(context)
在Node 12.x +中,结果是
test([ 'context' ])
在内部,自format
的{{1}}版本开始使用util.inspect(),这在最近也得到了改进。
要解决您的问题,请使用例如
%s
或创建自己的数组格式化程序,以解决所有可能的情况。
有人可能会说新功能更加精确和确定。此外,它从未被锁定为合同。