简述
通常 js 脚本 在通过诸如 webpack 等打包压缩后,会变成仅一行的 js 文件,这样带来几点好处:
- 压缩,减少体积(jquery.min.js 能压缩十倍文件大小)
- 多个文件合并成一个,能在第一次访问时候减少 js 文件请求数
- 将其他脚本编译成 JavaScript 脚本供页面使用
但同时也带了一个新的问题:我们的 debug,诸如 console.log 和 报错信息 等,控制台无法输出正确的源码位置。由此 Source Map 应运而生。
Source Map 就是 源码 和对应 压缩成仅一行后的 js 代码 的对照文件
源码转换
压缩后:jquery.min.js 例子
Source Map:jquery.min.map 例子
可以看到 如1所示
压缩后的 jquery.min.js 文件有两行:一行 js 脚本 + 一行注释
其中第二行注释内容:
1 | //@ sourceMappingURL=jquery.min.map |
这是一种固定格式:告诉我们将 URL 链接中的 jquery.min.js 替换为 jquery.min.map,即可得到 Source Map 文件。这不关是告诉我们,同时也是告诉浏览器如何输出正确的源码位置。
Source Map 文件格式
固定由一个对象组成,里面包含 6 个属性(5 个必填)
1 | { |
Source Map 对象的 mappings 属性
mappings 属性仅包含一段字符串。里面的内容需要进行层次划分来达到,横纵坐标转换。
1 | { |
分隔符有:(;)分号(,)逗号(总共两种)
第一次分割是用(;)分号,对应压缩后的行数(压缩目的是节省,所以压缩后大多为一行,也会出现多行的情况,但总是从第一行开始,前面不会有空行)第一行的内容结束,分号隔开,接上第二行
第二次分割使用(,)逗号,对应压缩后的位置。通常一个报错信息会指出一个错误开始的地方,开始的地方到语句结束的地方就叫一个位置。(注意:这一层不表示压缩后的对应列数,仅大概位置)
最后分割为一段字符串单位后,就进行位置转换了。
如 AAgBC
这样的字符串,是按照 VLQ 编码(Variable-length Quantity)表示的,表示该位置对应的转换前的源码位置。
VLQ 编码
VLQ 编码字段通常有 5 个字符(4 个字符、6 个字符)
- 从左边算起:
- 第一位表示这个位置在压缩后的代码的第几列
- 第二位表示这个位置属于
sources属性
中的哪一个文件 - 第三位表示这个位置属于转换前代码的第几行
- 第四位表示这个位置属于转换前代码的第几列
- 第五位表示这个位置属于
names属性
中的哪一个变量
由于每个字符使用 6 个两进制位,所以字段内容的对应值与 Base64 相似,具体的对应参数可以查阅 VLQ 编码