1. babel 5.x 和babel 6.x
babel 5.x -> 6.x 的变化非常大,15 年 11 月,Babel 发布了 6.0 版本。相较于前一代 Babel 5,新一代 Babel 更加模块化, 将所有的转码功能以插件的形式分离出去,默认只提供 babel-core,babel-cli两个不同方式的转换平台。原本只需要装一个 babel ,现在必须按照自己的需求配置,灵活性提高的同时也提高了使用者的学习成本。
2. babel 5.x
babel 5.x包囊括了整个编译器、所有的转换器以及一个CLI工具, 这么做的缺点就是它会导致很多不必要的下载,并且代码也令人困惑,灵活性也很差。
3. babel 6.x
babel 6.x已经不存在babel包了,转而代之的是babel-cli和babel-core两个包。babel-cli是用于命令行的代码转换,而babel-core是用于项目编译环境。
4. babel-cli
安装babel-cli(用于在终端使用babel )######
npm install -g babel-cli
然后安装babel-preset-es2015插件集######
npm install --save babel-preset-es2015
在命令行输入:######
babel es6.js --presets es2015
输出:######
"use strict";
[1, 2, 3].map(function (x) {
return x * x;
});
.babelrc#####
命令行中,我们可以发现都会带有相关插件参数,也可以在.babelrc文件中配置:
{
"presets": ["es2015"],
"plugins": []
}
5. AST(抽象语法树)
如果对于源代码而言,AST就是源代码的抽象语法结构的树状表现形式。举个例子说明:
源代码:####
let a = "hello";
let b = a;
转换后的AST:####
# of nodes: 9
# of tokens: 10
Tokens:
Keyword(let) Identifier(a) Punctuator(=) String("hello") Punctuator(;)
Keyword(let) Identifier(b) Punctuator(=) Identifier(a) Punctuator(;)
6. babel-core:
babel-core 的作用是把 js 代码分析成 ast ( 抽象语法树 ,是源代码的抽象语法结构的树状表现形式),方便各个插件分析语法进行相应的处理。有些新语法在低版本 js 中是不存在的,如箭头函数,rest 参数,函数默认值等,这种语言层面的不兼容只能通过将代码转为 ast,分析其语法后再转为低版本 js。首先安装 babel-core。
安装 babel-core####
npm install babel-core
引入 babel-core####
var babel = require("babel-core");
字符串形式的 JavaScript 代码编译####
var result = babel.transform("code();", {plugins:[],preset:{}...});
result.code;//
result.map;//
result.ast;//
如果是文件的话,可以使用异步 api:####
var result = babel.transformFile("filename.js", {plugins:[],preset:{}...}, function(err, result) {
result.code;//
result.map;//
result.ast;//
});
如果是文件的话,也可以使用同步 api####
var result = babel.transformFile("filename.js", {plugins:[],preset:{}...});
result.code;//
result.map;//
result.ast;//
7. babel 配置:
你或许已经注意到了,目前为止通过运行 Babel 自己我们并没能“翻译”代码,而仅仅是把代码从一处拷贝到了另一处。这是因为我们还没告诉 Babel 要做什么。你可以通过安装插件(plugins)或预设(presets,也就是一组插件)来指示 Babel 去做什么事情。
.babelrc 插件配置#####
接下来我们要让babel去把es6语法翻译为浏览器可以识别的es5语法。比如箭头函数和常量,所以我们给它添加了两个插件:babel-plugin-transform-es2015-arrow-functions,babel-plugin-transform-es2015-constants
{
"presets": [],
"plugins": ["transform-es2015-arrow-functions","babel-plugin-transform-es2015-constants"]
}
此时,babel就可以转换es6的箭头函数和let常量了。但有的时候,我们还需要很多转换,因此插件的数量会越来越多,当然手动配置这些单一特性非常的繁琐,所以babel提供了presets预设,也就是一套插件集。这样就很方便,而无需一个一个插件的安装和设置。目前,插件集有:babel-preset-es2015 ,babel-preset-react。
babel转es6语法####
npm install --save-dev babel-preset-es2015
{
"presets": ["es2015"],
"plugins": []
}
babel转react语法####
npm install --save-dev babel-preset-react
{
"presets": ["react"],
"plugins": []
}
8. babel-loader:
在webpack中可以使用babel-loader加载器来编译所有的js代码,而无需手动引入babel-core。当然,你也可以把相关插件或者插件集写入.babelrc文件中,具体实现如下:
module: {
loaders: [
{
test: /\.js/,
loader: 'babel?presets[]=es2015,presets[]=react,plugins[]=transform-runtime'
}
]
}
9. babel-register:
babel-register 是放在 node 里使用的。它的作用是替代 node 的 require命令,与 node 自身的 require不同,它可以加载 es2015、jsx 等类型文件。有了它,我们就可以在require引入的文件中也可以写es6、jsx,用法如下
require('babel-register')({presets: ['es2015', 'react']})
require('./app')
10. babel-polyfill:
babel 虽然可以转换各种 ES2015 语法及 jsx,但浏览器未提供原生支持的许多功能还是需要 polyfill,比如 Promise。我们只要在代码中引入 babel-polyfill 就可以模拟出一个 ES2015 的环境,用法如下:
安装######
npm install babel-polyfill --save
引入######
import babel-polyfill
webpack中######
entry : {app : ['babel-polyfill','/app.js']}
11. babel-runtime:
与 babel-polyfill 一样,babel-runtime 的作用也是模拟 ES2015 环境。只不过,babel-polyfill 是针对全局环境的,引入它,我们的浏览器就好像具备了规范里定义的完整的特性 – 虽然原生并未实现。babel-runtime 更像是分散的 polyfill 模块,我们可以在自己的模块里单独引入,比如 require(‘babel-runtime/core-js/promise’),它们不会在全局环境添加未实现的方法,只是,这样手动引用每个 polyfill 会非常低效。我们借助 Runtime transform 插件来自动化处理这一切。至于要用 babel-polyfill 还是 babel-runtime,则需要根据具体需求。举个例子,如果一个库里引用了 babel-polyfill,别人的库也引用了 babel-polyfill,我们很可能会跑两个 babel-polyfill 实例,这里,使用 babel-runtime 会更合适。