理解webpack中的devTool的配置項

2.1. eval
  eval 會將每個module模塊,執行eval,執行後不會生成sourcemap文件,僅僅是在每個模塊後,增長sourceURL來關聯模塊處理先後對應的關係。在webpack中配置devtool: 'eval', 以下打包後的代碼:javascript

複製代碼
(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。css

優勢是:打包速度很是快,由於不須要生成sourcemap文件。
缺點是:因爲會映射到轉換後的代碼,而不是映射到原始代碼,因此不能正確的顯示行數。html

2.2 source-mapvue

在webpack中配置加上 devtool: 'source-map' 配置完成後,source-map會爲每個打包後的模塊生成獨立的sourcemap文件,好比在package.json文件中 這樣配置:java

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

而後運行 npm run build 後,會在dist目錄下生產map文件。咱們繼續打包後的代碼以下:webpack

複製代碼
(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文件,
好比咱們在dist目錄中會生成 bundle.js.map文件,咱們能夠打開看下這個文件代碼會以下:web

複製代碼
{
  "version":3,
  "sources":[
    "webpack:///webpack/bootstrap","webpack:///./js/demo1.js",
    "webpack:///./js/main.js","webpack:///./styles/main.css"
  ],
  "names":["printMe","console","log","require"],
  "mappings":";AAAA;AACA;;AAEA;AACA...",
  "file":"bundle.js",
  "sourcesContent":[],
  "sourceRoot": ""
}
複製代碼

上面生成後的map文件是一個javascript對象,能夠被解析器讀取,它主要有如下幾個屬性:chrome

version: Source Map 的版本,目前爲3.
sources: 轉換前的文件,該項是一個數組,表示可能存在多個文件合併.
names: 轉換前的全部變量名和屬性名。
mappings: 記錄位置信息的字符串。
sourcesContent: 轉換前的文件內容列表,與sources列表依次對應。
sourceRoot: 轉換前的文件所在的目錄,若是與轉換前的文件在同一個目錄,該項爲空。npm

chrome和firefox如何使用Source Map呢?json

1. 開啓開發者工具

使用快捷鍵 option + command + i; 或者在 菜單欄選擇視圖 -> 開發者 -> 開發者工具。

2. 打開設置

點擊右上角的三個點的圖標,選擇Settings, 以下圖所示:

3. 開啓Source Map
在Sources中,選中 Enable Javascript source maps 以下圖所示

開啓完成後,咱們在 package.json 配置以下代碼:

scripts: {
  "dev": "webpack-dev-server --progress --colors --devtool source-map --hot --inline",
}

而後在main.js 代碼中,添加以下代碼:

require('../styles/main.css');
import demo1Func from './demo1.js';

console.log('main.js');
console.log(a)

如上a未定義,直接打印a,確定會報錯的。咱們在命令行中 運行 npm run dev 後,打開頁面會發現報錯,報錯以下:

而後咱們點擊 main.js:5 後,會進入main.js代碼內,以下圖:

2.3 inline(好比 inline-source-map)
該屬性不會生成獨立的 .map文件,而是將 .map文件以dataURL的形式插入。

以下代碼:

複製代碼
/***/ (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');
console.log(a);

/***/ }),

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

// removed by extract-text-webpack-plugin

/***/ })

/******/ });
//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJzb3VyY2Vz.....
複製代碼

inline-source-map 使用缺點:它會使得bundle.js文件變得很是大,由於它須要把 sourceMappingURL 以dataurl的形式插入到bundle.js裏面去。以下圖所示:

2.4 cheap(如:cheap-source-map)

該屬性在打包後一樣會爲每個文件模塊生成 .map文件,可是與source-map的區別在於cheap生成的 map文件會忽略原始代碼中的列信息;
好比生成後的bundle.js.map中的mappings的代碼以下:

複製代碼
"mappings":";AAAA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;AACA;;;;;;;;;;;;;AClFA;AAAA;AAAA;AACA;AACA;AACA;;;;;;;;;;
複製代碼

如上能夠看到,它不會生成列的信息,有逗號就表示包含了列信息。增長該屬性後,cheap就不會生成列信息,調式代碼列信息沒有什麼用,所以使用cheap後,文件大小相對於source-map來說,bundle.js 文件會變得更小。

以下圖使用的是 source-map 生成的bundle.js.map 文件, 會包含列的信息,以下圖所示:

使用cheap屬性後,也不會有loader模塊之間對應的sourcemap,由於webpack打包最終會將全部的非js資源,經過loader形式轉換成js資源,好比 vue 中的文件,xx.vue -> vue-loader轉換 -> js -> 壓縮 -> 壓縮後的js

因此說若是沒有loader之間的sourcemap文件的話,那麼在debug的時候,定義到壓縮前的js中的時候,不能跟蹤到vue中。

2.5 module(如:cheap-module-source-map)
該屬性的配置也是生成一個沒有列的信息的sourceMaps文件,同時loader的sourcemap也被簡化成爲只包含對應行的。

三:開發環境和線上環境如何選擇sourceMap?

從上面的eval, inline, source-map, cheap, module中能夠看到,各自屬性值表明打包後的具體含義,所以咱們能夠分析下開發環境和正式環境要如何選擇sourceMap;咱們能夠從以下幾個方面考慮:

1. 源代碼中的列信息是沒有任何做用,所以咱們打包後的文件不但願包含列相關信息,只有行信息能創建打包先後的依賴關係。所以無論是開發環境或生產環境,咱們都但願添加cheap的基本類型來忽略打包先後的列信息。

2. 無論是開發環境仍是正式環境,咱們都但願能定位到bug的源代碼具體的位置,好比說某個vue文件報錯了,咱們但願能定位到具體的vue文件,所以咱們也須要module配置。

3. 咱們須要生成map文件的形式,所以咱們須要增長 source-map屬性。

4. 咱們介紹了eval打包代碼的時候,知道eval打包後的速度很是快,由於它不生成map文件,可是能夠對eval組合使用 eval-source-map使用會將map文件以DataURL的形式存在打包後的js文件中,好比以下:

它的效果相似於inline的效果,所以在正式環境中不要使用 eval-source-map, 由於它會增長文件的大小,可是在開發環境中,能夠試用下,由於他們打包的速度很快。

所以咱們能夠總結以下:

在開發環境中咱們可使用 

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

在正式環境中咱們可使用  

module.exports = { 
  devtool: 'cheap-module-source-map';
}

如上是總結的在開發環境和正式環境使用的sourcemap進行打包的簡單思路。

相關文章
相關標籤/搜索