UglifyJs打包壓縮問題引發的思考

問題背景

最近作了一個webapp項目,qa用手機測試功能時,在iphone6plus上表現是白屏,其餘手機目測是ok的;由於以前在測試其餘項目時也發如今這個iphone6上表現與其餘手機不太同樣。因而當時覺得這個手機出了什麼問題,或者其版本太低;就不放在心上。javascript

然而此次白屏的影響仍是要加以重視,因而在空閒的時候主動看了下,用VSCosole查看了日誌信息,控制檯報了一個警告信息:java

unexception token const ...

而後看了加載的js源碼,居然發現一個大坑:webpack

  • 代碼沒有壓縮git

  • 部分代碼也沒有編譯成es5es6

這時內心頓生一陣陣的涼意,辛虧看了一下這個問題,不然發到線上會有重大問題。github

uglifyjs爲啥會報錯

出現上面的問題,首先會想到的webpack的壓縮代碼插件出問題了,項目中使用uglifyjs-webpack-plugin來壓縮代碼。因而在本地執行發佈上線的操做代碼編譯壓縮,果不其然,壓縮相似這樣的錯誤:web

ERROR in static/javascripts/test_0_30fbc92.js from UglifyJs
Unexpected token: name (instance) [static/javascripts/test_0_30fbc92.js:2854,6]

具體能夠看下圖:api

而後定位到指定文件的報錯的位置,發現都是es6的語法:數組

  • 第一個文件2874行的內容:let instance瀏覽器

  • 第二個文件78行的內容: function loadJS(url, {timeout = 5000, crossOrigin = false } = {}) {

能夠看到,這兩個位置都是文件第一次出現es6沒有編譯的位置,其實在此以後還有不少未編譯的es6語法。

可能到這裏有人會問,上面壓縮報錯爲何還能在非iphone6p的其餘手機上能夠正常訪問到呢,可能緣由以下:

  • uglifyjs-webpack-plugin雖然報錯可是並不會阻止代碼的產出,從上圖也能夠看出代碼已經產出。只不過其內容沒有壓縮

  • 另外一個緣由我猜是未出現問題的手機上打開瀏覽器已經支持這些es6語法

分析了這麼多,爲啥uglifyjs-webpack-plugin會報錯呢,由於當前引用uglifyjs-webpack-plugin的版本爲0.4.6,它依賴的是uglify-js; 它不支持壓縮 es6,能夠參考github的issueIt seems like uglify-js does not support es6?

因此:

uglify-js在壓縮代碼時,遇到es6語法就不會壓縮而且也會報錯。

若是想壓縮e6代碼,可使用uglify-es,其提供配置屬性ecma來壓縮不一樣類型的js。

es6爲啥沒有編譯

上面分析咱們得知,uglify-webpack-plugin之因此沒有壓縮,由於代碼混合es6語法,那麼es6語法爲啥沒有編譯呢?推測:

在使用babel來編譯es6時,因爲webpack錯誤配置的緣由致使某些文件不在指定的babel編譯範圍,babel從而會忽略這些js文件的編譯

咱們的項目目錄結構以下:

這是個多個微系統共用的一個工程,這些微系統共用的組件大部分相同,他們共用一個webpack配置。

webpack的有關js的配置以下所示:

{
      test: /\.js$/,
      loader: 'babel-loader',
      include: [
        path.resolve('moudleA'),
        path.resolve('moudleB')
      ]
    }

可是與服務端交互的api目錄、公共組件components目錄以及公共的js方法目錄common目錄沒有配置進上面babel-loader的include數組中,從而babel-loader會忽略這些目錄下的js文件編譯,致使這些目錄下的js文件沒有被babel-loader編譯。從而致使上述問題。

因此,總結一下:

開發過程當中遇到任何問題仍是須要認真對待一下,保持一顆這就是bug的心態去發現並找出緣由所在,才能下降線上出現重大問題的風險。

參考

相關文章
相關標籤/搜索