部署前端以前,开发者一般会对代码进行打包压缩,这样能够减小代码大小,从而有效提升访问速度。然而,压缩代码的报错信息是很难Debug的,由于它的行号和列号已经失真。这时就须要Source Map来还原真实的出错位置了。javascript
前端代码愈来愈复杂的状况下,开发者一般会使用webpack、UglifyJS2等工具对代码进行打包变换,这样能够减小代码大小,有效提升访问速度。关于变换代码的缘由,这里不妨引用一下大神阮一峰的JavaScript Source Map 详解:html
- 压缩,减少体积。好比jQuery 1.9的源码,压缩前是252KB,压缩后是32KB。
- 多个文件合并,减小HTTP请求数。
- 其余语言编译成JavaScript。最多见的例子就是CoffeeScript。
下面是一个简单的“hello World”程序hello.js前端
function sayHello() {
var name = "Fundebug";
var greeting = "Hello, " + Name;
console.log(greeting);
}
sayHello();
复制代码
使用UglifyJS2对源代码进行压缩变换:java
uglifyjs hello.js \
-m toplevel=true \
-c unused=true,collapse_vars=true \
-o hello.min.js
复制代码
压缩后的代码hello.min.jswebpack
function o(){var o="Hello, "+Name;console.log(o)}o();
复制代码
使用Firefox执行hello.js的报错信息是这样:git
ReferenceError: Name is not defined
sayHello file:///Users/fundebug/sourcemap-tutorial/hello.js:4:9
<匿名> file:///Users/fundebug/sourcemap-tutorial/hello.js:8:1
复制代码
而hello.min.js的报错信息是这样:github
ReferenceError: Name is not defined
o file:///Users/fundebug/sourcemap-tutorial/hello.min.js:1:18
<匿名> file:///Users/fundebug/sourcemap-tutorial/hello.min.js:1:59
复制代码
对比压缩先后的出错信息,咱们会发现,错误行号和列号已经失真,且函数名也通过了变换。而对于真实的前端项目,开发者会将数十个源文件压缩为一个文件,这时,错误的列号可能多达数千,且出错的真实文件名也是很难肯定的,这样的话,压缩代码的报错信息是很难Debug的。web
而Source Map则能够用于还原真实的出错位置,帮助开发者更快的Debug。小程序
使用UglifyJS2时指定source-map选项便可生成Source Map:微信小程序
uglifyjs hello.js \
-m toplevel=true \
-c unused=true,collapse_vars=true \
--source-map hello.min.js.map \
--source-map-include-sources \
--source-map-root \
-o hello.min.js
复制代码
各类主流前端任务管理工具,打包工具都支持生成Source Map,具体能够查看生成Source Map - Fundebug文档。
生成的hello.min.js多了sourceMappingURL,表示Source Map文件的位置。
function o(){var o="Hello, "+Name;console.log(o)}o();
//# sourceMappingURL=hello.min.js.map
复制代码
生成的Source Map为hello.min.js.map:
{
"version": 3,
"sources": ["hello.js"],
"names": ["sayHello", "greeting", "Name", "console", "log"],
"mappings": "AAAA,QAASA,KAEL,GACIC,GAAW,UAAYC,IAC3BC,SAAQC,IAAIH,GAGhBD",
"file": "hello.min.js",
"sourceRoot": "",
"sourcesContent": ["function sayHello()\n{\n var name = \"Fundebug\";\n var greeting = \"Hello, \" + Name;\n console.log(greeting);\n}\n\nsayHello();\n"]
}
复制代码
由hello.min.js.map可知,Source Map是一个JSON文件,而它包含了代码转换先后的位置信息。也就是说,给定一个转换以后的压缩代码的位置,就能够经过Source Map获取转换以前的代码位置,反过来也同样。Source Map各个属性的含义以下:
Source Map真正神奇之处在于mappings属性,它记录了位置是如何对应的。JavaScript Source Map 详解已经有很好的解释,这里再也不赘述。
主流浏览器均支持Source Map功能,不过Chrome与Firefox须要一些简单的配置,具体步骤请参考How to enable source maps。下面以MacBook上的Chrome浏览器为例,介绍一下配置方法:
使用快捷键option + command + i;或者在菜单栏选择视图->开发者->开发者工具
使用快捷键fn + F1;或者点击右上角的三个点的图标,选择Settings
在Sources中,选中Enable JavaScript source maps
为了测试,我写了一个简单的HTML文件hello.min.html
<head>
<script type="text/javascript" src="hello.min.js"></script>
</head>
复制代码
使用Chrome打开hello.min.html,在控制台看到的错误以下:
Uncaught ReferenceError: Name is not defined
at o (hello.min.js:1)
at hello.min.js:1
复制代码
报错的文件仍然为hello.min.js,须要刷新一下Source Map才有做用:
Uncaught ReferenceError: Name is not defined
at o (hello.js:4)
at hello.js:8
复制代码
注意,Chrome的报错信息没有列号,所以4为错误的行号。Chrome不只能够经过Source Map还原真实的出错位置,还能够根据Source Map的sourcesContent还原出错的源代码。点击出错位置,便可跳转到源码,这样Debug将很是方便。
Fundebug专一于JavaScript、微信小程序、微信小游戏、支付宝小程序、React Native、Node.js和Java实时BUG监控。 自从2016年双十一正式上线,Fundebug累计处理了6亿+错误事件,获得了Google、360、金山软件等众多知名用户的承认。欢迎免费试用!
转载时请注明做者Fundebug以及本文地址:
blog.fundebug.com/2017/03/13/…