版权声明:本文为博主原创文章,遵循 CC 4.0 by-sa 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://ligang.blog.csdn.net/article/details/54691218
最近,公司Node项目正式切换为了Koa2,正式启用了ES6,然而一些语法(如,import)在Node6版本中并未支持。所以我们需要使用Babel进行转换,目前我们采用了Babel6去实现转换。
一、Babel6的由来
默认情况下,Babel自带了一组ES2015语法转换器。这些转换器能让你现在就使用最新的JavaScript语法,而不用等待浏览器或Node提供支持。同时,Babel内嵌了对JSX的支持,可以让源码的语法渲染上升到一个全新的水平。Babel由插件组成。通过利用现有的插件或者开发你自己的插件可以组合出满足你自身需要的转换管道。 过去的一年,Babel团队认为Babel不应该仅仅只是个ES6语法转换器,取而代之的,它应该成为一个平台,它应该包括一组精心设计的工具用于创建下一代JavaScript工具集。Babel有能力驱动代码压缩、代码规范(Linter)、代码格式化、语法高亮、代码完成工具、类型检查、codemod工具等一系列功能,Babel能够让JavaScript社区朝着更好的方向发展。因此,发布了Babel6。这应该有史以来Babel最重要的一次更新,因为它能让Babel更坚实的迈向平台化。
二、Babel6的主要变化
1. 模块化
模块化是Babel6中最大的变化,所有的内部组件都被抽取出来重构为单独的插件,每个插件都定义了一个轻量级的公共API,从而可以被其他组件所独立依赖。如果你想使用某些Babel内部组件执行某种构建任务,现在,只需要单独的去安装这个插件,然后就能完成任务。
2. 可选的插件
因为Babel现在的目标不仅仅是作为ES2015的转换器,而是作为一个JavaScript工具平台,因此所有的插件都是可插拔的。这就意味着,如果你现在直接安装Babel的最新版本,那么默认情况下它并没有用来转换ES2015的代码的功能,你需要安装相应的转换器插件。
3. 插件预设
在配置文件中指定和维护大量的转换器信息可能会导致大量的工作,因此Babel 6引入了插件预设值的概念,可以用于组织相似的插件。
三、配置
1. 安装
代码语言:javascript复制# 在命令行使用Babel,你可以安装babel-cli
$ npm install --global babel-cli
# 在一个Node项目中使用Babel,你可以安装babel-core
$ npm install --save-dev babel-core
需要注意,安装babel-cli会依赖安装babel-core
2. .babelrc文件
.babelrc
结尾的文件通常代表运行时自动加载的文件,配置等等的。即,转换依据。运行Babel时,首先会查找当前目录下是否有.babelrc
文件;如果不存在,将会依次查找上级目录是否有.babelrc
文件或package.json
中是否具有"babel": {}
哈希值。
(1)预设插件-presets
如果不想自己组装插件,可以通过presets使用“预设”的插件集。
每个年度预设只编译当年批准。每年使用preset-latest变换所有预设
- env:根据支持环境自动编译
- latest:所有你需要编译ES2015 (目前包含:es2017、 - es2016、es2015)
- es2017:只编译ES2017到ES2016的内容
- es2016:只编译ES2016到ES2015的内容
- es2015:仅编译ES2015到ES5
- react:剥离类型注释并将JSX转换为createElement调用
(2)手动插件-plugins
plugins:转码逻辑通过一系列插件实现,默认不使用任何插件。
手动配置这些单一特性非常的繁琐,这只适用于你仅仅使用了某几个ES6、ES7的新特性,如果不是这种情况,你可以直接安装插件的预设。
(3)env选项
可以使用env选项针对特定环境进行设置。此env值会从process.env.BABEL_ENV
中获取;如果该值不存在,会使用process.env.NODE_ENV
;二者都不存在,使用默认值”development”。
示例:使用ES6及ES7中的async functions
代码语言:javascript复制npm install --save-dev babel-cli babel-preset-es2015
npm install --save-dev babel-plugin-transform-async-to-generator
{
"presets": ["es2015"],
"plugins": ["transform-async-to-generator"]
}
需要其他新版本功能可通过http://babeljs.io/docs/plugins/进行查找! 注意:上述遇到ES7的async会先转换成ES6的generator,最后转换成ES5的普通函数! 示例:线上模式使用”transform-runtime”避免全局污染
代码语言:javascript复制npm install --save-dev babel-cli babel-preset-es2015
npm install --save-dev babel-plugin-transform-async-to-generator
npm install --save-dev babel-plugin-transform-runtime
npm install --save babel-runtime
{
"presets": ["es2015"],
"plugins": ["transform-async-to-generator"],
"env": {
"production": {
"plugins": ["transform-runtime", {
"helpers": false, // 默认是true
"polyfill": false, // 默认是true
"regenerator": true, // 默认是true
"moduleName": "babel-runtime" // 默认是"babel-runtime"
}]
}
}
}
transform-runtime
插件避免每个文件共有的代码编译出重复代码块以及污染全局。
四、使用
有三种方式,实现转换。所有转换依赖规则可以通过上述.babelrc进行配置。
方式一:babel-polyfill
babel-polyfill包含 regenerator runtime 和 core-js。这将模拟一个完整的ES2015 环境,旨在用于应用程序而不是库/工具。
代码语言:javascript复制npm install --save babel-polyfill
因为这是一个polyfill(它会在你的源代码之前运行),所以我们需要它是一个dependency,而不是一个devDependency
示例
代码语言:javascript复制/* test.js */
require('babel-polyfill');
function a(callback) {
callback();
}
a(() => {
console.log(Array.from(...arguments));
console.log(123);
});
直接运行test.js即可,node test.js
方式二:babel-node
默认会调用babel-polyfill
。需要注意,在生产环境下,不能使用该方式,因为其所有转换都缓存在内存中,会导致内存使用率过高,带来一定的风险!
babel-node test.js
方式三:babel
将源文件按照.bablerc设置要求转换成相关内容保存到其他文件中。
代码语言:javascript复制# 单个文件
babel test.js --out-file test-compiled.js
# 目录
babel src --out-dir dist
具体内容,请参照:http://babeljs.io/docs/usage/cli/
方式四:编译工具
如,webpack
代码语言:javascript复制npm install --save-dev babel-loader babel-core
代码语言:javascript复制module: {
rules: [
{
test: /.js$/,
exclude: /(node_modules|bower_components)/,
use: {
loader: 'babel-loader',
options: {
presets: ['es2015'],
plugins: [require('transform-async-to-generator')]
}
}
}
]
}
注意: exclude可以是正则、绝对路径、函数。使用webpack配置后,无需.babelrc文件!