升级到Nodejs 12.2后,无效的销毁分配目标异常

时间:2019-08-19 15:12:48

标签: node.js

我们最近从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发生了什么变化,我们该如何解决? 我希望在任何节点版本中输出都是相同的。

1 个答案:

答案 0 :(得分:1)

基本上,您的问题可以简化为以下问题。 为什么在节点<= 11.x

require('util').format('test(%s)',['context'])返回

test(context)

在Node 12.x +中,结果是

test([ 'context' ])

在内部,自format的{​​{1}}版本开始使用util.inspect(),这在最近也得到了改进。

要解决您的问题,请使用例如

%s

或创建自己的数组格式化程序,以解决所有可能的情况。

有人可能会说新功能更加精确和确定。此外,它从未被锁定为合同。