欧美bbbwbbbw肥妇,免费乱码人妻系列日韩,一级黄片

Webpack中Source?Map配置深入解析

 更新時(shí)間:2022年11月15日 10:14:03   作者:陳民哲  
這篇文章主要為大家介紹了Webpack中Source?Map配置深入解析,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪

為什么需要Source Map

通常我們運(yùn)行在瀏覽器中的代碼是經(jīng)過(guò)處理的,處理后的代碼可能與開(kāi)發(fā)時(shí)代碼相差很遠(yuǎn),這就導(dǎo)致開(kāi)發(fā)調(diào)試和線上排錯(cuò)變得困難。這時(shí)Source Map就登場(chǎng)了,有了它瀏覽器就可以從轉(zhuǎn)換后的代碼直接定位到轉(zhuǎn)換前的代碼。在webpack中,可以通過(guò)devtool選項(xiàng)來(lái)配置Source Map。

devtool選項(xiàng)

當(dāng)mode為development時(shí),devtool默認(rèn)為‘eval’,當(dāng)mode為production時(shí),devtool默認(rèn)為false。

devtool為false和'eval'有啥區(qū)別

在回答這個(gè)問(wèn)題之前,我們得做點(diǎn)準(zhǔn)備工作。

準(zhǔn)備工作

1,創(chuàng)建項(xiàng)目 安裝依賴

// 1,創(chuàng)建項(xiàng)目 安裝依賴
mkdir sourcemap-demo
cd sourcemap-demo
npm init -y
npm install webpack webpack-cli --save-dev
npm install html-webpack-plugin --save-dev

2,添加文件

// 添加index.html
<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8" />
  <title>起步</title>
</head>
<body>
</body>
</html>
// 添加src/index.js
import a from './a';
console.log(`hello index`);
a();
// 添加src/a.js
export default function b() {
  console.log('hello a');
}

3,寫(xiě)配置 webpack.config.js

const HtmlWebpackPlugin = require('html-webpack-plugin');
const path = require('path');
module.exports = {
  entry: './src/index.js',
  mode: 'development', // 注意:這地方要將mode設(shè)置為development。因?yàn)楫?dāng)mode為production時(shí)webpack會(huì)開(kāi)啟代碼壓縮,不利于我們觀察現(xiàn)象。
  output: {
    filename: '[name].js',
    path: path.resolve(__dirname, 'dist'),
    clean: true,
  },
  devtool: false, // 先配置為false
  plugins: [new HtmlWebpackPlugin()],
};

4,在package.json中添加

"scripts": {
    "build": "webpack"
  }

5,執(zhí)行 npm run build,打包文件生成到了dist文件夾中,至此,準(zhǔn)備工作完畢。

觀察devtool為false時(shí)

我們要觀察兩個(gè)地方,一個(gè)是dist/main.js。一個(gè)在瀏覽器中的情況。

1, 在dist/main.js中

var __webpack_modules__ = ({
 "./src/a.js":
      ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        __webpack_require__.r(__webpack_exports__);
        __webpack_require__.d(__webpack_exports__, {
          "default": () => (b)
        });
        function b() {
          console.log('hello a');
        }
  })
 ...
 var __webpack_exports__ = {};
  (() => {
    __webpack_require__.r(__webpack_exports__);
    var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__("./src/a.js");
    console.log(`hello index`);
    (0, _a__WEBPACK_IMPORTED_MODULE_0__["default"])();
  })();

內(nèi)容分析:

  • __webpack_modules__對(duì)象對(duì)應(yīng)著我們?cè)创a中的js文件, key是路徑,value就是經(jīng)過(guò)webpack轉(zhuǎn)換過(guò)的模塊。
  • 我們寫(xiě)的 console.log(hello index); 這類源碼中的內(nèi)容,基本沒(méi)什么變化的被打包到dist/main.js中。

2,在瀏覽器中,觀察開(kāi)發(fā)者工具中的Sources。

內(nèi)容分析:

  • 只能看到webpack打包后的代碼.

小結(jié)

devtool為false,只能看到打包后的代碼,不利于開(kāi)發(fā)調(diào)試和線上排錯(cuò)。

觀察devtool為'eval'時(shí)

重新編譯后。

