【webpack】你所不知道的sourceMap

sourceMap的做用

一般,js代碼出錯,控制檯會提示第幾行第幾列代碼出錯。可是webpack打包壓縮後的代碼,都被壓縮到了一行,變量也變成了a,b,c,d。代碼出錯,控制檯就無法正確的提示錯誤位置。javascript

sourceMap就能夠解決這個問題。sourceMap就是一個信息文件,裏面儲存着打包前的位置信息。也就是說,轉換後的代碼的每個位置,所對應的轉換前的位置。具體如何編碼,能夠看下阮一峯的文章css

有了它,出錯的時候,瀏覽器控制檯將直接顯示原始代碼出錯的位置,而不是轉換後的代碼,點擊出錯信息將直接跳轉到原始代碼位置。html

sourceMap的調試

  1. Console直接點擊錯誤提示跳轉到源碼(如上圖所示)

通常瀏覽器會默認開啓sourceMap調試,若是控制檯不能顯示源碼錯誤位置,則須要打開配置。前端

打開瀏覽器的這個配置後,控制檯的Console面板的錯誤提示,直接點擊就會跳轉到對應的源文件出錯位置。vue

  1. Sources面板找到源文件,進行斷點調試

若是沒Console沒報錯,可是頁面顯示不正確。能夠點擊控制檯的Sources面板,源文件都在 webpack:// 目錄下,或者直接搜索文件,打開源文件後進行斷點調試。java

按需加載的路由,只有頁面加載了,源文件纔會在這個目錄下顯示。 node

webpack配置

vue-cli3的vue.config.js文件:webpack

module.exports = {
    productionSourceMap: false, //默認是true
}
複製代碼

打包後的文件:git

對於打包後的sourceMapwebpack提供多種類型的配置github

其中,開發環境使用:

  • eval:會把每一個模塊封裝到 eval 裏包裹起來執行,而且會在末尾追加map文件的地址。map文件映射到轉換後的代碼(可執行的js文件),而不是映射到原始代碼(vue文件),因此不能正確的顯示錯誤行數。

  • eval-source-map: 和 eval 相似,爲每一個模塊生成原始的sourceMapmap文件會以dataURL的形式添加到js中(相似於圖片的base64形式)。原始的sourceMap能夠正確提示錯誤行數。

  • cheap-eval-source-map: 跟eval-source-map相同,惟一不一樣的就是增長了cheapcheap是指忽略了列信息(絕大部分時候列信息對於錯誤提示沒啥用,只須要提示行數就行)。

  • cheap-module-eval-source-map: 與cheap-eval-source-map相同,可是包含了不一樣loader模塊之間的sourceMap。例如藉助babel編譯ES6,若是生成不包含loadersourcemap,此時debug到的將是編譯後的代碼,而非原始代碼。

生產環境使用:

  • source-map: map文件包含完整的原始代碼,可是打包會很慢。打包後的js最後一行是map文件地址的註釋

  • hidden-source-map:與 sourceMap 相同,也生成map文件,可是打包後的js最後沒有map文件地址的引用。瀏覽器不會主動去請求map文件,通常用於網站錯誤分析,須要讓錯誤分析工具按名稱匹配到map文件。

  • nosources-source-map:生成的map文件不包含源碼,可是會正確提示錯誤的行數。另外項目的目錄結構和文件名稱會暴露在Sources面板

特定環境用(針對一些第三方工具,用的不多,暫不詳細討論):

  • inline-source-map
  • inline-cheap-source-map
  • inline-cheap-module-source-map
  • cheap-source-map
  • cheap-module-source-map

其實就是inline,cheap,module,source-map的自由組合。

  • inline 是以dateURL的形式添加map,不額外生成map文件
  • cheap 是沒有列信息
  • module 是包含了loadersourcemap
  • source-map 則是映射到源文件

不一樣的參數,生成的sourceMap不一樣,打包速度、體積、錯誤提示的效果也不一樣。而vue-cli3幫咱們預選了一種模式:

開發環境,配置文件位置:node_modules\\@vue\cli-service\lib\config\dev.js,第5行

生產環境,配置文件位置: \node_modules\\@vue\cli-service\lib\config\prod.js,第11行

另外:css一樣有sourceMap不過vue-cli3是默認關閉的

module.exports = {
    css: {
        sourceMap: false, //默認false
    }
}
複製代碼

sourceMap的安全問題

事情都是具備兩面性的,方便調試的同時,也將源碼暴露在控制檯,可能會致使代碼泄露的安全問題。

