煦涵说Webpack-IE低版本兼容指南

Webpack,Webpack 是一个前端资本加载/打包东西,如今版本已 release 到 v2.6.1,本日的文章不支撑引见Webpack的API及运用,而是对近来项目开辟中运用Webpack打包时处置惩罚IE低版本(IE8及以下)浏览器兼容题目做一次总结。issue直达,假如文章对您有协助迎接 star !!!

《煦涵说Webpack-IE低版本兼容指南》

PC端项目前端基本手艺选型jQuery + ES6 + EJS + Babel + Webpack:

  • jQuery:供应选择器和ajax接口兼容支撑;
  • ES6:跟进前端趋向,轻易向后兼容;
  • EJS:供应前端模板引擎支撑;
  • Babel:供应 ES6 转码支撑;
  • Webpack: 进步前端资本加载/打包;

项目开辟历程都在 Chrome 浏览器中,一切都OK,没有任何题目,当在IE9以下浏览器中调试发明很多坑,现总结以下,今后新手参考。

Case One: defaultclasscatch ES3中保留字题目

报错信息:

SCRIPT1048: 缺乏标识符

对应代码:

e.n = function (t) {
    var n = t && t.__esModule ? function () {
        return t.default
    } : function () {
        return t
    };
    return e.d(n, "a", n), n
}

网上查找材料,webpack有一款loader插件es3ify-loader来处置惩罚ES3的兼容题目,修正webpack设置,题目处理,增添划定规矩以下:

module: {
    rules: [{
            test: /.js$/,
            enforce: 'post', // post-loader处置惩罚
            loader: 'es3ify-loader'
        }
    ]
}

这个loader是干啥用的捏,就是把这些保留字给你加上引号,运用字符串的情势援用,请看实例:

// 编译前
function(t) { return t.default; }

// 编译后
function(t) { return t["default"]; }

Case Two: uglify-js发生题目

从新构建,在IE低版本浏览器预览,运用 webpack.optimize.UglifyJsPlugin 紧缩时,又报上面一样的错误了,从新采纳 beauty:true, build 发明引号被紧缩掉了,究其原因,研讨了下uglify-js默许设置,发明了 compress.properties 属性,增添build options以下,题目处理:

new webpack.optimize.UglifyJsPlugin({
    compress: {
        properties: false,
        warnings: false
    },
    output: {
        beautify: true
    },
    sourceMap: false
})

Case Three: uglify-js题目

从新构建,在IE低版本浏览器预览,运用 webpack.optimize.UglifyJsPlugin 紧缩时,又报上面一样的错误了,报错代码:

{
    catch: function (t) {
        return this.then(null, t)
    }
}

继承查找uglify-js设置,发明 output.quote_keys,修正build options,题目处理:

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题目

从新构建,在IE低版本浏览器预览,报错信息以下:

SCRIPT3126: 没法设置未定义或 null 援用的属性

继承剖析紧缩后代码,发明照样uglify-js题目,其mangle 设置属性 mangle.screw_ie8 默许为 true, 什么意义捏,意义就是把支撑IE8的代码clear掉,screw you => 去你的,修正紧缩设置项,从新编译,题目处理:

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兼容报错

在 webpack 的 entry 进口文件top引入 es5-shim 题目处理

require('es5-shim');
require('es5-shim/es5-sham');

Case Six: Console.log 题目

在 webpack 的 entry 进口文件top引入 console-polyfill 题目处理

require('console-polyfill');

Case Seven: Promise 兼容

在 webpack 的 entry 进口文件top引入 es6-promise 题目处理

require('es6-promise');

Case Eight: Object.defineProperty 题目

这个case 应当说是最难搞的一个case了,耗时也比较长,症结点在于运用 es5-shim/es5-sham也有题目,检察你官网发如今低版本浏览器也会有题目,官网形貌以下:

⚠️ 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…

那这个Object.defineProperty 是怎样发生的呢,这个是babel编译后发生的,当我们在代码运用 import export ES6 Module时涌现的,那你能够最直接的主意就是我不必ES6 Module了,改用Commonjs范例,OK,修正后编译,确切处理了题目,然则检察代码里照样有一段代码的,以下:

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);
}

看代码已做了容错推断。

Case Nine: Object.defineProperty 题目

从新构建,到场 json3 处置惩罚 JSON 对象兼容时,代码在此处抛出了非常:

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__');

经由过程断点调试,supportsAccessors值为false且hasGetter或许hasSetter时抛出了非常,也就是说当前js引擎不支撑接见器属性,却在属性形貌符中设置了get,set,那末就会抛出非常。检察 defineGetter 的兼容状况,只兼容IE11,虽然IE9、IE10一样不支撑defineGetter,不过他们直接支撑Object.defineProperty要领和get语法,无需sham,所以代码并不会走到非常这里。然则IE8以下就扯淡了。处理这类状况只能修正源代码了。

至此,Webpack打包时,IE低版本浏览器(IE8及以下)碰到的兼容题目就总结这里,假如你有新的题目,迎接留言。

感谢您的浏览

–eof–

作者[煦涵]
2017年05月28日

下面是「FED实验室」的微信民众号二维码,迎接长按、扫描关注:
《煦涵说Webpack-IE低版本兼容指南》

    原文作者:FEDLAB
    原文地址: https://segmentfault.com/a/1190000009613296
    本文转自网络文章,转载此文章仅为分享知识,如有侵权,请联系博主进行删除。
点赞