前端技术发展飞快,最近在学习ES6,希望能在项目中渐渐熟悉ES6的新特性,奈何公司的项目中用不到ES6,而且也不是目前流行的AMD、CMD或者UMD的模块,而是完全一套自己的机制,其中的模块更类似与一个类,为了能让ES6应用于公司项目中,便只好自己写一个转换的插件,使得ES6能够顺利的转换成公司的模块。
但是Babel.js关于插件的文档非常的不齐全,Github上也少有案例可以参考,这里写下自己编写Babel插件的心得。
首先我们需要对Babel.js有一定的了解,并且会使用它来 进行ES6到ES5的转换 。
你可以通过Babel.js的官方网站(传送门: http://babeljs.io/ )了解Babel,它是一个非常实用的 ES6to5转换器 。
这里 是一个在线的转换器,你可以看到其转换代码的效果,这里只包含语法方面的,模块方面的转换需要指定特定的模块化形式,在本机你需要执行如下步骤:
$ npm install -g babel
import $ from 'jquery' export class MyClass { constructor(name = 'nobody') { this.name = name; } getMyName() { return this.name; } }
然后使用使用如下命令对其进行转换
$ babel example.es6 -o example.js -m amd
上面的ES6代码就变成使用AMD模块化的es5代码啦。
define(['exports', 'jquery'], function (exports, _jquery) { 'use strict'; Object.defineProperty(exports, '__esModule', { value: true }); var _createClass = (function () { ... })(); function _interopRequireDefault(obj) { ... } function _classCallCheck(instance, Constructor) { ... } var _$ = _interopRequireDefault(_jquery); var MyClass = (function () { function MyClass() { var name = arguments[0] === undefined ? 'nobody' : arguments[0]; _classCallCheck(this, MyClass); this.name = name; } _createClass(MyClass, [{ key: 'getMyName', value: function getMyName() { return this.name; } }]); return MyClass; })(); exports.MyClass = MyClass; });
当然,你也可以将其转换成UMD的:
$ babel example.es6 -o example.js -m umd
有木有很方便,麻麻再也不用担心我的ES6用不上了。
接下来主要是针对一种情景:假设公司的或者自己的系统用了其他的模块化实现方式,如何通过编写插件,将ES6代码翻译成自己项目可以用到的ES5模块呢?
在介绍如何编写插件之前,首先需要了解几个概念。
编写Babel插件之前,有几个概念我们首先需要了解一下
AST (Abstract Syntax Trees)
百度百科中的解释为:
在计算机科学中, 抽象语法树 (abstract syntax tree或者缩写为AST),或者语法树(syntax tree),是源代码的抽象语法结构的树状表现形式,这里特指编程语言的源代码。树上的每个节点都表示源代码中的一种结构。之所以说语法是“抽象”的,是因为这里的语法并不会表示出真实语法中出现的每个细节。比如,嵌套括号被隐含在树的结构中,并没有以节点的形式呈现;而类似于if-condition-then这样的条件跳转语句,可以使用带有两个分支的节点来表示。
简单来说就是将一段代码抽象成一个有特定节点类型的树,以便可以用过变换树,来实现代码的转换。为了更方便理解JS的AST,推荐一个AST的可视化工具给大家:
JavaScript AST: http://jointjs.com/demos/javascript-ast
ES6和ES5中的AST表达式
以下是Babel.js提供的ES5和ES6的AST节点类型的文档,可以通过这两篇文档先来了解一下我们具体可以在Babel的插件编写中,对哪些AST节点进行操作,并且其传入的参数是怎样的,这对Babel的插件开发是非常重要的。
ES5: https://github.com/estree/estree/blob/master/spec.md
ES6: https://github.com/estree/estree/blob/master/es6.md