前言:随着ES6和ES7标准的出现,JavaScript语言标注引入了大量的新语言和新的API,无疑这些新的特性给我前端开发带来了极大的便利,但是很不幸的是目前只有相对较新的浏览器才支持这些特性,如果我们想在低版本浏览器使用这些的新的语法和API,就需要一个工具来将它解析成低版本浏览器能识别的语法,于是babel就诞生了!
1.如何编译
babel工作时会去项目根目录下寻找.babelrc或者babel.config.js配置文件,根据配置文件里的配置信息来对js语法进行编译。
配置格式如下
{
"presets": [
["env", { "modules": false }],
"stage-2"
],
"plugins": ["transform-runtime"]
}
presets :预设
babel通过插件来告诉它如何编译和要编译那些js语言,比如我们想要编译let关键字,就需要引入let相关的插件,要编译箭头函数,就要引入箭头函数相关的插件,由于一个一个引入配置比较麻烦,babel官方就这些常用的插件封装成了一组plugin集合,这样我们就只需配置一次了。
{
"plugins": [
"check-es2015-constants",
"es2015-arrow-functions",
"es2015-block-scoped-functions",
// ...
]
}
引入babel-preset-env之后,只需配置一行
{
"presets":["env"]
}
plugins:有一些插件在presets集合里没有包含,这时候我们还得通过插件来配置
比如:bable-polyfill与babel-runtime
Babel默认只转换新的javascript语法,而不转换新的API,比如 Iterator, Generator, Set, Maps, Proxy, Reflect,Symbol,Promise 等全局对象。以及一些在全局对象上的方法(比如 Object.assign)都不会转码。比如说,ES6在Array对象上新增了Array.form方法,Babel就不会转码这个方法,如果想让这个方法运行,必须使用 babel-polyfill来转换等。babel-polyfill与babel-runtime就是为了解决这些新的API的
比较:
babel-polyfill:当前运行环境不支持新的API时,babel-polyfill向全局对象或内置对象的原型上添加属性来实现,缺点是可能造成全局变量的污染。
babel-runtime:它是将es6编译成es5去执行。我们使用es6的语法来编写,最终会通过babel-runtime编译成es5.也就是说,不管浏览器是否支持ES6,只要是ES6的语法,它都会进行转码成ES5.所以就有很多冗余的代码。这时我们就是通过import来按需导入需要兼容的API,但是如果我现在有100个文件甚至更多的话,难道我们需要一个个文件加import Promise from 'babel-runtime/core-js/promise' 吗?那这样肯定是不行的,因此这个时候出来一个 叫 babel-plugin-transform-runtime。
babel-plugin-transform-runtime:babel-plugin-transform-runtime会自动帮我们polyfill当前环境不支持的API,不需要我们一个一个去导入,polyfill包就在在babel-runtime
这个包里。
配置项:
helpers: 默认值为true,表示是否开启内联的babel helpers(即babel或者环境本来存在的某些对象方法函数)如:extends,etc这样的
在调用模块名字时将被替换名字。
polyfill:默认值为true,表示是否把内置的东西(Promise, Set, Map)等转换成非全局污染的。
regenerator:默认值为true,是否开启generator函数转换成使用regenerator runtime来避免污染全局域。
moduleName:默认值为 babel-runtime,当调用辅助 设置模块(module)名字/路径.
presets中的配置项:
modules:将ES6模块语法转换为另一种模块类型。将该设置为false就不会转换模块。默认为 'commonjs'.
在webpack中设置为false,,因为webpack已经帮我们做了这件事。