浅谈webpack devtool里的7种SourceMap模式


Posted in Javascript onJanuary 14, 2019

我们先来看看文档对这 7 种模式的解释:

模式 解释
eval 每个module会封装到 eval 里包裹起来执行,并且会在末尾追加注释 //@ sourceURL.
source-map 生成一个SourceMap文件.
hidden-source-map 和 source-map 一样,但不会在 bundle 末尾追加注释.
inline-source-map 生成一个 DataUrl 形式的 SourceMap 文件.
eval-source-map 每个module会通过eval()来执行,并且生成一个DataUrl形式的SourceMap.
cheap-source-map 生成一个没有列信息(column-mappings)的SourceMaps文件,不包含loader的 sourcemap(譬如 babel 的 sourcemap)
cheap-module-source-map 生成一个没有列信息(column-mappings)的SourceMaps文件,同时 loader 的 sourcemap 也被简化为只包含对应行的。

注1:

webpack不仅支持这 7 种,而且它们还是可以任意组合上面的eval、inline、hidden关键字,就如文档所说,你可以设置 souremap 选项为 cheap-module-inline-source-map。

注2:

如果你的modules里面已经包含了SourceMaps,你需要用source-map-loader来和合并生成一个新的 SourceMaps。

使用结果有何不同

下面我们将列出这 7 种模式打包编译后的结果,从中看看他们的异同:

eval

webpackJsonp([1],[ 
function(module,exports,__webpack_require__){  
eval(
   ...   
//# sourceURL=webpack:///./src/js/index.js?'
  )
 }, 
function(module,exports,__webpack_require__){  
eval(
   ...   
//# sourceURL=webpack:///./src/static/css/app.less?./~/.npminstall/css-loader/0.23.1/css-loader!./~/.npminstall/postcss-loader/1.1.1/postcss-loader!./~/.npminstall/less-loader/2.2.3/less-loader'
  )
 }, 
function(module,exports,__webpack_require__){  
 eval(
   ...   
 //# sourceURL=webpack:///./src/tmpl/appTemplate.tpl?"
  )
 },
...])

eval 模式会把每个 module 封装到eval 里包裹起来执行,并且会在末尾追加注释。

Each module is executed withevaland//@ sourceURL.

source-map

webpackJsonp([1],[ 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...},
 ...
])//# sourceMappingURL=index.js.map

与此同时,你会发现你的 output 目录下多了一个index.js.map文件。

我们可以把这个 index.js.map 格式化一下,方便我们在下文的观察比较:

{ 
"version":3, 
"sources":[
  "webpack:///js/index.js","webpack:///./src/js/index.js",  
  "webpack:///./~/.npminstall/css-loader/0.23.1/css-loader/lib/css-base.js",
  ...
], 
"names":["webpackJsonp","module","exports"...], 
"mappings":"AAAAA,cAAc,IAER,SAASC...", 
"file":"js/index.js", 
"sourcesContent":[...], 
"sourceRoot":""
}

关于 sourceMap 行列信息如何映射源代码的详解,此处不是我们要重点讨论的话题,从略

hidden-source-map

webpackJsonp([1],[ 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...},
 ...
])

与 source-map 相比少了末尾注释,

但 output 目录下的 index.js.map 没有少

inline-source-map

webpackJsonp([1],[ 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...}, 
function(e,t,i){...},
 ...
])
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9...

可以看到末尾的注释 sourceMap 作为DataURL的形式被内嵌进了 bundle中,由于 sourceMap 的所有信息都被加到了bundle中,整个 bundle 文件变得硕大无比。

eval-source-map

webpackJsonp([1],[ 
function(module,exports,__webpack_require__){  
eval(
   ...   
//# sourceMappingURL=data:application/json;charset=utf-8;base64,...
  )
 }, function(module,exports,__webpack_require__){  
eval(
   ...   
//# sourceMappingURL=data:application/json;charset=utf-8;base64,...
  )
 }, 
 function(module,exports,__webpack_require__){  
eval(
   ...   
//# sourceMappingURL=data:application/json;charset=utf-8;base64,...
  )
 },
 ...
]);

和 eval 类似,但是把注释里的sourceMap 都转为了 DataURL。

cheap-source-map

和 source-map 生成结果差不多。output 目录下的index.js内容一样。

但是 cheap-source-map 生成的 index.js.map 的内容却比 source-map 生成的 index.js.map 要少很多代码,我们对比一下上文 source-map 生成的 index.js.map 的结果,发现source属性里面少了列信息,只剩一个"webpack:///js/index.js"

// index.js.map
{ 
"version":3, "file":"js/index.js", 
"sources":["webpack:///js/index.js"], 
"sourcesContent":[...], 
"mappings":"AAAA", 
"sourceRoot":""
}

cheap-module-source-map

// index.js.map
{ 
"version":3, "file":"js/index.js", 
"sources":["webpack:///js/index.js"], 
"mappings":"AAAA", "sourceRoot":""
}

在 cheap-module-source-map 下 sourceMap 的内容更少了,sourceMap的列信息减少了,可以看到sourcesContent也没有了。

这么多模式用哪个好?

开发环境推荐:

cheap-module-eval-source-map

生产环境推荐:

cheap-module-source-map