雖說前端代碼是公開的,可是代碼的壓縮混淆也必定程度上提升了安全性。

代碼泄露可能致使的問題:

  1. 代碼被抄襲

場景:給A客戶寫了一個地圖功能,A客戶展現給B客戶,B客戶想要寫地圖,可是不會,查看源碼後,抄走了地圖功能

  1. 業務流失

場景:競爭對手拿到了源碼,挑出其中的漏洞或者缺陷,大肆宣傳。或者直接寫一份後臺,成本少,價格低致使業務被搶走

  1. 系統被攻擊

場景:因爲項目急,鑑權是經過前端動態生成路由控制的,後臺沒作判斷,致使修改源碼後,能夠得到更多的權限(數據被刪除)

例如常見的視頻播放網站,若是不加密,直接一個<video>標籤,那麼就很容易被人拿到視頻資源,本身的會員業務也會損失。

sourceMap的處理

若是無特殊需求,生產環境是須要關閉這個選項的,vue-cli3直接配置productionSourceMap: false便可。或者不關閉可是在測試環境遷移到正式環境時刪掉map文件。也能夠經過服務器配置,特殊帳號(調試專用)能訪問到map文件,其餘用戶則不行。

若是須要控制檯能正確提示報錯的位置而不暴露源碼,推薦用nosources-source-map模式,可是這個模式會暴露源碼的目錄結構與文件命名。通常測試環境用這個比較好,QA測試出來的問題能正確提示錯誤,即便運維忘了刪除sourceMap文件,也不會暴露源碼。

// vue.config.js
module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {//只修改生產環境配置
        return {
           devtool: 'nosources-source-map',
        };
    }
  }
}

複製代碼

補充:本地sourceMap調試

  1. 辦法1 : 網絡攔截

webpack打包仍然生成sourceMap,可是將map文件挑出放到本地服務器,將不含有map文件的部署到服務器,藉助第三方軟件(例如fiddler),將瀏覽器對map文件的請求攔截到本地服務器,就能夠實現本地sourceMap調試。

  1. 辦法2 : 修改webpack打包,測試環境不放map文件,修改sourceMap的引用到本地服務器

可行性:本地調試專用,因爲測試環境和本機屬於同一個局域網,因此測試環境能夠請求到本地服務器上的sourceMap文件,部署以後,客戶訪問則不能訪問到本機的局域網IP,也就沒法拿到sourceMap文件。

缺點:其餘人打包須要修改電腦IP和本地服務器文件地址,沒法直接複用,優勢是絕對安全。或者能夠提供另外一臺專門放map文件的服務器,打包以後自動上傳map文件到這個服務器。

藉助SourceMapDevToolPlugin修改打包後的文件對map文件的引用地址,同時藉助filemanager-webpack-pluginmap文件移到到本地服務器上。代碼以下(vue.config.js):

const webpack = require('webpack')
const FileManagerPlugin = require('filemanager-webpack-plugin');

module.exports = {
  configureWebpack: config => {
    if (process.env.NODE_ENV === 'production') {
      return {
        devtool: false, // 注意SourceMapDevToolPlugin和devtool不可共存
        plugins: [
          new webpack.SourceMapDevToolPlugin({
            append: '\n//# sourceMappingURL=http://192.168.23.230/sourceMap/[url]', // 192.168.23.230是本機局域網IP
            filename: '[file].map',
          }),
          new FileManagerPlugin({
            onEnd: {
              copy: [{ 
                source: './dist/js/*.map', 
                destination: 'D:/xampp/htdocs/sourceMap', // D:/xampp/htdocs/是本地服務器的文件地址
              }],
              delete: ['./dist/js/*.map'],
              archive: [{ //順便把網站文件壓縮一下
                source: './dist',
                destination: './dist/dist.zip',
              }]
            }
          })
        ]
      };
    }
  }
}

複製代碼

這個插件主要是實現了對sourceMap的更精細控制,好比打包以後的位置,以及修改js/css文件最後面對sourceMap的引用地址。 這裏主要用到修改sourceMap引用地址的功能。

使用這個必須關閉`devtool`

這個插件的主要功能是打包以後文件的移動,刪除,拷貝,壓縮等功能,使用以前須要先安裝: npm install filemanager-webpack-plugin --save-dev

注意: 這個插件有bug,移動操做不支持模糊匹配,只能改爲複製+刪除

最後

有什麼問題,歡迎指出。

相關文章
相關標籤/搜索