前端线上怎么定位bug位置

由于现在构建工具盛行,前端部署的代码都是经过编译,压缩后的,于是乎,SoueceMap就扮演了一个十分重要的角色,用来作为源代码和编译代码之间的映射,方便定位问题。

1、生产环境为什么要关闭SourceMap?

虽然map文件提供了便利,但是在生产环境,为了安全,是建议关闭SourceMap的,因为通过.map文件和编译后代码可以很容易反编译出项目的源码,这样就相当于泄露了项目的代码。下面做个测试:

首先全局安装reverse-sourcemap

npm install --global reverse-sourcemap

选择编译后的代码进行测试,下面是vue项目编译生成的代码。
在这里插入图片描述
在命令行执行命令,将main.js反编译回源码,并输出到sourcecode目录下。

reverse-sourcemap -v dist/main.a8ebc11c3f03786d8e3b.js.map  -o sourcecode

在这里插入图片描述

上面是执行命令输出的sourcecode目录,生成的目录结构和源码目录一致,打开一个文件,和源码做下对比:
在这里插入图片描述

可以看出,反编译出的代码无论目录结构还是具体代码都和源码一致。

2、生产环境代码报错如何定位源码位置

生产环境的代码,经过压缩、编译,很不利于debug。由于生产环境没有配置SourceMap,所以代码报错时,或是通过Fundebug,Sentry等工具搜集到的报错信息,得到报错代码的行和列都是编译后的代码,这样很不易于定位问题。

在这里插入图片描述
针对这个问题,需要准备一份生产环境代码的map文件,为了方便,可以在项目的package.json增加debug命令用来生成map文件。这条命令除了开启sourcemap,其他的具体webpack配置和生产环境配置相同。

  "scripts": {
        "start": "vue-cli-service serve --mode dev",
        "stage": "vue-cli-service build --mode staging",
        "online": "vue-cli-service build",
        "debug": "vue-cli-service build --mode debug"
    },

有了map文件,通过SourceMap提供的API就可以定位到源码的位置。下面是实现的核心代码。

// Get file content
const sourceMap = require('source-map');
const readFile = function (filePath) {
  return new Promise(function (resolve, reject) {
    fs.readFile(filePath, {encoding:'utf-8'}, function(error, data) {
      if (error) {
        console.log(error)
        return reject(error);
      }
      resolve(JSON.parse(data));
    });
  });
};

// Find the source location
async function searchSource(filePath, line, column) {
  const rawSourceMap = await readFile(filePath)
  const consumer = await new sourceMap.SourceMapConsumer(rawSourceMap);
  const res = consumer.originalPositionFor({
    'line' : line,
    'column' : column
   });
   consumer.destroy()
  return res
}

最重要的就是使用SourceMap提供的 originalPositionFor API。
SourceMapConsumer.prototype.originalPositionFor(generatedPosition)

originalPositionFor API的参数为一个包含line和column属性的对象

  • line 编译生成代码的行号,从1开始
  • column 编译生成代码的列号,从0开始

这个方法会返回一个具有以下属性的对象:

{ source: 'webpack:///src/pages/common/403.vue?c891', // 源代码文件的位置,如果无法获取,返回null。
  line: 4, // 源代码的行号,从1开始,如果无法获取,返回null。
  column: 24, // 源代码的列号,从0开始,如果无法获取,返回null。
  name: 'get' // 源代码的标识,如果无法获取,返回null。
  }

3、源码定位工具

为了使用方便,有人把做成了一个命令行小工具。全局安装后,不需要做任何配置就可以使用。

3.1 安装

npm install --global source-location

3.2 参数介绍

Usage: sl [options]

Options:
  -v, --version           output the version number
  -p, --source-flie-path  The generated source file  编译后的map文件
  -l, --ine               The line number in the generated source  编译后代码行号
  -c, --column            The column number in the generated source  编译后代码列号
  -h, --help              output usage information

3.3 使用案例

终端执行命令:

sl -p dist/1.f47efcb58028826c7c05.js.map -l 1 -c 34 

命令行将会输出:源码的文件路径:path,源码行号:line,源码标识:name。
在这里插入图片描述

项目的github地址: github.com/front-end-y…。这样子的源码映射类似的插件可见我写的文章https://blog.youkuaiyun.com/fageaaa/article/details/154461669第五节。

另外,推荐大家使用Fundebug,一款很好用的BUG监控工具~

前端新一代云资源运维监控平台通常具备多维度的数据收集与分析能力,可从以下方面助力线Bug 的排查和修复: ### 日志监控与分析 平台会收集前端应用产生的各类日志,包括错误日志、性能日志等。通过对错误日志的分析,能快速定位代码中抛出异常的具体位置。例如,当出现 JavaScript 错误时,日志会记录错误类型(如 `ReferenceError`、`TypeError` 等)、错误发生的文件和行号,结合代码上下文,可明确问题所在。性能日志则有助于发现性能瓶颈相关的 Bug,如页面加载过慢可能是由于某个资源加载时间过长,通过分析性能日志能找出该资源并进行优化。 ### 性能指标监控 监控前端应用的关键性能指标,如页面加载时间、首屏渲染时间、资源加载时间等。当这些指标出现异常波动时,可能意味着存在 Bug。例如,若某个页面的加载时间突然变长,可能是由于某个脚本文件体积过大、网络请求超时或者服务器响应缓慢等原因。平台会提供详细的性能分析报告,展示各个阶段的耗时情况,帮助定位问题根源。 ### 用户行为监控 记录用户在前端应用中的操作行为,如点击事件、页面跳转、表单提交等。通过分析用户行为数据,可以重现 Bug 发生的场景。例如,当用户反馈某个功能无法正常使用时,查看用户的操作路径和相关数据,能模拟用户的操作过程,从而更容易发现问题。同时,用户行为监控还能发现一些因用户特定操作顺序或输入数据导致的 Bug。 ### 实时告警功能 平台可设置实时告警规则,当监控到异常情况时及时通知运维人员。例如,当错误日志数量突然增加、性能指标超出预设阈值等情况发生时,会触发告警。运维人员可以根据告警信息快速定位问题,并及时采取措施进行修复。 ### 全链路追踪 对于复杂的前端应用,可能涉及多个服务和接口的调用。全链路追踪功能可以记录请求在各个环节的处理过程,包括请求的发起时间、响应时间、调用的服务和接口等信息。通过全链路追踪,能够清晰地了解请求的整个生命周期,找出可能存在问题的环节。例如,当某个接口调用失败时,可通过全链路追踪查看该接口的调用情况,判断是前端代码问题还是后端服务问题。 ### 代码版本管理与回滚 结合代码版本管理工具,平台可以记录前端应用的各个版本信息。当发现某个版本上线后出现 Bug 时,可以快速回滚到上一个稳定版本,以避免问题进一步扩大。同时,通过对比不同版本的代码,能找出可能引入 Bug 的代码变更。 ### 示例代码 以下是一个简单的 JavaScript 错误捕获和日志记录示例,可将错误信息发送到监控平台: ```javascript window.onerror = function (message, source, lineno, colno, error) { const errorInfo = { message: message, source: source, lineno: lineno, colno: colno, stack: error ? error.stack : null }; // 模拟发送错误信息到监控平台 fetch('/monitoring/error', { method: 'POST', headers: { 'Content-Type': 'application/json' }, body: JSON.stringify(errorInfo) }); }; ```
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

太阳与星辰

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值