前陣子重構了一個挺有意思的項目,是一個基于瀏覽器環境的數據采集sdk。公司各個產品的前端頁面中都嵌入了這個sdk,用于采集用戶的行為數據,上傳到公司的大數據平臺,為后續的運營決策分析提供數據支撐。
筆者接手這個項目的時候,前任開發者已經把功能都寫差不多了。唯一需要做的就是做下模塊化拆分和代碼規范,以便后續的開發維護。模塊化拆分用webpack,代碼規范用eslint。既然要重構,那就順手用es6重寫吧。callback也不要了,全換成promise,async、await也用起來,反正怎么爽怎么寫。
問PM瀏覽器最低兼容到哪個版本,PM說兼容公司各個產品所兼容的最低版本就行。和公司各個產品的前端負責人溝通后發現,居然有兼容IE8的,真是我了個fk。
google了一下Webpack+Babel+ES6兼容IE8,果然坑很多。試了好幾篇博客給出的方案,都跑不通。也沒怎么研究具體哪里有問題,因為那些解決方案里面的webpack和babel都是舊版的,跑通了也不高興用。筆者分析了那些博客中提出的幾個關鍵性問題,然后參考webpack和babel最新的官方文檔,總結出一套最新的Webpack4+Babel7+ES6兼容IE8的方案。
ES6兼容IE8需要解決四個問題
語法支持
IE瀏覽器不支持ES6的語法,只在IE10、IE11中支持了部分ES6的API,所以在IE瀏覽器中使用ES6需要把ES6的代碼編譯成ES5才能執行。方法也很簡單,就是用babel-loader。這部分沒什么坑,所以我也就不細說了。給個網站,大家可以自行查看ES5、ES6在各瀏覽器版本中的支持情況
https://kangax.github.io/compat-table/es6/
ES3保留關鍵字
如果在IE8下通過object.propertyName的方式使用ES3中的保留關鍵字(比如default、class、catch),就會報錯
SCRIPT1048: 缺少標識符
webpack有一款loader插件es3ify-loader專門用來處理ES3的關鍵字兼容問題。這個插件的作用就是把這些保留字給你加上引號,使用字符串的形式引用。
// 編譯前function(t) { return t.default; }// 編譯后function(t) { return t["default"]; }然而,筆者親身實踐后發現,UglifyJS本來就已經提供了對IE瀏覽器的支持,不需要額外引入es3ify-loader。webpack默認的UglifyJS配置不支持ie8,需要手動配下。
{ mode: 'production', optimization: { minimizer: [ new UglifyJsPlugin({ uglifyOptions: { ie8: true } }) ] }}執行環境
解決了前面兩個問題只能保證語法上不報錯,但使用ES6中的API(比如Promise)還是會報錯。另外,IE8對ES5的API支持也很差,只支持了少量的API,有些API還只是支持部分功能(比如Object.defineProperty)。所以,要在IE8中完美運行ES6的代碼,不僅需要填充ES6的API,還要填充ES5的API。
新聞熱點
疑難解答
圖片精選