浅谈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 相关文章推荐
js自带函数备忘 数组
Dec 29 Javascript
jquery遍历input取得input的name
Apr 27 Javascript
js+css在交互上的应用
Jul 18 Javascript
深入理解JavaScript系列(15) 函数(Functions)
Apr 12 Javascript
原始的js代码和jquery对比体会
Sep 10 Javascript
js的匿名函数使用介绍
Dec 11 Javascript
Javascript 实现图片无缝滚动
Dec 19 Javascript
JS中使用FormData上传文件、图片的方法
Aug 07 Javascript
Vue组件Draggable实现拖拽功能
Dec 01 Javascript
Javascript实现html转pdf高清版(提高分辨率)
Feb 19 Javascript
JavaScript实现简单计时器
Jun 22 Javascript
html5 录制mp3音频支持采样率和比特率设置
Jul 15 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
关于mysql 字段的那个点为是定界符
2007/01/15 PHP
PHP连接SQLSERVER 注意事项(附dll文件下载)
2012/06/28 PHP
解析wamp5下虚拟机配置文档
2013/06/27 PHP
laravel中的fillable和guarded属性详解
2019/10/23 PHP
各种常用浏览器getBoundingClientRect的解析
2009/05/21 Javascript
js判断两个日期是否相等的方法
2013/09/10 Javascript
Jquery EasyUI中弹出确认对话框以及加载效果示例代码
2014/02/13 Javascript
JavaScript中的console.time()函数详细介绍
2014/12/29 Javascript
jQuery中die()方法用法实例
2015/01/19 Javascript
javascript实现点击按钮让DIV层弹性移动的方法
2015/02/24 Javascript
在Javascript中处理数组之toSource()方法的使用
2015/06/09 Javascript
基于jquery css3实现点击动画弹出表单源码特效
2015/08/31 Javascript
理解javascript中Map代替循环
2016/02/26 Javascript
IE和Firefox之间在JavaScript语法上的差异
2016/04/22 Javascript
AngularJS 自定义指令详解及示例代码
2016/08/17 Javascript
vue.js中过滤器的使用教程
2017/06/08 Javascript
详谈vue+webpack解决css引用图片打包后找不到资源文件的问题
2018/03/06 Javascript
小程序实现列表删除功能
2018/10/30 Javascript
ES6扩展运算符和rest运算符用法实例分析
2020/05/23 Javascript
jQuery实现移动端下拉展现新的内容回弹动画
2020/06/24 jQuery
vue.js 输入框输入值自动过滤特殊字符替换中问标点操作
2020/08/31 Javascript
vue组件中实现嵌套子组件案例
2020/08/31 Javascript
Python SQLAlchemy基本操作和常用技巧(包含大量实例,非常好)
2014/05/06 Python
wxPython窗口的继承机制实例分析
2014/09/28 Python
Django框架封装外部函数示例
2019/05/28 Python
详解python实现小波变换的一个简单例子
2019/07/18 Python
Python 中的 import 机制之实现远程导入模块
2019/10/29 Python
Python Serial串口基本操作(收发数据)
2020/11/06 Python
在pycharm创建scrapy项目的实现步骤
2020/12/01 Python
Space NK美国站:英国高端美妆护肤商城
2017/05/22 全球购物
美国玩具公司:U.S.Toy
2018/05/19 全球购物
传统软件工程与面向对象的软件工程有什么区别
2012/05/31 面试题
房地产销售大学生自我评价分享
2013/11/11 职场文书
面试后的英文感谢信
2014/02/01 职场文书
法人任命书范本
2014/06/04 职场文书
2015年社会治安综合治理工作总结
2015/04/10 职场文书