1, 在dist/main.js中

  var __webpack_modules__ = ({
    "./src/a.js":
      ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ b)\n/* harmony export */ });\nfunction b() {\n  console.log('hello a');\n}\n\n//# sourceURL=webpack://sourcemap/./src/a.js?");
      }),
    "./src/index.js":
      ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ \"./src/a.js\");\n\n\nconsole.log(`hello index`);\n(0,_a__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();\n\n//# sourceURL=webpack://sourcemap/./src/index.js?");
      })
  });

內(nèi)容分析:

  • 模塊中的內(nèi)容被eval包裹。內(nèi)容末尾有// # sourceURL=webpack://sourcemap/./src/index.js。瀏覽器會(huì)對(duì)eval后面的sourceURL特殊處理。下面看看怎么特殊處理的

2,在瀏覽器中

內(nèi)容分析:

  • 所有sourceURL的內(nèi)容會(huì)被翻譯成上圖中左側(cè)下方sourcemap-demo節(jié)點(diǎn)的結(jié)構(gòu),點(diǎn)擊某個(gè)節(jié)點(diǎn),會(huì)看到其eval對(duì)應(yīng)的代碼。從中我們看到了console.log(hello index);。

小結(jié)

devtool為'eval',可以在瀏覽器開(kāi)發(fā)者工具中看到模塊結(jié)構(gòu),通常也就是我們?cè)创a的結(jié)構(gòu)。也能看到被webpack轉(zhuǎn)換過(guò)點(diǎn)代碼,在一定程度上能幫助我們調(diào)試代碼和排查問(wèn)題了。

devtool為'source-map'和'eval-source-map'有啥區(qū)別

觀察devtool為'source-map'時(shí)

現(xiàn)在將devtool設(shè)置成source-map,看看效果。

1, 在dist/main.js中

//# sourceMappingURL=main.js.map

內(nèi)容分析:

  • 最下面多了一行注釋代碼sourceMappingURL指向main.js.map。同時(shí)dist文件夾下多了個(gè)main.js.map。
main.js.map文件

源碼和打包后代碼的映射文件,有了它,當(dāng)線上出bug時(shí),瀏覽器可以在控制臺(tái)顯示報(bào)錯(cuò)在源碼中的行數(shù)和列數(shù)。

2,在瀏覽器中

內(nèi)容分析:

  • 在瀏覽器中可以看到我們的源碼了。

小結(jié)

  • devtool為'source-map',會(huì)生成映射文件,出bug時(shí)可以準(zhǔn)確定位到問(wèn)題在源碼中的位置,便于開(kāi)發(fā)調(diào)試和排查問(wèn)題。
  • 它同樣有缺點(diǎn),一是source-map的生成比較耗時(shí),二是在開(kāi)發(fā)時(shí),我們會(huì)用熱更新,沒(méi)有source-map的話只需替換被更改的模塊就行了,但是有source-map時(shí),就要重新生產(chǎn)整個(gè)打包文件的map文件,比較耗時(shí)。

那么有什么方式可以避免devtool為'source-map'的缺點(diǎn)嗎,答案是'eval-source-map'

觀察devtool為'eval-source-map'時(shí)

1, 在dist/main.js中

var __webpack_modules__ = ({
    "./src/a.js":
      ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */   \"default\": () => (/* binding */ b)\n/* harmony export */ });\nfunction b() {\n  console.log('hello a');\n}//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvYS5qcy5qcyIsIm1hcHBpbmdzIjoiOzs7O0FBQWU7QUFDZjtBQUNBIiwic291cmNlcyI6WyJ3ZWJwYWNrOi8vc291cmNlbWFwLWRlbW8vLi9zcmMvYS5qcz82ZTFjIl0sInNvdXJjZXNDb250ZW50IjpbImV4cG9ydCBkZWZhdWx0IGZ1bmN0aW9uIGIoKSB7XG4gIGNvbnNvbGUubG9nKCdoZWxsbyBhJyk7XG59Il0sIm5hbWVzIjpbXSwic291cmNlUm9vdCI6IiJ9\n//# sourceURL=webpack-internal:///./src/a.js\n");
      }),
    "./src/index.js":
      ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
        eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _a__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./a */ \"./src/a.js\");\n\n\nconsole.log(`hello index`);\n(0,_a__WEBPACK_IMPORTED_MODULE_0__[\"default\"])();//# sourceURL=[module]\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoiLi9zcmMvaW5kZXguanMuanMiLCJtYXBwaW5ncyI6Ijs7QUFBb0I7O0FBRXBCO0FBQ0EsOENBQUMiLCJzb3VyY2VzIjpbIndlYnBhY2s6Ly9zb3VyY2VtYXAtZGVtby8uL3NyYy9pbmRleC5qcz9iNjM1Il0sInNvdXJjZXNDb250ZW50IjpbImltcG9ydCBhIGZyb20gJy4vYSc7XG5cbmNvbnNvbGUubG9nKGBoZWxsbyBpbmRleGApO1xuYSgpOyJdLCJuYW1lcyI6W10sInNvdXJjZVJvb3QiOiIifQ==\n//# sourceURL=webpack-internal:///./src/index.js\n");
      })
  });

