SourceMap

什么是SourceMap?

​ webpack4在项目进行打包后,会将开发中的多个文件代码打包到一个文件中,并且经过压缩,去掉多余的空格,且babel编译化后,最终会用于线上环境,那么这样处理后的代码和源代码会有很大的差别,当有bug的时候,我们只能定位到压缩处理后的代码位置,无法定位到开发环境中的代码,对于开发不好调式,因此sourceMap出现了,它就是为了解决不好调式代码问题。

webpack中的SourceMap

eval

​ eval 会将每一个module模块,执行eval,执行后不会生成sourcemap文件,仅仅是在每一个模块后,增加sourceURL来关联模块处理前后对应的关系。在webpack中配置devtool: ‘eval’

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
(function(modules) { // webpackBootstrap
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"default\", function() { return printMe; });\n\nfunction printMe() {\n console.log('11111111');\n}\n\n//# sourceURL=webpack:///./js/demo1.js?");

/***/ "./js/main.js":
/*!********************!*\
!*** ./js/main.js ***!
\********************/
/*! no exports provided */
/***/
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _demo1_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./demo1.js */ \"./js/demo1.js\");\n\n\nconsole.log('main.js');\n\n//# sourceURL=webpack:///./js/main.js?");
})
})

​ 每一个打包后的模块后面都增加了包含sourceURL的注释,sourceURL的值是压缩前存放的代码的位置,这样就通过sourceURL关联了压缩前后的代码。

优点是:打包速度非常快,因为不需要生成sourcemap文件。
缺点是:由于会映射到转换后的代码,而不是映射到原始代码,所以不能正确的显示行数。

source-map

​ 在webpack中配置加上 devtool: ‘source-map’ 配置完成后,source-map会为每一个打包后的模块生成独立的sourcemap文件

1
2
3
"scripts": {
"build": "webpack --progress --colors --devtool source-map"
}

打包后文件:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
(function(module, __webpack_exports__, __webpack_require__) {

"use strict";
__webpack_require__.r(__webpack_exports__);
/* harmony import */ var _demo1_js__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./demo1.js */ "./js/demo1.js");
__webpack_require__(/*! ../styles/main.css */ "./styles/main.css");
console.log('main.js');
/***/ }),

/***/ "./styles/main.css":
/*!*************************!*\
!*** ./styles/main.css ***!
\*************************/
/*! no static exports found */
/***/ (function(module, exports) {

// removed by extract-text-webpack-plugin

/***/ })

/******/ });
//# sourceMappingURL=bundle.js.map

如上打包后的代码最后面一句代码是 //# sourceMappingURL=bundle.js.map ,同时在dist目录下会针对每一个模块生成响应的 .map文件。然后我们可以在谷歌开发者工具的Sources面板中,选中 Enable Javascript source maps,然后就可以进行源码错误调试。

inline(比如 inline-source-map)

​ 该属性不会生成独立的 .map文件,而是将 .map文件以dataURL的形式插入。它会使得bundle.js文件变得非常大,因为它需要把 sourceMappingURL 以dataurl的形式插入到bundle.js里面去。

cheap(如:cheap-source-map)

​ 该属性在打包后同样会为每一个文件模块生成 .map文件,但是与source-map的区别在于cheap生成的 map文件会忽略原始代码中的列信息,调式代码列信息没有什么用,因此使用cheap后,文件大小相对于source-map来讲,bundle.js 文件会变得更小。

module(如:cheap-module-source-map)

​ 该属性的配置也是生成一个没有列的信息的sourceMaps文件,同时loader的sourcemap也被简化成为只包含对应行的。可以追踪第三方模块调试信息。

开发环境和线上环境如何选择

​ 从上面的eval, inline, source-map, cheap, module中可以看到,各自属性值代表打包后的具体含义,因此我们可以分析下开发环境和正式环境要如何选择sourceMap。

  1. 源代码中的列信息是没有任何作用,因此我们打包后的文件不希望包含列相关信息,只有行信息能建立打包前后的依赖关系。
  2. 不管是开发环境还是正式环境,我们都希望能定位到bug的源代码具体的位置,比如说某个vue文件报错了,我们希望能定位到具体的vue文件,因此我们也需要module配置。
  3. 需要生成map文件的形式,因此我们需要增加 source-map属性。
  4. eval打包后的速度非常快,因为它不生成map文件,但是会将map文件以DataURL的形式存在打包后的js文件中,增大文件体积,可以在开发环境使用。

开发环境

1
2
3
module.exports = {
devtool: 'cheap-module-eval-source-map'
}

生成环境

1
2
3
module.exports = { 
devtool: 'cheap-module-source-map';
}
-------------本文结束感谢您的阅读-------------