最近在开发一个低代码平台,主要用于运营搭建 H5 活动。这中间涉及到第三方组件的开发,而第三方组件想要接入平台,需要经过我们特定的打包工具来 build。构建之后的组件,会合并成单个的 js 文件,而且代码会被压缩会混淆,这个时候如果需要调试,那就会极其痛苦。想要有一个好的调试环境,就要涉及 SourceMap 的输出,而 Webpack 的 devtools
字段就是用于控制 SourceMap。
SourceMap 原理
在详细解释 devtools 配置之前,先看看 SourceMap 的原理。SourceMap 的主要作用就是用来还原代码,将已经编译压缩的代码,还原成之前的代码。
下图左边代码为 Webpack 打包之前,右边为打包之后。
![](https://i-blog.csdnimg.cn/blog_migrate/f328b66cb88d66855dbbc437c4097b0c.png)
打开 chrome 引入 dist.js
,会发现浏览器会自动将压缩的代码进行了还原。
![](https://i-blog.csdnimg.cn/blog_migrate/f1656319a96226b8773f342f0ae392ba.png)
那这个 SourceMap 到底是怎么将右边的代码还原成左边的样子的呢。我们先看一下 dist.js.map
的结构。
{// 版本号"version": 3,// 输出的文件名"file": "dist.js",// 输出代码与源代码的映射关系"mappings": "MAAA,IAAMA,EAAM,CACVC,KAAM,KACNC,OAAQ,KAGV,SAASC,IACPH,EAAIE,QAAU,EAGhB,SAASE,IACPJ,EAAIE,QAAU,EACdG,QAAQC,IAAIN,EAAIC,KAAM,OAGxBE,IACAC,IACAA,IACAD,K",// 原代码中的一些变量名"names": ["dog", "name", "weight","eat", "call", "console", "log"],// 源文件列表// 我们打包的时候经常是多个js文件合并成一个,所以源文件有多个"sources": ["webpack:///./src/index.ts"],// 源文件内容的列表,与sources字段对应"sourcesContent": ["const dog = {\nname: '旺财',\nweight: 100\n}\n\nfunction eat() {\ndog.weight += 1\n}\n\nfunction call() {\ndog.weight -= 1\nconsole.log(dog.name, '汪汪汪')\n}\n\neat()\ncall()\ncall()\neat()"],
}
其他字段应该都好理解,比较难懂的就是 mappings
字段,看着就像是一堆乱码。这是一串使用 VLQ 进行编码的字符串,规则比较复杂。我们可以直接在 github 找一个VLQ(https://github.com/Rich-Harris/vlq/blob/master/src/index.js)编码的库,对这串字符进行解码。
/** @type {Record<string, number>} */
let char_to_integer = {};
/** @type {Record<number, string>} */
let integer_to_char = {};
'ABCDEFG