收藏本站腾讯微博新浪微博

经典论坛

 找回密码
 注册

QQ登录

只需一步,快速开始

蓝色理想 最新研发动态 网站开通淘帖功能 - 蓝色理想插件 论坛内容导读一页看论坛 - 给官方提建议

论坛活动及任务 地图和邮件任务 请多用悬赏提问 热夏来袭,选一款蓝色理想的个性T恤吧!

手机上论坛,使用APP获得更好体验 急需前端攻城狮,获得内部推荐机会 论坛开通淘帖功能,收藏终于可以分类了!

搜索
查看: 1309|回复: 0

[教程] Source Map入门教程

[复制链接]
发表于 2017-3-13 12:05:09 | 显示全部楼层 |阅读模式
部署前端之前,开发者通常会对代码进行打包压缩,这样可以减少代码大小,从而有效提高访问速度。然而,压缩代码的报错信息是很难Debug的,因为它的行号和列号已经失真。这时就需要Source Map来还原真实的出错位置了。

fundebug-sourcemap.jpg

为啥变换代码?

前端代码越来越复杂的情况下,开发者通常会使用webpack、UglifyJS2等工具对代码进行打包变换,这样可以减少代码大小,有效提高访问速度。关于变换代码的原因,这里不妨引用一下大神阮一峰的JavaScript Source Map 详解:

        压缩,减小体积。比如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对源代码进行压缩变换:

uglifyjs hello.js \
         -m toplevel=true \
         -c unused=true,collapse_vars=true \
         -o hello.min.js

压缩后的代码hello.min.js

function o(){var o="Hello, "+Name;console.log(o)}o();

为啥需要Source Map?

使用Firefox执行hello.js的报错信息是这样:

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的报错信息是这样:

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的。

而Source Map则可以用于还原真实的出错位置,帮助开发者更快的Debug。

什么是Source Map?


使用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各个属性的含义如下:

    version:Source Map的版本号。
    sources:转换前的文件列表。
    names:转换前的所有变量名和属性名。
    mappings:记录位置信息的字符串,经过编码。
    file:(可选)转换后的文件名。
    sourceRoot:(可选)转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
    sourcesContent可选)转换前的文件内容列表,与sources列表依次对应。

Source Map真正神奇之处在于mappings属性,它记录了位置是如何对应的。JavaScript Source Map 详解已经有很好的解释,这里不再赘述。

更多详细信息,请参考Fundebug博客。
您需要登录后才可以回帖 登录 | 注册

本版积分规则

QQ|小黑屋|Archiver|手机版|blueidea.com ( 湘ICP备12001430号 )  

GMT+8, 2020-10-31 03:27 , Processed in 0.109098 second(s), 12 queries , Gzip On, Memcache On.

Powered by Discuz! X3.2 Licensed

© 2001-2013 Comsenz Inc.

快速回复 返回顶部 返回列表