我个人正在写Node.js的系列学习笔记node-learning-manual,包含了Node.js的基本模块和工程化相关的知识, 如果对你有帮助,请点个start,您的支持是对我最大的鼓励。
前言
前端发展到现在,可谓是混乱至极,已经远远超出我对前端所谓一把jQuery抄起来就是怼,
Webpack, babel, node.js, react, vue各种工程框架,构建工具你不会点好像都不算是个合格的
前端工程师,语法相关的ES6/7总是绕不过Babel,这篇文章就是直接讨论Babel。
本文只要围绕以下几块来说:
- Babel编译过程介绍
- Babel插件及预设
- Babel-register在项目中的使用
- babel的polyfill引入机制
- babel在前端工程的定位
Babel编译过程介绍
-
核心包
// 暴露babel.transform方法来编译source code babel-core // 语法字符串解析parser babylon // 结合plugins遍历AST语法树 babel-traverse // 生成最后的编译字符串 babel-generator
-
babel编译流程
input string -> babylon parser -> AST -> babel-traverse //使用plugins遍历AST语法树 -> AST -> babel-generator -> output string
Babel是一个JavaScrpit的编译器,从宏观的角度来看,它有三个运行阶段:解析,转化,生成。基本上如果不设置配置文件.babelrc,Babel运行的结果便是 const babel = code => code ,通过读取代码,最后生成一样的代码。Babel的最核心的概念便是插件,通过在配置文件 .babelrc中添加不同的插件基本可以做所有的事情。
Babel插件(plugins)及预设(presets)
首先聊聊插件与预设的关系,官方预设便是由官方评审维护的一系列插件组合。插件与预设的关系便是父子集合的关系。
每年babel都会评估当年的插件,babel-preset-env 取代了 es2015, es2016, es2017 以及最新的代码
Babel-register在项目中的使用
babel-register的设计思想非常厉害,简单的来说就是require hook。也是babel常见的一种使用方法。
这种方法只需要引入文件就可以运行 Babel,或许能更好地融入你的项目设置。
让我们先在项目中创建index.js文件
// index.js
console.log("hello world");
接着需要我们安装babel-register
$ npm install i -D babel-register
接着,在项目中创建 register.js
文件并添加如下代码:
require("babel-register");
require("./index.js");
然后我们只需要启动 node register.js 便可,通过修改require function,对所有的通过require引入的代码先经过babel编译一遍,再给到runtime执行。
babel的polyfill引入机制
Babel 几乎可以编译所有时新的 JavaScript 语法,但对于 APIs 来说却并非如此。
比方说,下列含有箭头函数的需要编译的代码:
function addAll() {
return Array.from(arguments).reduce((a, b) => a + b);
}
最终会变成这样
function addAll() {
return Array.from(arguments).reduce(function(a, b) {
return a + b;
});
}
然而,它依然无法随处可用因为不是所有的 JavaScript 环境都支持 Array.from
。
为了解决这个问题,我们使用一种叫做 Polyfill(代码填充,也可译作兼容性补丁) 的技术。 简单地说,polyfill 即是在当前运行环境中用来复制(意指模拟性的复制,而不是拷贝)尚不存在的原生 api 的代码。 能让你提前使用还不可用的 APIs,Array.from
就是一个例子。
要使用 Babel polyfill,首先用 npm 安装它:
$ npm install --save babel-polyfill
然后只需要在文件顶部导入 polyfill 就可以了:
import "babel-polyfill";
所以我的个人建议是按需引入core-js的模块而不是整个babel-polyfill bundle,来对ES6/7新增的数据对象和方法做polyfill。
babel-runtime引入机制
为了实现 ECMAScript 规范的细节,Babel 会使用“助手”方法来保持生成代码的整洁。
由于这些助手方法可能会特别长并且会被添加到每一个文件的顶部,因此你可以把它们统一移动到一个单一的“运行时(runtime)”中去。
通过安装 babel-plugin-transform-runtime
和 babel-runtime
来开始。
$ npm install --save-dev babel-plugin-transform-runtime
$ npm install --save babel-runtime
然后更新 .babelrc
:
{
"plugins": [
+ "transform-runtime",
"transform-es2015-classes"
]
}
现在,Babel 会把这样的代码:
class Foo {
method() {}
}
编译成:
import _classCallCheck from "babel-runtime/helpers/classCallCheck";
import _createClass from "babel-runtime/helpers/createClass";
let Foo = function () {
function Foo() {
_classCallCheck(this, Foo);
}
_createClass(Foo, [{
key: "method",
value: function method() {}
}]);
return Foo;
}();
这样就不需要把 _classCallCheck
和 _createClass
这两个助手方法放进每一个需要的文件里去了。
babel总结
babel的出现让开发者可以自由的采用ES6/7的语法来编写JS项目,极大的丰富了开发 (browser, node) 层面的JS语言特性。
babel的AST parser、polyfill、 register一起完成了babel体系对JS的完备解决方案。
参考资料
我个人正在写Node.js的系列学习笔记node-learning-manual,包含了Node.js的基本模块和工程化相关的知识, 如果对你有帮助,请点个start,您的支持是对我最大的鼓励。