sourcemap使用

  sourcemap是什么以及怎么生成就不过多阐述了,这是之前看到的一篇文章感觉介绍的很详细:弄懂 SourceMap,前端开发提效 100%

浏览器加载sourcemap

  我们线上代码一般不会开启sourcemap,在排查线上的问题时,可以通过浏览器自带的能力加载sourcemap在这里插入图片描述

自建sourcemap服务

  在某些情况下我们没办法直接用浏览器加载sourcemap来使用,比如我们的监控平台捕获到了错误栈,但是页面不能复现,只能通过日志的相关信息来排查,此时便需要自建的sourcemap解析服务来处理了。我们可以通过source-map这个包处理。

/**
* 如其名, 用来消费sourcemap
*/
const {SourceMapConsumer} = require('source-map')
const fs = require('fs');
const path = require('path');

// 错误行
const LINE  = 1;
// 错误列
const COLUMN = 205;
// sourcemap文件路径
const ORIGIN_FILE_PATH = path.join(__dirname,'./sourcemap.js.map');
// sourcemap文件内容
const ORIGIN_FILE_CONTENT = fs.readFileSync(ORIGIN_FILE_PATH, 'utf-8');

/**
 * 解析Source Map文件
 * 通过文件读取的方式, 将sourcemap文件传入
 */
SourceMapConsumer.with(ORIGIN_FILE_CONTENT, null, consumer => {
    /**
     * originalPositionFor
     * 传入编译后文件的位置信息
     * 得到对应的源码位置信息
     */
  const originalPosition = consumer.originalPositionFor({
    source : fs.readFileSync(path.join(__dirname,'./sourcecode.js'), 'utf-8'),
    // 举例: 报错堆栈信息为, test.js:40:57515
    line: LINE,
    column: COLUMN
  });

  /**
   * originalPosition是一个对象, 包含定位到的
   * 源代码文件位置
   * 和具体定位的行列信息等
   */
  console.log('originalPosition:',originalPosition);

  /**
   * sourceContentFor 通过解析出的路径
   * 得到源代码的文本信息
   */
  const content = consumer.sourceContentFor(consumer.sources.find(source => source === originalPosition.source));

  /**
   * content就是对应的源代码的原始文本了
   */
  console.log('原始代码:',content);

  function getLineByIndex(str, lineIndex) {
    const lines = str.split(/\r?\n/); // 使用正则表达式兼容所有平台
    if (lineIndex >= 0 && lineIndex < lines.length) {
        return lines[lineIndex];
    } else {
        throw new Error("行索引超出范围");
    }
  }

  const errorLine = getLineByIndex(content, originalPosition.line - 1);
  console.log('具体报错行代码:',errorLine);

});

输出效果
在这里插入图片描述
根据上述信息, 我们可以扩展出一个功能更完善的工具
比如在团队内部部署一个微型服务, 自助上传souremap, 输入报错信息, 然后打印出具体的错误,还可以做报错代码的高亮展示等优化,更进一步地, 可以跟git直接关联起来, 导航到具体的报错文件, 更加直观。