什么是 Source map
简单来说 Source map 就是一个存储信息的文件,里面储存着位置信息。
Source map 英文释义:源程序映射。
位置信息:转换后的代码 对应的 转换前的代码 位置映射关系。
有了 Source map,就算线上运行的是转换后的代码,调试工具中也可以直接显示转换前的代码。这极大的方便了我们开发者调试和排错。
Source map 文件介绍
就以上述案例生成的 main.js.map 为例,我们来了解一下,它的内容结构是怎样的。
{
// version:Source map 的版本,目前为 3。
"version": 3,
// file:转换后的文件名。
"file": "main.js",
// sourceRoot:转换前的文件所在的目录。如果与转换前的文件在同一目录,该项为空。
"sourceRoot": "",
// sources:转换前的文件。该项是一个数组,表示可能存在多个文件合并。
"sources": ["webpack://app/./main.js"],
// sourcesContent:原始代码
"sourcesContent": ["alert('tomato')\r\n"],
// names:转换前的所有变量名和属性名。
"names": ["alert"],
// mappings:记录位置信息的字符串,下文详细介绍。
"mappings": "AAAAA,MAAM"
}
webpack 中 devtool 的多种配置
查看官方文档,可以了解到,devtools 的配置项可以达到 10-20 种左右的情况。其实并不需要记住那么多情况,本质上是一些配置项的排列组合。
配置项如下:
- source-map:生成 sourcemap 文件,可以配置 inline,会以 dataURL 的方式内联,可以配置 hidden,只生成 sourcemap,不和生成的文件关联;
- hidden:是否会在打包后文件的末尾增加 sourceURL;
- inline:不产生独立的 .map 文件,把 source-map 的内容以 dataURI 的方式追加到目标文件末尾;
- eval:浏览器 devtool 支持通过 sourceUrl 来把 eval 的内容单独生成文件,还可以进一步通过 sourceMappingUrl 来映射回源码,webpack 利用这个特性来简化了 sourcemap 的处理,可以直接从模块开始映射,不用从 bundle 级别。
- cheap:只映射到源代码的某一行,不精确到列,可以提升 sourcemap 生成速度;
- nosources:不生成 sourceContent 内容,可以减小 sourcemap 文件的大小;
- module: sourcemap 生成时会关联每一步 loader 生成的 sourcemap,可以映射回最初的源码;
不同的配置之间可以排列组合
eval
eval : 每一个模块都执行eval()过程,并且会追加//@ sourceURL
eval-source-map:每一个模块在执行eval()过程之后,并且会为每一个模块生成sourcemap文件,生成的sourcemap文件通过DataURL的方式添加
eval会将每一个module模块,执行eval,执行后不会生成sourcemap文件,仅仅是在每一个模块后,增加sourceURL来关联模块处理前后的对应关系。举例来说:
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?"
)
},
...])
上述是一个指定devtool:eval的压缩后的代码,我们发现压缩后的代码的每一个模块后面都增加了一端包含sourceURL的注释,sourceURL的值是压缩前的代码,这样就通过sourceURL关联了压缩前后的代码,并没有为每一个模块生成相应的sourcemap。
因为不需要生成模块的sourcemap,因此打包的速度很快。
注意!
eval-source-map组合使用是指将.map以DataURL的形式引入到打包好的模块中,类似于inline属性的效果,我们在生产中,使用eval-source-map会使打包后的文件太大,因此在生产环境中不会使用eval-source-map。但是因为eval的rebuild速度快,因此我们可以在本地环境中增加eval属性。