生产上的问题你不会用 sourcemap 定位吗?(二)

简介: 生产上的问题你不会用 sourcemap 定位吗?

Edge 浏览器

image.png

image.png

异常监控系统

这里以 sentry 为例 简单演示 一下,大致包括:

  • 接入 sentry
  • 异常捕获
  • 添加 sourcemap

首先,在 Sentry 监控平台上注册/登录拥有自己的账号,然后可以构建一个对应的项目(首次注册登录会有指引),项目创建好以后会生成一个 dsn,在接入 sentry 时需要传入。

其次,按照引导页的提示在你的项目(以 vue3 为例)中安装依赖 npm install --save @sentry/vue @sentry/tracing

最后,在你项目入口文件(main.js)中初始化接入 Sentry 即可:

import { createApp } from "vue";
import { createRouter } from "vue-router";
import * as Sentry from "@sentry/vue";
import { BrowserTracing } from "@sentry/tracing";
const app = createApp({
  // ...
});
const router = createRouter({
  // ...
});
Sentry.init({
  app,
  dsn: "https://x@x.ingest.sentry.io/x",
  integrations: [
    new BrowserTracing({
      routingInstrumentation: Sentry.vueRouterInstrumentation(router),
      tracePropagationTargets: ["localhost", ...],
    }),
  ],
  // Set tracesSampleRate to 1.0 to capture 100%
  // of transactions for performance monitoring.
  // We recommend adjusting this value in production
  tracesSampleRate: 1.0,
});
app.use(router);
app.mount("#app");
复制代码

经过以上处理,默认情况下 Sentry 已经可以自动获取到错误信息了,如:

image.png

image.png

image.png

显然,没有接入 sourcemap 的错误信息在 sentry 中也无法进行快速定位,因此下一步就是需要给 sentry 上传 sourcemap 相关的文件。

sentry 上传 sourcemap 流程sentry 文档

  • 安装 webpack 插件:npm install --save-dev @sentry/webpack-plugin
  • 配置 webpack 插件
// vue.config.js
  const { defineConfig } = require('@vue/cli-service')
  const SentryWebpackPlugin = require('@sentry/webpack-plugin')
  module.exports = defineConfig({
    configureWebpack(config) {
      if (process.env.NODE_ENV === 'production') {
        config.devtool = 'hidden-source-map'
        config.plugins.push(
          new SentryWebpackPlugin({
            include: './dist',
            ignoreFile: '.gitignore',
            ignore: ['node_modules', 'webpack.config.js'],
            configFile: './.sentryclirc',
            release: '0.0.1',
            urlPrefix: '~/js/',
          }),
        )
      }
    },
  })
复制代码
  • 在项目根目录下新建 .sentryclirc 文件
[auth]
token = 在 sentry 平台生成
[defaults]
url = https://sentry.io/ // 如果是自己部署的就填部署地址,如果不是就不改
org = sentry 平台的 org
project = sentry 平台的 project
复制代码
  • 如皋设置 release 字段,那么要保证 main.js 中的 Sentry。init({...}) 和  SentryWebpackPlugin 中的要保持一致性,或者都不设置
  • 构建产物 npm run build
  • 进入 dist 目录通过 http-server  启动本地服务模拟生产环境产生错误
  • 进入 sentry 中查看异常信息,上传 sourcemap 文件后,错误信息如下:
  • image.png

手动映射

通常情况下为了安全性,不推荐使用 浏览器 映射的方式,虽然这种方式对你来说很简便,但也为别有用心的人提供了便捷,因此,通常都会有接入对应的 监控平台,当然除此之外还可以通过 手动映射 的方式进行定位:

  • 安装 source map 库:npm install source-map
  • 新建 sourcemap.js