內(nèi)容分析:

  • 與devtool為'source-map'的區(qū)別是,不是在文件最底部多了一行//# sourceMappingURL=main.js.map,也沒(méi)有生成map文件。而是每個(gè)模塊直接跟隨一個(gè)sourceMappingURL,其中是源碼和打包后代碼的映射信息。這樣點(diǎn)好處時(shí)在webpack因?yàn)殚_(kāi)發(fā)者的更改要進(jìn)行熱更新時(shí),不必重新生成全局map文件,只需重新生成更改模塊的map信息就好。

2,在瀏覽器中

內(nèi)容分析:

  • 在瀏覽器中同樣可以看到源碼,相比于'source-map',熱更新時(shí)編譯時(shí)間更少。

小結(jié)

  • 這里總結(jié)下'eval'的好處,由于Mapping信息被拆分在了每個(gè)模塊eval函數(shù)后面的sourceMappingURL中,熱更新時(shí)不必全量生成map數(shù)據(jù),從而擁有更快的編譯速度。(官網(wǎng)管這叫rebuild速度快)

對(duì)于開(kāi)發(fā)調(diào)試,eval-source-map模式就完美了嗎,如果追求更快的編譯速度而不求追求的出現(xiàn)bug時(shí)精準(zhǔn)的行列信息,只提供bug所在行信息就行,應(yīng)該用什么?答案是'eval-cheap-source-map'。

devtool為'eval-cheap-source-map'和'eval-cheap-module-source-map'有啥區(qū)別

eval-source-map可以在出現(xiàn)bug時(shí)準(zhǔn)確的定位到出錯(cuò)代碼在源碼的行和列。但如果你不需要列映射,只需要知道bug所在的行,那可以考慮eval-cheap-source-map,它比eval-source-map開(kāi)銷小,編譯的快。

觀察devtool為'eval-cheap-source-map'時(shí)

1, 在dist/main.js中

這里不貼代碼了,相比于eval-source-map,sourceMappingURL后的內(nèi)容少很多。

2,在瀏覽器中

與eval-source-map相同,更多細(xì)節(jié)暫不研究。

3,eval-cheap-source-map的問(wèn)題

我們?cè)黾觠s代碼babal專義的環(huán)節(jié),安裝 babel

 npm install babel-loader @babel/core @babel/preset-env -D

添加代碼

// src/b.js
export default class B {
  constructor() {
    this.str = 'hell b'
  }
  sayHello() {
    console.log(this.str)
  }
}
// index.js
import a from './a';
+ import B from './b';
console.log(`hello index`);
a();
+ const b = new B();
+ b.sayHello();

查看在瀏覽器中的表現(xiàn)

壞了,瀏覽器中展示點(diǎn)代碼是經(jīng)過(guò)loader編譯后的代碼,不是我們手寫(xiě)的代碼了。

經(jīng)實(shí)驗(yàn),如果設(shè)置成eval-source-map,不會(huì)有這個(gè)問(wèn)題,瀏覽器中仍然可以看到源碼。

有沒(méi)有什么設(shè)置,既可以沒(méi)有列映射,又能在瀏覽器中看到源碼的呢?答案是eval-cheap-module-source-map。

觀察devtool為'eval-cheap-module-source-map'時(shí)

