如何使用源映射从转译的代码中隐藏函数调用

How can I hide a function call from transpiled code using source maps?

本文关键字:代码 隐藏 函数调用 何使用 映射      更新时间:2023-09-26

假设我有一种语言看起来像

print "Hello World"

转译为

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string')
            throw new TypeError('String expected');
        console.log(s);
    }
};
$__Helpers.print("Hello World");

如果此语言的用户这样做

print 5
一个

类型错误将由$__Helpers.print说"预期字符串"抛出。 我希望开发人员工具将print 5行显示为此错误的原始调用。 我知道如何让我的源映射显示如下所示的调用堆栈

transpiled_script.js:2
original_script.os:1

其中transpiled_script.js:2是调用$__Helpers.print函数的脚本和行号,original_script.os:1是调用print 5的脚本和行号。 我想让开发工具忽略对transpiled_script.js的顶级调用(这只是我的转译器的实现细节(,只显示来自原始脚本的调用(这是他们应该在自己的脚本中调试的部分(。

我显然不能简单地将transpiled_script.js:2映射到original_script.os:1,因为original_script.os内部可能会有多个调用print,所以这不是 1 对 1 的关系。

有什么办法可以做到这一点吗?

(我正在使用 escodegen

来生成我的源代码和源映射(escodegen 使用 Node mozilla/source-map 模块(,所以有一种方法告诉 escodegen 或 mozilla/source-map 这样做是理想的,但如果不可能,我可以覆盖 escodegen 的输出。

您可以拆分跟踪并打印所需的行

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string'){
            var err = new TypeError('String expected');
            var trace = err.stack.split(''n')
            console.error(trace[0]); // TypeError: string expected
            console.error(trace[2]); // the line who called the function, probably 
            //original_script.os:1, or whatever line number the call was from
            //quit the script
        }
        console.log(s);
    } };

编辑:更好的解决方案是替换错误的跟踪,而不是抛出它,代码现在看起来像这样:

var $__Helpers = {
    print: function(s) {
        if (typeof s != 'string'){
            var err = new TypeError('String expected: Got'+s);
            err.stack = err.stack.replace(/'n.*transpiled_script'.js.*?'n/g,"'n");
            throw err;
        }
        console.log(s);
    } };

这也适用于嵌套调用中的错误。