soucemap的来龙去脉

237 阅读3分钟

为什么会有soucemap?

出于代码安全、静态资源压缩提升页面性能等目的,前端项目中的代码往往会做压缩、混淆处理;但处理过后的代码难以阅读(如下图),提高了排查问题的难度;

c1ac9b47-916d-48aa-b88b-72e195f84720.png

哪里有问题,哪里就有解决方案,于是Chrome通过soucemap,将转义过后的代码与转义之前的代码进行匹配映射,方便排查问题

2e4f49b0-9342-4022-a11b-3b34aac0ac16.png

soucemap是如何映射对应关系的?

下图是soucemap文件里的内容 image.png

字段说明:

  • version:Source map的版本,目前为3。
  • file:转换后的文件名。
  • sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
  • sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。
  • names:转换前的所有变量名和属性名。
  • mappings:记录位置信息的字符串,下文详细介绍。

其中最重要的字段是mappings,里面记录着映射关系,它分成三层

  • 第一层是行对应,以分号(;)表示,每个分号对应转换后源码的一行。所以,第一个分号前的内容,就对应源码的第一行,以此类推。
  • 第二层是位置对应,以逗号(,)表示,每个逗号对应转换后源码的一个位置。所以,第一个逗号前的内容,就对应该行源码的第一个位置,以此类推。
  • 第三层是位置转换,以VLQ编码表示,代表该位置对应的转换前的源码位置。

第三层里的内容有5位、4位、1位的情况,下面是5位时各位的含义:

  • 第一位,表示这个位置在(转换后的代码的)的第几列。
  • 第二位,表示这个位置属于sources属性中的哪一个文件。
  • 第三位,表示这个位置属于转换前代码的第几行。
  • 第四位,表示这个位置属于转换前代码的第几列。
  • 第五位,表示这个位置属于names属性中的哪一个变量。

4位的情况是去掉了第五位,1位的情况是只有第一位

VLQ编码

先来看下base64,下方是base64编码的索引表

291137095326660.png

base64中每个字符实际使用的只有6位,VLQ编码中是如何使用这6位的呢:这6个位中,左边的第一位(最高位)表示是否"连续"(continuation)。如果是1,代表这6个位后面的6个位也属于同一个数;如果是0,表示该数值到这6个位结束。

image.png

这6个位中的右边最后一位(最低位)的含义,取决于这6个位是否是某个数值的VLQ编码的第一个字符。如果是的,这个位代表"符号"(sign),0为正,1为负(Source map的符号固定为0);如果不是,这个位没有特殊含义,被算作数值的一部分。

扩展

  • Q:同样内容base64编码与正常编码所占内存的大小关系是怎样?
  • Q:项目中soucemap如何配置合理?
  • Q:能用soucemap封装实现哪些功能?