在這種情況下,源自 loader 的 source map 會(huì)得到更好的處理結(jié)果。既沒(méi)有列映射,又能在瀏覽器中看到源碼。

小結(jié)

在開(kāi)發(fā)模式下,為方便我們的開(kāi)發(fā)調(diào)試。

  • 如果你想要最全的源碼,bug精準(zhǔn)定位到哪行哪列,使用eval-source-map。
  • 如果只需要將錯(cuò)誤定位到哪行,使用eval-cheap-module-source-map。

開(kāi)發(fā)模式下其他配置

inline-source-map,inline-cheap-source-map等inline開(kāi)頭的

就是把map文件內(nèi)容放打包js代碼文件中??雌饋?lái)沒(méi)多大用處。

eval-nosources-cheap-source-map 等有nosources關(guān)鍵字的

源碼信息不再map文件中,瀏覽器通常會(huì)嘗試從 web 服務(wù)器或文件系統(tǒng)加載源代碼。目前不了解其使用場(chǎng)景。

生產(chǎn)環(huán)境的source map配置

(none)

生產(chǎn)環(huán)境不配置等同于寫(xiě)了devtool: false。默認(rèn)不生成 source map,這是個(gè)不錯(cuò)的選擇。因?yàn)閯e人可以通過(guò) source map看到我們的源碼,影響安全。

source-map

在線上環(huán)境不必使用eval-*了,沒(méi)有熱更新的情況。也沒(méi)必要使用cheap-*了,只要發(fā)布的時(shí)候編譯一次,慢點(diǎn)就慢點(diǎn)。

顯然使用source-map有個(gè)問(wèn)題,會(huì)讓用戶看到源碼。我們可以通過(guò)服務(wù)器配置,禁止普通用戶訪問(wèn) source map 文件。只讓固定IP(開(kāi)發(fā)者的電腦的IP)的用戶可以訪問(wèn)到。

hidden-source-map

hidden-source-map - 與 source-map 相同,都會(huì)生成.map文件。但不會(huì)為 bundle 添加引用注釋。

目前,各大監(jiān)控平臺(tái)均有針對(duì)錯(cuò)誤監(jiān)控的Source Map的解析功能。例如開(kāi)源監(jiān)控平臺(tái)Sentry支持Webpack插件和自身的CLI工具上傳map文件后進(jìn)行解析。

使用hidden-source-map,當(dāng)線上報(bào)錯(cuò)時(shí),將錯(cuò)誤堆棧跟蹤信息上報(bào)給監(jiān)控平臺(tái),監(jiān)控平臺(tái)結(jié)合map文件就可以告訴我們?cè)创a級(jí)別的錯(cuò)誤信息了。

總結(jié)

通過(guò)這次配置研究,我們要學(xué)習(xí)到

  • eval配置的作用和原理。
  • source-map配置的作用和原理。
  • 開(kāi)發(fā)環(huán)境和生產(chǎn)環(huán)境視情況選擇devtool的值。

以上就是Webpack中Source Map配置深入解析的詳細(xì)內(nèi)容,更多關(guān)于Webpack Source Map配置的資料請(qǐng)關(guān)注腳本之家其它相關(guān)文章!

相關(guān)文章

  • js的函數(shù)的按值傳遞參數(shù)(實(shí)例講解)

    js的函數(shù)的按值傳遞參數(shù)(實(shí)例講解)

    下面小編就為大家分享一篇js的函數(shù)的按值傳遞參數(shù)的實(shí)例,具有很好的參考價(jià)值,一起跟隨小編過(guò)來(lái)看看吧,希望對(duì)大家有所幫助
    2017-11-11
  • 微信小程序的注冊(cè)頁(yè)面包含倒計(jì)時(shí)驗(yàn)證碼、獲取用戶信息

    微信小程序的注冊(cè)頁(yè)面包含倒計(jì)時(shí)驗(yàn)證碼、獲取用戶信息

    本文通過(guò)實(shí)例代碼給大家介紹了微信小程序的注冊(cè)頁(yè)面包含倒計(jì)時(shí)驗(yàn)證碼、獲取用戶信息的相關(guān)知識(shí),本文通過(guò)實(shí)例代碼給大家介紹的非常詳細(xì),需要的朋友可以參考下
    2019-05-05
  • 最新評(píng)論