为啥用sourceMap
这几天在搞前端错误日志,做过线上发布的都知道,我们发布到生产环境的代码,一般都有如下步骤:
- 压缩混淆,减小体积
- 多个文件合并,减少
HTTP
请求数 - 通过编译或者转译,将其他语言编译成
JavaScript
这三个步骤,都使得实际运行的代码不同于开发代码,不管是 debug 还是捕获线上的报错,都会变得困难重重。
解决这个问题的方法,就是使用sourceMap
。
啥是sourceMap
简单说,sourceMap
就是一个文件,里面储存着位置信息。
仔细点说,这个文件里保存的,是转换后代码的位置,和对应的转换前的位置。
有了它,出错的时候,通过断点工具可以直接显示原始代码,而不是转换后的代码。
sourceMap长啥样
通过webpack、uglifyjs
等工具,我们可以使用 sourceMap
,这里不细说配置方法,可以看这里。
sourceMap
是一个map
文件,与源码在同一个目录下。
在压缩代码的最后一行,会有这样的一个引用:
... //# sourceMappingURL=main.js.map
指向的就是我们的map
文件。
sourceMap
的格式如下:
{ "version": 3, // SourceMap的版本,目前为3 "sources": [ "../src/main.js" // 转换前的文件,该项是一个数组,表示可能存在多个文件合并 ], "names": [ // 转换前的所有变量名和属性名 "add", "x", "y", "test", "console", "log" ], // 记录位置信息的字符串 "mappings": "CAAA,WACI,IAAIA,IAAM,SAASC,EAAEC,GACjBC,OACAC,QAAQC,IAAIJ,EAAEC,IAElBF,IAAI,EAAE,IALV" }
来一个实际应用
为了突出主题,我这里用uglifyjs来压缩代码,并生成sourceMap,并且使用到页面上(就不再使用webpack重量级工具来示例了)。
首先安装uglifyjs,并去压缩我们的代码
uglifyjs ./src/main.js -o ./build/main.js --source-map url=main.js.map
src/main.js代码如下
(function(){ var add = function(x,y){ test(); console.log(x/y) }; add(4,2); })()
压缩完成后,会在build根目录下生成,压缩后的代码和sourceMap文件
然后再页面上引入压缩后的代码
<!DOCTYPE html> <html lang="en"> <head> <meta charset="UTF-8"> <meta name="viewport" content="width=device-width, initial-scale=1.0"> <title>Document</title> </head> <body> 测试 </body> <script src="./build/main.js"></script> </html>
运行项目,会发现有一个报错,然后点击报错,会发现直接(通过sourceMap)定位到了源代码中的位置,很方便调试
正式环境下,建议关掉sourceMap,因为会导致打包后的体积增加
参考:https://segmentfault.com/a/1190000020213957