Babel介绍
babel默认将es6语法转为es5,如果想要在低版本浏览器上支持es6新增的api,如Array.prototype.from等方法,则需要添加polyfill。
babel的一些主要概念介绍
babel-preset-env : 将es2015 ,es2016,es2017的语法转为es5。
babel-core: 包含transform方法,任何需要引用babel处理文件的,则需调用该方法。
babel-regiser:node中,替换require的引用,在文件中require(‘babel-register’), 然后require 相应的es6 文件,直接运行node file.js, 如果需要polyfill还是需要引入的 。babel-register相当于对本文件中的require的文件进行转换编译,除了自己,使用方法如下:
babel-cli: 提供命令行执行转换es6文件并输出。
babel-node: 相当于提供了个node 命令,但是会在执行node命令之前对es6进行编译,不建议在production中使用,由于编译中的缓存数据存储在内存中,造成性能问题。
babel-polyfill: 模拟了一个全面的es5环境,添加polyfill有3种方法:
全局添加polyfill,在webpack的entry中,例如:entry:[‘babel-plyfill’, ‘.index.js’];缺点是全局污染。
babel-runtime,将所需的polyfill 额外打包成一个help.js 文件,然后再所需之处对这个文件进行引用,手动引用的工作可以用babel-plugin-transform-runtime插件,在.babelrc文件中配置,会自动替换手动的工作。缺点是不能应用实例方法。理由:如”foobar”.includes(“foo”) (在转换时难找到相对应的目标方法替换),可以转换静态方法。
babel-preset-env, 有个配置选项useBuiltIn,如果true则自动添加所需的babel-polyfill,而在入口文件处需引入require(’babel-polyfill’),这也是官方推荐的。配置如下:
重点说下polyfill,有了polyfill我们可以在任何低版本的浏览器上写es6的新方法,由于公司支持到ie8,所以试下在IE8上去写es6,然后想法很美好,现实很骨感!
步骤如下:
新建个main.js ,里面包含最简单的es6语法,箭头和map函数。
webpack.config.js配置:
.babelrc配置:
以为这样就外事大吉了,少年你还是太年轻了,打开IE8,报错如下,缺少标识符:
点击进去查看:
查找资料,得出结论是IE8中用的是es3的语法,所以需要将es5的语法转为es3的,利用babel提供的2个插件:transform-es3-member-expression-literals 和transform-es3-property-literals ,这2个插件做的事情其实是将关键字如default、return等,写法改变一下,给关键字加上引号,重新生成结果如下:
然后打包,刷新浏览器,发现报堆栈溢出,报错如下,
去Github上查看,发现原来babel-polyfill 中包含的core-js是不可以经过babel转换的。
于是在babel-loader转换处,exclude 对core-js的转换:
刷新页面,又报错了:
原因是由于Object.defineProperty只能用在DOM对象上,如果传入普通的js对象,则报错。自己如果手动hack,为抛错的那行加上try,catch则一切正常了。阿里的这篇文章 提供了很好的分析思路。
附上github上未被解决的理由…
babel-polyfill这条路走不通,按照上面core-js作者说的,还是有方法可以实现的,查找资料说是可以通过es5-shim(即es3对es5某些方法的实现)实现试试:
打包,刷新浏览器,运行正确了,alert了三次(此处放鞭炮)。
如果需要增加对import 和export的依赖,如代码:
刷新运行,报错了,
根据babel官网的介绍,需要在presets里增加loose: true 选项。
最终.babelrc的配置如下:
以上代码在如下环境中运行:
在ie8环境中基本实现了es6的写法,如果需支持其他的写法,则另需要增加插件polyfill的引用,如:promise,Object.assign等方法。
本博客所有文章除特别声明外,均采用 CC BY-SA 4.0 协议 ,转载请注明出处!