const { SourceMapConsumer } = require('source-map')
   const fs = require('fs')
   const rawSourceMap = fs.readFileSync('./dist/js/app.dde017e5.js.map', 'utf-8')
   // 填入错误信息
   originalPositionFor('app.dde017e5.js:1:11871')
   function originalPositionFor(errInfo) {
     const [budleName, line, column] = errInfo.split(':')
     SourceMapConsumer.with(rawSourceMap, null, (consumer) => {
       const originalPosition = consumer.originalPositionFor({
         line: parseInt(line),
         column: parseInt(column),
       })
       console.log('bundle name = ', budleName)
       console.log('original position = ', originalPosition)
     })
复制代码
  • 演示如下:

image.png

image.png

image.png

sourcemap 的映射原理

.map 文件中有 mappings 字段,其内容很难让人不注意,毕竟和其他内容相比看起来太与众不同了:

image.png

实际上,mappingsBase64 VLQ 编码形式存储了映射到源代码 行、列 等相关信息。

为什么使用 Base64 VLQ 编码?

源代码通常都是很庞大的,单纯使用 数字 表示 行信息列信息 会使得整个 .map 文件体积变大,而 Base64 VLQ 是一种 压缩数字 内容的编码方式,因此可以用来减少文件体积。

由于 Base64 所能表示的数字存在 上限,如果需要表示超过上限的数字该怎么办,实际上只有 每个分号中的第一串英文 是用来表示代码的 第几行、第几列 的绝对位置外,后面的都是相对于之前的位置来做 加减法 的。

可以通过 BASE64 VLQ CODEC 这个网站了解具体的映射关系.

mappings 的组成

mappings 的内容主要由三部分组成:

  • 英文串
  • 每段英文串表示 运行时代码开发时代码 位置关联的 base64VLQ 编码内容
  • 每段英文串拥由 5 部分组成:
  • 运行时代码所在的列,通常源代码经压缩后只有 1行,因此不需要存储行信息,只需要存储列信息
  • 对应 sources 字段下标,即对应哪个源文件
  • 开发时代码的第几行
  • 开发时代码的第几列
  • 对应 names 字段下标,即对应哪个变量名
  • 逗号 ,
  • 用于分隔一行代码中的内容或位置,例如 "var a = 1;console.log(a);" 相当于 "var, a, =, 1, console, log"
  • 分号 ;
  • 表示 运行时代码 的行信息,用来定位是编译后代码的第几行,如果启用代码压缩那么就不会有 分号,因为代码会被压缩在一行上

简单解析 mappings

下面以 console.log(1); 为例子简单介绍下对应关系,毕竟源码内容复杂的不好分析:

// main.js
console.log(1);
// main.js.map
{
  "version": 3,
  "file": "main.js",
  "mappings": "AAAAA,QAAQC,IAAI",
  "sources": ["webpack://vue3-wp5/./src/main.js"],
  "sourcesContent": ["console.log(1);\n"],
  "names": ["console", "log"],
  "sourceRoot": ""
}
复制代码

还是先关注 mappings 字段,其内容由于是编码后的内容,为了更直观的看到其代表的具体数字内容,我们可以通过 BASE64 VLQ CODEC 网站来得到结果:

image.png

现在,我们知道了 "AAAAA,QAAQC,IAAI" 对应 [0,0,0,0,0], [8,0,0,8,1], [4,0,0,4],结合上述其内容就表示:

  • [0,0,0,0,0] 对应 console
  • 0 :编译代码 第 0
  • 0 :对应 sources[0],即 main.js
  • 0 :源代码 第 0
  • 0 :源代码 第 0
  • 0 :对应 names[0],即 console
  • [8,0,0,8,1] 对应 log
  • 8 :编译代码 第 8,其实是 第 8+0=8
  • 0 :对应 sources[0],即 main.js
  • 0 :源代码 第 0
  • 8 :源代码 第 8,其实是 第 8+0=8
  • 1 :对应 names[1],即 log
  • [4,0,0,4] 对应 1
  • 4 :编译代码 第 4,其实是 第 8+4=12
  • 0 :对应 sources[0],即 main.js
  • 0 :源代码 第 0
  • 4 :源代码 第 4,其实是 8+4=12
  • 不是变量,因此没有和 names 相关信息

是不是有些奇怪,明明 1 的位置比 log 的位置更靠后,为什么编码显示的列数却更小,别忘了下面这个规则:

实际上只有 每个分号中的第一串英文 是用来表示代码的 第几行、第几列 的绝对位置外,后面的都是相对于之前的位置来做 加减法

即实际显示的列号数应为:

image.png

最后

以上就是对 sourcemap 相关内容的介绍,希望本文对你有所帮助!!!

说个题外话,有人好奇我哪有那么内容要写,其实大多文章内容只是将自己需要解决或者同事遇到的问题进行总结和扩展而已,所以大多数文章的想法就来源于此,其次我认为写文章的原则就是:写出来的文章首先要保证自己有收获! 另外,更多的是看看各位掘友对同一个问题都会有什么更好的方案!


目录
相关文章
|
4月前
|
前端开发 JavaScript
cypress 如何定位元素?
cypress 如何定位元素?
cypress 如何定位元素?
|
7月前
|
JavaScript 应用服务中间件 nginx
vuecli3打包项目上线之后报错怎么使用本地的sourcemap文件定位调试?
vuecli3打包项目上线之后报错怎么使用本地的sourcemap文件定位调试?
55 0
|
12天前
|
前端开发 JavaScript 测试技术
自动化测试定位方式那么多,应该选哪个?
本文介绍了移动应用自动化测试中的定位策略,包括 ID、XPath、ClassName、AccessibilityID、Name、XPath 模糊定位、Android UI Automator、iOS Predicate 等。在Web测试中,使用class name、css selector、id等定位元素。选择定位器应遵循与研发约定、优先使用特定属性及组合定位的原则。当元素定位不到时,可能因定位信息错误、元素状态等问题,可通过调整策略、等待元素加载或使用JS操作解决。特殊控件如弹框、下拉框等,需采用特定方法如JS注入或send_keys()处理。
11 3
|
2月前
|
测试技术 Android开发 索引
XPath定位如何在App自动化测试中大显神威
本文介绍了如何在Appium中使用XPath进行自动化App测试。通过淘宝App实例,展示了XPath在定位元素上的应用,包括基础定位(如通过text、resource-id、class和content-desc属性),contains模糊定位,组合定位以及层级定位(如父、子、兄弟和祖元素定位)。XPath的灵活性和强大功能使得在Appium中高效地定位元素成为可能,从而提升移动应用的测试效率。
17 0
|
3月前
|
运维 监控 供应链
阿里云 RPA:提高业务效率的新路径
机器人流程自动化(RPA)技术正迅速改变着企业的运营方式,为提高业务效率提供了全新的解决方案。阿里云 RPA 作为行业领先的产品,凭借其强大的功能和创新的技术,成为了众多企业提高业务效率的首选。
|
4月前
|
安全 算法 JavaScript
安卓逆向 -- 关键代码定位与分析技术
安卓逆向 -- 关键代码定位与分析技术
51 0
|
8月前
|
JavaScript 前端开发
Cypress 基础 - 元素的定位
Cypress 基础 - 元素的定位
57 0
|
8月前
测试定位打卡
测试定位打卡
40 0
|
存储 Web App开发 JSON
生产上的问题你不会用 sourcemap 定位吗?(一)
生产上的问题你不会用 sourcemap 定位吗?
309 0
文件定位
文件定位
89 0