在eval期间移动偏移(使用sourcemap)

时间:2017-07-05 13:21:47

标签: javascript node.js source-maps

我正在从文件加载脚本,并且我使用eval()生成如下的Javascript代码:

var code = fs.readFileSync('myfile');
var shiftedCode= 'function(param) {' + code + '}\n'+ '//# sourceURL=myfile';
eval(shiftedCode)

问题是当我在代码中放置一个断点或调试器时,它会在正确的一行之后停止两行,因为我想在开头添加了一个字符。

有没有办法将sourceURL转移到正确的起点可能正在使用源图?

提前感谢您的帮助。

4 个答案:

答案 0 :(得分:11)

定义问题

我发现您正在尝试将Javascript代码从一个页面导入到另一个页面,并且您遇到了一些问题(您定义了一个问题,我将定义另一个问题):

  1. 源图/调试器问题
    • 首先 ,我不建议在运行时构建源图。 GulpGruntWebpack等工具可以帮助您处理这些用例,并让您专注于业务逻辑,让您远离这些问题。
    • 第二次 考虑一下将在另一个页面中使用此代码的人。你认为改变源图会没问题吗?这将是每一次转变!
    • 可能的解决方案: lib也可以帮助您处理用例。首先生成新代码,然后运行它。
  2. 
    
    var offsetLines = require('offset-sourcemap-lines');
    var conv = require('convert-source-map');
    var fs = require('fs');
    var code = fs.readFileSync('myfile');
    var originalMap = conv.fromSource(code).toObject();
    var codeBody = conv.removeComments(code);
    var offsettedMap = offsetLines(originalMap, 1); // One line to be shifted
    var newSourceMapComment = conv.fromObject(offsettedMap).toComment();
    var shiftedCode= 'function(param) {\n' + codeBody + '}\n' + newSourceMapComment;
    eval(shiftedCode)
    
    
    

    1. 小心!您正在使用危险的eval()
      • 使用eval()可以打开一个程序,最多可以进行几次不同的注入攻击。在大多数情况下使用eval()可以替代问题的更好的替代方法。
      • 导致代码缓慢。
      • MDN: Don't use eval() needlessly!
          

        eval()是一个危险的函数,它执行它以调用者的特权传递的代码。如果您使用可能受恶意方影响的字符串运行eval(),您最终可能会使用您的网页/扩展程序的权限在用户的计算机上运行恶意代码。更重要的是,第三方代码可以看到eval()被调用的范围,这可能导致类似功能不易受影响的可能攻击。

          eval()通常比替代方案慢,因为它必须调用JS解释器,而许多其他结构由现代JS引擎优化。

          对于常见用例,eval()有更安全(和更快!)的替代方案。

    2. 推荐

      正如我们所说,您正在尝试导入一些代码。那么,为什么不使用像AMD,RequireJS,CommonJS,ES6模块功能这样的Javascript模块化系统呢......

      假设您使用ES6 modules,那将非常直截了当。您需要将myfile脚本导出为模块并将其导入任何位置并将其导入

      //  myfile.js
      export function sum (x, y) { return x + y }
      
      //  someApp.js
      import {sum} from "myfile"
      console.log(sum(10, 20));
      

答案 1 :(得分:0)

您可以使用以下包offset-sourcemap-lines

var offsetLines = require('offset-sourcemap-lines');
var conv = require('convert-source-map');
var fs = require('fs');

var codeWithSourceMapComment = fs.readFileSync('/path/to/code-with-sourcemap-comment.js', 'utf-8');
var originalMap = conv.fromSource(codeWithSourceMapComment).toObject();

var header = 'function(param) {' + code + '}\n';
var offset = header.match(/\n/g).length + 2; //you might need to work on this

var offsettedMap = offsetLines(originalMap, offset);

var codeBody = conv.removeComments(codeWithSourceMapComment);
var newSourceMapComment = conv.fromObject(offsettedMap).toComment();
console.log(header + codeBody + '\n' + newSourceMapComment);

答案 2 :(得分:0)

那个解决方案怎么样?而不是使用eval使用Function constructor

运行代码

myfile.js

var a = 123;
console.log(a, param1, param2);

loader.js

var code = fs.readFileSync('myfile.js');
var notShiftedCode = code + '\n//# sourceURL=myfile' 
var f = new Function('param1', 'param2', code2)

f(456,678)

我在chrome devtool上检查了它,看起来非常不合适(使用F11进入功能)

答案 3 :(得分:0)

我正在深入挖掘源图'部分' 属性。根据规范,这可以通过设置起始偏移量来解决我的问题:https://docs.google.com/document/d/1U1RGAehQwRypUTovF1KRlpiOFze0b-_2gc6fAH0KY0k/edit#heading=h.535es3xeprgt

但主要的问题是我无法使用此规范找到调试工具:似乎已广泛实施或根本没有。

'偏移sourcemap线'是解决问题的有价值的黑客,但它也可以在合并期间抵消相关的源映射。