node-source-map-support:为 Node.js 和浏览器提供源码映射支持,优化堆栈跟踪显示

Adds source map support to node.js (for stack traces)

分支10Tags42
当前项目代码仓暂无内容

源代码映射支持

本模块通过V8堆栈追踪API为Node中的堆栈信息提供源代码映射支持。它使用source-map模块来替换源代码映射文件的路径与行号至其原本的值。输出格式模拟了Node的堆栈信息样式,旨在提升各类编译到JavaScript语言的地位,使其更受重视。由于源代码映射具有通用性,并不局限于特定编程语言,因此您可以在同一Node进程中使用多种编译到JavaScript的语言。

安装和用法

对于Node的支持

Node版本 ≥12.12.0

从Node 12.12.0起,不再需要此包,因为引入了--enable-source-maps标志。但请注意,如果您使用的是vm模块,则--enable-source-maps可能无法正常工作。

Node版本 <12.12.0

安装过程如下:

$ npm install source-map-support

可以通过库如source-map-index-generator生成源代码映射。一旦有了有效的源代码映射文件,在文件中某处放置一个源码映射注释(通常由转换器自动生成):

//# sourceMappingURL=path/to/source.map

如果单个文件中有多个源码映射URL注释,最后出现的那个将会被采用(例如,若一个文件在编码时提及了注释,或是经过了多次转译)。该路径应为绝对路径,或者相对于已编译的文件的位置。

接下来有两种选择。

命令行界面使用方式
node -r source-map-support/register compiled.js
程序化使用方式

在已编译文件的顶部加入以下一行:

require('source-map-support').install();

也可以直接加载register模块以启用源代码映射支持,这在ES6环境下尤为有用:

import 'source-map-support/register'

// 或者
import sourceMapSupport from 'source-map-support'
sourceMapSupport.install()

注意:如果您正在使用babel-register,其中已经包含了source-map-support。

对于Mocha测试框架而言也非常方便:

$ mocha --require source-map-support/register tests/

浏览器环境下的支持

此库同样适用于Chrome浏览器。尽管开发者工具控制台已经支持源代码映射,但是V8引擎本身并不支持,所以未加本库前Error.prototype.stack属性会显示错误的信息。只需使用browserify(http://browserify.org/)部署您的源文件即可让所有功能生效,记住在调用browserify命令时添加--debug参数,这样就可以确保编译后的代码中包含源代码映射。

即便您使用的是其他构建流程,或者是直接引用源代码文件,此库依然可以发挥作用。只需要在页面中包含browser-source-map-support.js文件并调用sourceMapSupport.install()函数。这个文件已经通过browserify进行了预处理,内含全部的浏览器端源代码映射支持功能。

<script src="browser-source-map-support.js"></script>
<script>sourceMapSupport.install();</script>

此外,本库也兼容AMD(异步模块定义),这是诸如RequireJS这样的工具所使用的模式。只需将browser-source-map-support指定为依赖项即可:

<script>
  define(['browser-source-map-support'], function(sourceMapSupport) {
    sourceMapSupport.install();
  });
</script>

配置选项

此模块实现了两个主要功能:一是修改Error对象中的stack属性;二是提供了一个类似于Node默认异常处理器的未捕获异常处理程序。如果您有自己的异常处理机制,或许希望禁用内置的处理程序。传递参数给安装器就能实现这一目的:

require('source-map-support').install({
  handleUncaughtExceptions: false
});

默认情况下,模块会从文件系统读取源代码映射数据。您可以设置回调函数来自定义读取行为,如下所示的例子中,Meteor就是将所有的源代码映射存储在内存中,以此避免频繁访问磁盘。

require('source-map-support').install({
  retrieveSourceMap: function(source) {
    if (source === 'compiled.js') {
      return {
        url: 'original.js',
        map: fs.readFileSync('compiled.js.map', 'utf8')
      };
    }
    return null;
  }
});

当XMLHttpRequest和window变量均被定义时,默认情况下模块假定自身运行于浏览器环境中。若二者不存在则假设是在Node环境下运行。然而在某些特殊场景下,比如正在进行浏览器仿真测试而两个全局变量又都存在的情况下,你可以显式地设定环境为browsernode

require('source-map-support').install({
  environment: 'node'
});

为了支持含有内联源代码映射的文件,还可以设置hookRequire选项,用来监控所有源文件中的内联源代码映射信息。

require('source-map-support').install({
  hookRequire: true
});

这种方法通过修补require模块加载链路实现,因此并未作为默认选项,也不建议用于生产环境。

示例演示

基础示例

original.js 文件内容:

throw new Error('test'); // 这是原生代码

compiled.js 文件内容:

require('source-map-support').install();

throw new Error('test'); // 这是编译后代码
// 下一行定义了源码映射信息。
//# sourceMappingURL=compiled.js.map

compiled.js.map 文件内容:

{
  "version": 3,
  "file": "compiled.js",
  "sources": ["original.js"],
  "names": [],
  "mappings": ";;AAAA,MAAM,IAAI"
}

运行compiled.js文件,观察堆栈信息如何指向original.js而非compiled.js文件:

$ node compiled.js

original.js:1
throw new Error('test'); // 这是原生代码
      ^
Error: test
    at Object.<anonymous> (original.js:1:7)
    at Module._compile (module.js:456:26)
    at Object.Module._extensions..js (module.js:474:10)
    ...

TypeScript示例

demo.ts 文件内容:

declare function require(name: string);
require('source-map-support').install();
class Foo {
  constructor() { this.bar(); }
  bar() { throw new Error('this is a demo'); }
}
new Foo();

在终端中利用TypeScript编译器编译并运行该文件:

$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc -sourcemap demo.ts
$ node demo.js

demo.ts:5
  bar() { throw new Error('this is a demo'); }
                ^
Error: this is a demo
    at Foo.bar (demo.ts:5:17)
    at new Foo (demo.ts:4:24)
    at Object.<anonymous> (demo.ts:7:1)
    ...

或者,您还可以在运行时使用-r source-map-support/register选项,无需在代码中手动添加require('source-map-support').install()语句:

$ npm install source-map-support typescript
$ node_modules/typescript/bin/tsc  -sourcemap demo.ts
$ node -r source-map-support/register demo.js

demo.ts:5
  bar() { throw new Error('this is a demo'); }
                ^
Error: this is a demo
    at Foo.bar (demo.ts:5:17)
    at new Foo (demo.ts:4:24)
    at Object.<anonymous> (demo.ts:7:1)
    ...

CoffeeScript示例

demo.coffee 文件内容:

require('source-map-support').install()
foo = ->
  bar = -> throw new Error 'this is a demo'
  bar()
foo()

在终端中利用CoffeeScript编译器编译并运行该文件:

$ npm install source-map-support coffeescript
$ node_modules/.bin/coffee --map --compile demo.coffee
$ node demo.js

demo.coffee:3
  bar = -> throw new Error 'this is a demo'
                     ^
Error: this is a demo
    at bar (demo.coffee:3:22)
    at foo (demo.coffee:4:3)
    at Object.<anonymous> (demo.coffee:5:1)
    ...

测试

此仓库同时包含针对 Node 的自动化测试和针对浏览器的手动测试。自动化测试可使用 Mocha 运行(在根目录下输入 mocha)。要运行手动测试:

许可证

本代码遵循 MIT 许可协议

项目介绍

为node.js添加源映射支持(用于堆栈跟踪)【此简介由AI生成】

定制我的领域
192.2 K222访问 GitHub