这也是下版本 webpack 使用 -d 命令启动 debug 模式时的默认选项

原因如下:

  1. 使用 cheap 模式可以大幅提高souremap 生成的效率。大部分情况我们调试并不关心列信息,而且就算 sourcemap 没有列,有些浏览器引擎(例如 v8) 也会给出列信息。
  2. 使用 eval 方式可大幅提高持续构建效率。官方文档提供的速度对比表格可以看到 eval 模式的编译速度很快。
  3. 使用 module 可支持babel这种预编译工具(在 webpack 里做为 loader 使用)。
  4. 使用 eval-source-map 模式可以减少网络请求。这种模式开启 DataUrl 本身包含完整 sourcemap 信息,并不需要像 sourceURL 那样,浏览器需要发送一个完整请求去获取 sourcemap 文件,这会略微提高点效率。而生产环境中则不宜用 eval,这样会让文件变得极大。

SourceMap模式效率对比图

浅谈webpack devtool里的7种SourceMap模式

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Javascript 相关文章推荐
IE的fireEvent方法概述及应用
Feb 22 Javascript
js验证是否为数字的总结
Apr 14 Javascript
angular中使用路由和$location切换视图
Jan 23 Javascript
JavaScript使用setInterval()函数实现简单轮询操作的方法
Feb 02 Javascript
js实现上传图片预览的方法
Feb 09 Javascript
JS实现简易图片轮播效果的方法
Mar 25 Javascript
javascript原生ajax写法分享
Apr 10 Javascript
基于vue的下拉刷新指令和滚动刷新指令
Dec 23 Javascript
vue短信验证性能优化如何写入localstorage中
Apr 25 Javascript
JS实现关键词高亮显示正则匹配
Jun 22 Javascript
基于Vue 服务端Cookies删除的问题
Sep 21 Javascript
layui实现form表单同时提交数据和文件的代码
Oct 25 Javascript
关于vue的npm run dev和npm run build的区别介绍
Jan 14 #Javascript
用npm-run实现自动化任务的方法示例
Jan 14 #Javascript
详解vue-cli 2.0配置文件(小结)
Jan 14 #Javascript
使用vue-cli脚手架工具搭建vue-webpack项目
Jan 14 #Javascript
vue-cli系列之vue-cli-service整体架构浅析
Jan 14 #Javascript
JS数组求和的常用方法总结【5种方法】
Jan 14 #Javascript
JS实现根据数组对象的某一属性排序操作示例
Jan 14 #Javascript
You might like
一个显示某段时间内每个月的方法 返回由这些月份组成的数组
2012/05/16 PHP
解析php中的escape函数
2013/06/29 PHP
yii2分页之实现跳转到具体某页的实例代码
2016/06/02 PHP
php简单实现多维数组排序的方法
2016/09/30 PHP
PHP-FPM运行状态的实时查看及监控详解
2016/11/18 PHP
PHP观察者模式示例【Laravel框架中有用到】
2018/06/15 PHP
PHP实现将上传图片自动缩放到指定分辨率,并保持清晰度封装类示例
2019/06/17 PHP
js实现网页倒计时、网站已运行时间功能的代码3例
2014/04/14 Javascript
JS实现让网页背景图片斜向移动的方法
2015/02/25 Javascript
分享jQuery封装好的一些常用操作
2016/07/28 Javascript
webpack教程之webpack.config.js配置文件
2017/07/05 Javascript
js字符串倒序的实例代码
2018/11/30 Javascript
微信小程序如何调用图片接口API并居中显示
2019/06/29 Javascript
jquery实现的分页显示功能示例
2019/08/23 jQuery
vue图片上传组件使用详解
2019/12/23 Javascript
[01:34]传奇从这开始 2016国际邀请赛中国区预选赛震撼开启
2016/06/26 DOTA
Python 学习笔记
2008/12/27 Python
17个Python小技巧分享
2015/01/23 Python
Python中title()方法的使用简介
2015/05/20 Python
举例讲解Python中的死锁、可重入锁和互斥锁
2015/11/05 Python
python数据类型_元组、字典常用操作方法(介绍)
2017/05/30 Python
Python内置模块ConfigParser实现配置读写功能的方法
2018/02/12 Python
python对矩阵进行转置的2种处理方法
2019/07/17 Python
Pandas 重塑(stack)和轴向旋转(pivot)的实现
2019/07/22 Python
简单了解Django ContentType内置组件
2019/07/23 Python
python迭代器常见用法实例分析
2019/11/22 Python
Python xpath表达式如何实现数据处理
2020/06/13 Python
python数据类型强制转换实例详解
2020/06/22 Python
Django-Scrapy生成后端json接口的方法示例
2020/10/06 Python
python实现双人五子棋(终端版)
2020/12/30 Python
利用CSS3 动画 绘画 圆形动态时钟
2018/03/20 HTML / CSS
HTML5自定义data-* data(obj)属性和jquery的data()方法的使用
2012/12/13 HTML / CSS
canvas 橡皮筋式线条绘图应用方法
2019/02/13 HTML / CSS
影视制作岗位职责
2013/12/04 职场文书
网吧消防安全责任书
2014/07/29 职场文书
JS前端可视化canvas动画原理及其推导实现
2022/08/05 Javascript