摘要:,是一個(gè)前端資源加載打包工具,現(xiàn)在版本已經(jīng)到,今天的文章不支持介紹的及使用,而是對(duì)最近項(xiàng)目開(kāi)發(fā)中使用打包時(shí)處理低版本及以下瀏覽器兼容問(wèn)題做一次總結(jié)。
Webpack,Webpack 是一個(gè)前端資源加載/打包工具,現(xiàn)在版本已經(jīng) release 到 v2.6.1,今天的文章不支持介紹Webpack的API及使用,而是對(duì)最近項(xiàng)目開(kāi)發(fā)中使用Webpack打包時(shí)處理IE低版本(IE8及以下)瀏覽器兼容問(wèn)題做一次總結(jié)。issue直達(dá),如果文章對(duì)您有幫助歡迎 star !!!
PC端項(xiàng)目前端基礎(chǔ)技術(shù)選型jQuery + ES6 + EJS + Babel + Webpack:
jQuery:提供選擇器和ajax接口兼容支持;
ES6:跟進(jìn)前端趨勢(shì),方便向后兼容;
EJS:提供前端模板引擎支持;
Babel:提供 ES6 轉(zhuǎn)碼支持;
Webpack: 提高前端資源加載/打包;
項(xiàng)目開(kāi)發(fā)過(guò)程都在 Chrome 瀏覽器中,一切都OK,沒(méi)有任何問(wèn)題,當(dāng)在IE9以下瀏覽器中調(diào)試發(fā)現(xiàn)好多坑,現(xiàn)總結(jié)如下,以后新手參考。
Case One: default 、 class、catch ES3中保留字問(wèn)題報(bào)錯(cuò)信息:
SCRIPT1048: 缺少標(biāo)識(shí)符
對(duì)應(yīng)代碼:
e.n = function (t) { var n = t && t.__esModule ? function () { return t.default } : function () { return t }; return e.d(n, "a", n), n }
網(wǎng)上查找資料,webpack有一款loader插件es3ify-loader來(lái)處理ES3的兼容問(wèn)題,修改webpack配置,問(wèn)題解決,添加規(guī)則如下:
module: { rules: [{ test: /.js$/, enforce: "post", // post-loader處理 loader: "es3ify-loader" } ] }
這個(gè)loader是干啥用的捏,就是把這些保留字給你加上引號(hào),使用字符串的形式引用,請(qǐng)看實(shí)例:
// 編譯前 function(t) { return t.default; } // 編譯后 function(t) { return t["default"]; }Case Two: uglify-js產(chǎn)生問(wèn)題
重新構(gòu)建,在IE低版本瀏覽器預(yù)覽,使用 webpack.optimize.UglifyJsPlugin 壓縮時(shí),又報(bào)上面同樣的錯(cuò)誤了,重新采用 beauty:true, build 發(fā)現(xiàn)引號(hào)被壓縮掉了,究其原因,研究了下uglify-js默認(rèn)配置,發(fā)現(xiàn)了 compress.properties 屬性,增加build options如下,問(wèn)題解決:
new webpack.optimize.UglifyJsPlugin({ compress: { properties: false, warnings: false }, output: { beautify: true }, sourceMap: false })Case Three: uglify-js問(wèn)題
重新構(gòu)建,在IE低版本瀏覽器預(yù)覽,使用 webpack.optimize.UglifyJsPlugin 壓縮時(shí),又報(bào)上面同樣的錯(cuò)誤了,報(bào)錯(cuò)代碼:
{ catch: function (t) { return this.then(null, t) } }
繼續(xù)查找uglify-js配置,發(fā)現(xiàn) output.quote_keys,修改build options,問(wèn)題解決:
new webpack.optimize.UglifyJsPlugin({ compress: { properties: false, warnings: false }, output: { beautify: true, quote_keys: true }, sourceMap: false }),
編譯后:
{ "catch": function(t) { return this.then(null, t); } }Case Four: uglify-js問(wèn)題
重新構(gòu)建,在IE低版本瀏覽器預(yù)覽,報(bào)錯(cuò)信息如下:
SCRIPT3126: 無(wú)法設(shè)置未定義或 null 引用的屬性
繼續(xù)分析壓縮后代碼,發(fā)現(xiàn)還是uglify-js問(wèn)題,其mangle 配置屬性 mangle.screw_ie8 默認(rèn)為 true, 什么意思捏,意思就是把支持IE8的代碼clear掉,screw you => 去你的,修改壓縮配置項(xiàng),重新編譯,問(wèn)題解決:
new webpack.optimize.UglifyJsPlugin({ compress: { properties: false, warnings: false }, output: { beautify: true, quote_keys: true }, mangle: { screw_ie8: false }, sourceMap: false })Case Five: ES5的API兼容報(bào)錯(cuò)
在 webpack 的 entry 入口文件top引入 es5-shim 問(wèn)題解決
require("es5-shim"); require("es5-shim/es5-sham");Case Six: Console.log 問(wèn)題
在 webpack 的 entry 入口文件top引入 console-polyfill 問(wèn)題解決
require("console-polyfill");Case Seven: Promise 兼容
在 webpack 的 entry 入口文件top引入 es6-promise 問(wèn)題解決
require("es6-promise");Case Eight: Object.defineProperty 問(wèn)題
這個(gè)case 應(yīng)該說(shuō)是最難搞的一個(gè)case了,耗時(shí)也比較長(zhǎng),關(guān)鍵點(diǎn)在于使用 es5-shim/es5-sham也有問(wèn)題,查看你官網(wǎng)發(fā)現(xiàn)在低版本瀏覽器也會(huì)有問(wèn)題,官網(wǎng)描述如下:
?? Object.defineProperty
In the worst of circumstances, IE 8 provides a version of this method that only works on DOM objects. This sham will not be installed. The given version of defineProperty will throw an exception if used on non-DOM objects.
In slightly better circumstances, this method will silently fail to set "writable", "enumerable", and "configurable" properties.
Providing a getter or setter with "get" or "set" on a descriptor will silently fail on engines that lack "defineGetter" and "defineSetter", which include all versions of IE.
https://github.com/es-shims/e...
那這個(gè)Object.defineProperty 是如何產(chǎn)生的呢,這個(gè)是babel編譯后產(chǎn)生的,當(dāng)我們?cè)诖a使用 import export ES6 Module時(shí)出現(xiàn)的,那你可能最直接的想法就是我不用ES6 Module了,改用Commonjs規(guī)范,OK,修改后編譯,確實(shí)解決了問(wèn)題,但是查看代碼里還是有一段代碼的,如下:
e.d = function(t, n, r) { e.o(t, n) || Object.defineProperty(t, n, { "configurable": !1, "enumerable": !0, "get": r }); }, e.n = function(t) { var n = t && t.__esModule ? function() { return t["default"]; } : function() { return t; }; return e.d(n, "a", n), n; }, e.o = function(t, e) { return Object.prototype.hasOwnProperty.call(t, e); }
看代碼已經(jīng)做了容錯(cuò)判斷。
Case Nine: Object.defineProperty 問(wèn)題重新構(gòu)建,加入 json3 處理 JSON 對(duì)象兼容時(shí),代碼在此處拋出了異常:
var hasGetter = "get" in descriptor; var hasSetter = "set" in descriptor; if (!supportsAccessors && (hasGetter || hasSetter)) { throw new TypeError(ERR_ACCESSORS_NOT_SUPPORTED); }
分析supportsAccessors代碼邏輯:
var supportsAccessors = owns(prototypeOfObject, "__defineGetter__");
通過(guò)斷點(diǎn)調(diào)試,supportsAccessors值為false且hasGetter或者h(yuǎn)asSetter時(shí)拋出了異常,也就是說(shuō)當(dāng)前js引擎不支持訪問(wèn)器屬性,卻在屬性描述符中設(shè)置了get,set,那么就會(huì)拋出異常。查看 defineGetter 的兼容情況,只兼容IE11,雖然IE9、IE10同樣不支持defineGetter,不過(guò)他們直接支持Object.defineProperty方法和get語(yǔ)法,無(wú)需sham,所以代碼并不會(huì)走到異常這里。但是IE8以下就扯淡了。解決這種情況只能修改源代碼了。
至此,Webpack打包時(shí),IE低版本瀏覽器(IE8及以下)遇到的兼容問(wèn)題就總結(jié)這里,如果你有新的問(wèn)題,歡迎留言。
感謝您的閱讀
--eof--
作者[煦涵]
2017年05月28日
下面是「FED實(shí)驗(yàn)室」的微信公眾號(hào)二維碼,歡迎長(zhǎng)按、掃描關(guān)注:
文章版權(quán)歸作者所有,未經(jīng)允許請(qǐng)勿轉(zhuǎn)載,若此文章存在違規(guī)行為,您可以聯(lián)系管理員刪除。
轉(zhuǎn)載請(qǐng)注明本文地址:http://systransis.cn/yun/83261.html
摘要:,下一代編譯器,當(dāng)前版本,它可以處理的所有新語(yǔ)法,并內(nèi)置了擴(kuò)展及類型注解支持,如果對(duì)不是很了解可以查看實(shí)驗(yàn)室微信公眾號(hào)文章煦涵說(shuō)。 Babel,下一代javascript編譯器,當(dāng)前版本 v2.4.0 ,它可以處理ES6的所有新語(yǔ)法,并內(nèi)置了React JSX擴(kuò)展及Flow類型注解支持,如果對(duì)Flow不是很了解可以查看FED實(shí)驗(yàn)室微信公眾號(hào)文章煦涵說(shuō)Flow。 Babel與JavaSc...
摘要:是一個(gè)新的包管理器,它由開(kāi)發(fā)者共同開(kāi)發(fā)完成。從包管理器中借鑒,創(chuàng)建了文件,用來(lái)記錄項(xiàng)目使用每個(gè)包的確切版本。感謝您的閱讀作者煦涵年月日下面是實(shí)驗(yàn)室的微信公眾號(hào)二維碼,歡迎長(zhǎng)按掃描關(guān)注 Yarn是一個(gè)新的Javascript包管理器,它由Facebook, Google, Exponent and Tilde開(kāi)發(fā)者共同開(kāi)發(fā)完成。Yarn 不是 NPM 的fork版本,而是它的重新設(shè)計(jì),Y...
摘要:現(xiàn)在已經(jīng)在前端比較流行的等框架中得到使用。今天煦涵就和大家一起來(lái)學(xué)習(xí)以及在實(shí)際項(xiàng)目中的使用。安裝這里我們選擇使用,當(dāng)前你也可以使用如果你對(duì)不是很了解,建議你閱讀煦涵說(shuō)。 Flow是Facebook出品的一個(gè)JavaScript代碼的靜態(tài)類型檢查工具,它做了很多處理,使您的代碼更快,更智能,更自信,更好的適應(yīng)性?,F(xiàn)在已經(jīng)在前端比較流行的React 、Vue 等框架中得到使用。今天煦涵就和...
摘要:對(duì)象表示法,是一種數(shù)據(jù)交換格式,能夠在服務(wù)器端交換數(shù)據(jù),年由提出,目的是取代繁瑣笨重的格式。煦涵煦涵煦涵煦涵煦涵參考文檔感謝您的閱讀作者煦涵年月日下面是實(shí)驗(yàn)室的微信公眾號(hào)二維碼,歡迎長(zhǎng)按掃描關(guān)注 JSON(Javascript Object Notaion, javascript 對(duì)象表示法), 是一種數(shù)據(jù)交換格式,能夠在服務(wù)器端交換數(shù)據(jù), 2001年由Douglas Crockfor...
摘要:入門本節(jié)描述從獲取工件到在應(yīng)用程序中使用它如何開(kāi)始使用高級(jí)別客戶端。保證能夠與運(yùn)行在相同主版本和大于或等于的次要版本上的任何節(jié)點(diǎn)通信。與具有相同的發(fā)布周期,將版本替換為想要的客戶端版本。 Java High Level REST Client 入門 本節(jié)描述從獲取工件到在應(yīng)用程序中使用它如何開(kāi)始使用高級(jí)別REST客戶端。 兼容性 Java High Level REST Client需...
閱讀 2491·2021-09-28 09:36
閱讀 3635·2021-09-22 15:41
閱讀 4456·2021-09-04 16:45
閱讀 2087·2019-08-30 15:55
閱讀 2875·2019-08-30 13:49
閱讀 852·2019-08-29 16:34
閱讀 2409·2019-08-29 12:57
閱讀 1706·2019-08-26 18:42