我将首先显示代码(节点10.15.3):
var ts = require("typescript");
require('source-map-support').install({
environment: 'node',
hookRequire: true
})
var content = "let a = 0;\n\nb = b * a";
var compilerOptions = {
module: ts.ModuleKind.CommonJS,
inlineSourceMap: true
};
var res1 = ts.transpileModule(content, {
compilerOptions: compilerOptions,
moduleName: "myModule2"
});
console.log(res1);
console.log('-------')
console.log(content)
console.log('-------')
console.log(res1.outputText)
console.log('-------')
eval(res1.outputText)
作为执行此代码的结果,我希望具有与给定内容变量相关的回溯(第3行中的错误),但是我不断在第2行中收到错误-这是代码的编译版本中的错误行。
这是输出
{ outputText:
'var a = 0;\nb = b * a;\n//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUVWLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBIn0=',
diagnostics: [],
sourceMapText: undefined }
-------
let a = 0;
b = b * a
-------
var a = 0;
b = b * a;
//# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoibW9kdWxlLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsibW9kdWxlLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLElBQUksQ0FBQyxHQUFHLENBQUMsQ0FBQztBQUVWLENBQUMsR0FBRyxDQUFDLEdBQUcsQ0FBQyxDQUFBIn0=
-------
SS: /root/ts-eval/exal.js undefined
SS: internal/modules/cjs/loader.js undefined
SS: internal/bootstrap/node.js undefined
ReferenceError: b is not defined
at eval (eval at <anonymous> (/root/ts-eval/exal.js:24:1), <anonymous>:2:1)
at Object.<anonymous> (/root/ts-eval/exal.js:24:1)
at Module._compile (internal/modules/cjs/loader.js:701:30)
at Object.Module._extensions..js (internal/modules/cjs/loader.js:712:10)
at Module.load (internal/modules/cjs/loader.js:600:32)
at tryModuleLoad (internal/modules/cjs/loader.js:539:12)
at Function.Module._load (internal/modules/cjs/loader.js:531:3)
at Function.Module.runMain (internal/modules/cjs/loader.js:754:12)
at startup (internal/bootstrap/node.js:283:19)
at bootstrapNodeJSCore (internal/bootstrap/node.js:622:3)
答案 0 :(得分:3)
您正在使用内联源映射,并且documentation处于source-map-support
状态:
要支持带有内联源地图的文件,可以指定
hookRequire
选项,该选项将监视所有源文件中的内联源地图。
您已将hookRequire
设置为true。但是,我引用的段落表明source-map-support
依赖于钩接到require
来检测内联源映射,因此,如果您的代码在未通过require
的情况下执行,则其源映射将不会被检测到,source-map-support
将无法修复堆栈跟踪。的确,如果我用以下代码替换您的eval
呼叫:
fs.writeFileSync("myModule2.js", res1.outputText);
require("./myModule2");
我得到了这样的堆栈跟踪,并带有正确的行号:
ReferenceError: b is not defined
at Object.<anonymous> (/tmp/t4/module.ts:3:1)
[...]
文件名为module.ts
,因为尚未为fileName
指定选项ts.transpileModule
。您可以将其设置为myModule2.ts
,以与moduleName
保持一致。
此外,如果您更改编译器选项以也内联源代码,如下所示:
var compilerOptions = {
module: ts.ModuleKind.CommonJS,
inlineSourceMap: true,
inlineSources: true,
};
您可以获得更好的堆栈跟踪。使用上面显示的compilerOptions
和我之前建议的fileName
,跟踪为:
/tmp/t4/myModule2.ts:3
b = b * a
^
ReferenceError: b is not defined
at Object.<anonymous> (/tmp/t4/myModule2.ts:3:1)
您可以在ReferenceError
之前看到引起问题的代码行的引用。
以上方法是导致source-map-support
修复源引用的最简单方法。这是另一种更复杂的方法,不需要将任何文件保存到磁盘,但是需要自定义source-map-support
从源文件路径获取源代码的方式。来源中的注释表明了新零件的作用。
const fs = require("fs");
const ts = require("typescript");
const vm = require("vm");
const path = require("path");
// This establishes a mapping between sourcePaths and the actual source.
const sourcePathToSource = Object.create(null);
require("source-map-support").install({
environment: "node",
// Pass to source-map-support a custom function for retreiving sources
// from source paths. This runs after source-map-support's default logic,
// only if that logic fails to find the requested source.
retrieveFile: (sourcePath) => sourcePathToSource[sourcePath],
});
const content = "let a = 0;\n\nb = b * a";
const compilerOptions = {
module: ts.ModuleKind.CommonJS,
sourceMap: true,
inlineSources: true,
};
// The path that the ts module would have.
const tsPath = path.resolve("myModule2.ts");
const res1 = ts.transpileModule(content, {
compilerOptions: compilerOptions,
fileName: tsPath,
moduleName: "myModule2"
});
console.log(res1);
console.log("-------");
console.log(content);
console.log("-------");
console.log(res1.outputText);
console.log("-------");
// The path that the compiled module would have.
const jsPath = path.resolve("myModule2.js");
// Establish the relationship between the path and the source.
sourcePathToSource[jsPath] = res1.outputText;
// Ditto for the source map file.
sourcePathToSource[path.resolve("myModule2.js.map")] = res1.sourceMapText;
vm.runInThisContext(res1.outputText, {
filename: jsPath,
});
运行上面的代码将得到以下输出:
/tmp/t4/myModule2.js:2
b = b * a;
^
ReferenceError: b is not defined
at /tmp/t4/myModule2.ts:3:1
at Script.runInThisContext (vm.js:123:20)
[...]
source-map-support
修改了堆栈跟踪中的源行号,以使其指向正确的位置,但是一开始的源引用没有被修改。问题在于source-map-support
使用的正则表达式。正则表达式要求将源文件引用括在括号中(例如(vm.js:123:20)
)。我尝试在source-map-support
到达异常之前对其进行转换,以使其适合正则表达式,但source-map-support
无法看到该转换。