重庆分公司,新征程启航
为企业提供网站建设、域名注册、服务器等服务
这篇文章主要介绍Webpack4+Babel7+ES6兼容IE8的示例分析,文中介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们一定要看完!
创新互联公司专注于企业全网整合营销推广、网站重做改版、蒙城网站定制设计、自适应品牌网站建设、H5建站、商城网站制作、集团公司官网建设、外贸营销网站建设、高端网站制作、响应式网页设计等建站业务,价格优惠性价比高,为蒙城等各大城市提供网站开发制作服务。
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。
babel为此提供了两种解决方案: @babel/polyfill、@babel/runtime。具体使用方法官方文档已经写的很详细了,笔者就不赘述了。这里纠正墨白同学文中的一个错误,就是@babel/polyfill现在已经支持按需加载,准确的说也不能算是错误,因为墨白同学在写这篇文章的时候还不支持按需加载。具体方法我就不细说了,文档里都有,配置下browserlist和@babel/preset-env的useBuiltsIns属性就可以了。
我只说下我在实际开发过程中碰到的坑。
虽然@babel/polyfill、@babel/runtime都支持按需加载,但都只能识别出业务代码中使用到的缺失的API,如果第三方库有用到这些缺失的API,babel不能识别出来,自然也就不能填充进来。比如regenerator-runtime中用到的Object.create和Array.prototype.forEach。解决办法是,在入口文件处手动引入缺失的API。
模块化加载
笔者原来是想用ES6的模块化加载方案,因为这样可以利用webpack的tree shaking,移除冗余代码,使打包出来的文件体积更小。但在IE8下测试发现Object.defineProperty会报错'Accessors not supported!'。报错代码如下
if ('get' in Attributes || 'set' in Attributes) throw TypeError('Accessors not supported!');
我用@babel/plugin-transform-modules-commonjs转成commonjs加载就可以把这个坑绕过去,但同时也意味着放弃了tree shaking。
总结
package.json
{ "devDependencies": { "@babel/core": "^7.2.2", "@babel/plugin-transform-runtime": "^7.2.0", "@babel/preset-env": "^7.1.0", "@babel/runtime": "^7.3.4", "babel-loader": "^8.0.4", "core-js": "^3.0.1", "uglifyjs-webpack-plugin": "^2.0.1", "webpack": "^4.20.2", "webpack-cli": "^3.1.2", "webpack-dev-server": "^3.1.9", "webpack-merge": "^4.1.4" } }
webpack配置
{ module: { rules: [ { test: /\.js$/, exclude: /(node_modules|bower_components)/, use: { loader: 'babel-loader', options: { presets: [ '@babel/preset-env' ], plugins: [ [ '@babel/plugin-transform-runtime' ], [ // 笔者为了兼容IE8才用了这个插件,代价是不能tree shaking // 没有IE8兼容需求的同学可以把这个插件去掉 '@babel/plugin-transform-modules-commonjs' ] ] } } } ] }, optimization: { minimizer: [ new UglifyJsPlugin({ sourceMap: true, uglifyOptions: { ie8: true, } }) ] } }
入口文件按需引入缺失的API
require('core-js/features/object/define-property') require('core-js/features/object/create') require('core-js/features/object/assign') require('core-js/features/array/for-each') require('core-js/features/array/index-of') require('core-js/features/function/bind') require('core-js/features/promise')
以上是“Webpack4+Babel7+ES6兼容IE8的示例分析”这篇文章的所有内容,感谢各位的阅读!希望分享的内容对大家有帮助,更多相关知识,欢迎关注创新互联行业资讯频道!