Babel快速入门

首先,作为入门的话,Babel的用户手册是个很不错的选择,里面基本覆盖了Babel使用的各方面。所以下面主要是我学习Babel的一些笔记,姑且当作是一篇入门吧。

Babel是什么

按照Babel官网的说法,Babel是一个Javascript编译器。它可以把用最新标准编写的Javascript代码编译成现在的浏览器或者node环境下能运行的代码,这个过程叫做“源码到源码”编译,又称转译(transpiling)。通过这个方式,我们就可以提前使用下一代的标准和特性进行编码,然后在现在的环境下运行。

安装Babel

通常我们使用Babel的babel-cli工具在命令行下进行文件的编译。我们可以对babel-cli进行全局安装,也可以把它安装到项目里。这里我选择了把它安装到项目里。这样做的好处是:

  1. 不同的项目可能会使用不同版本的Babel,使用全局的话只能使用一致的版本

  2. 方便项目的部署,使用全局安装的话意味着对环境有个隐式的依赖。

除了babel-cli,还有其他使用Babel的方式,具体可以看用户手册。

下面我们开始安装babel-cli。首先新建一个工作目录,并创建package.json文件:

$ npm init -y
安装babel-cli:

$ npm install --save-dev babel-cli
安装完我们可以这样运行:

$ ./node_modules/babel-cli/bin/babel.js -V6.11.4 (babel-core 6.11.4)

但是这样运行很不方便,我们可以通过npm scripts来运行Babel。在package.json文件里,我们增加scripts字段,并添加一个脚本:

{
"scripts": {
"build": "babel src -d lib"
},
"devDependencies": {
"babel-cli": "^6.11.4"
}
}
这里增加了一条名字为build的脚本,命令的内容是把src里的文件通过Babel转译到lib目录里。然后我们可以通过以下命令运行脚本:

$ npm run build
当然,现在运行这个命令会报错,因为我们并没有src文件夹。下面我们正式进入正题。

Babel的基础使用

转译初探

首先我们创建src目录,然后创建一个js文件index.js:

[1,2,3].map(n => n + 1);
然后运行npm run build命令,就会看到lib文件夹里多了一个转译后的文件index.js。但是打开来看会发现这个转译后的文件跟源文件并没有区别。因为Babel需要你通过插件(Plugin)或者预设(presets)告诉它做什么。例如我们可以通过babel-preset-es2015告诉Babel把ES2015的文件转译成ES5。这也是Babel最常用的一个用法之一。

配置文件

要使用插件或者预设(相当于一组插件),我们需要在Bable的配置文件里面进行配置。有两个方式进行配置。

第一个方式是通过.babelrc文件:

{
"presets": [],
"plugins": []
}
第二个方式是使用package.json文件:

{
"name": "my-package",
"version": "1.0.0",
"babel": {
"presets": [],
"plugins": []
}
}

使用预设

上面说过,预设就是一组插件的集合,例如预设babel-preset-es2015就是把一堆跟ES2015有关的插件组合起来提供编译ES2015代码为ES5代码的功能。下面我们开始使用babel-preset-es2015预设来把ES2015转译成ES5。

首先我们安装这个预设:

$ npm install --save-dev babel-preset-es2015
然后在配置文件里添加这个预设:

{
"presets": [
"es2015"
],
"plugins": []
}
最后我们再次运行一次npm run build命令,再次打开lib/index.js文件,我们会看到代码已经被编译成ES5的语法:

"use strict";

[1, 2, 3].map(function (n) {
return n + 1;
});

Babel的执行

Polyfill

像上面那段转译后的代码我们可以直接使用在当前的环境下,但是并不是所有转译后的文件我们都只能直接使用,因为虽然Babel可以编译目前几乎所有的ES2015语法,但是一些新的API可能在当前的Javascript环境下无法支持。例如下面的代码(假设文件为lib/index.js):

function addAll() {
return Array.from(arguments).reduce((a, b) => a + b);
}
转译后会变成:

function addAll() {
return Array.from(arguments).reduce(function(a, b) {
return a + b;
});
}
可以看到语法上已经转译成ES5了,但是并不是所有的Javascript环境都支持Array.from,例如我们在IE上运行如下页面:

        console.log(addAll(1, 2, 3, 4, 5));

可能会报以下的错误:

对象不支持“from”属性或方法
Babel的解决方法就是使用Polyfill技术(使用了core-js和regenerator),通过在当前的运行环境模拟不存在的API来达到使用新API的目的。

首先我们安装babel-polyfill:

$ npm install --save babel-polyfill
注意这里使用的是--save而不是--save-dev,因为我们需要在代码里引入babel-polyfill。我们需要在文件顶部导入它:

import "babel-polyfill";
在添加这句代码后,上面的代码在转译后会变成下面这个样子:

"use strict";

require("babel-polyfill");

function addAll() {
return Array.from(arguments).reduce(function (a, b) {
return a + b;
});
}
因为Babel编译时默认使用的是CommonJS的模块规范,所以会看到转译后的代码使用了require方法来加载babel-polyfill。这个在node环境下运行没有问题,但是在浏览器环境下运行就会报错,因为浏览器目前还不原生的支持模块的加载。那在浏览器下怎么使用babel-polyfill呢?

我们可以把babel-polyfill通过外部js的方式加载进来,而不是在js代码里进行引入:

但是如果你打算在项目里使用模块,上面明显不是很好的解决方案。下面我们看看如果解决在浏览器环境下模块的加载问题。

使用模块

要在浏览器环境下加载依赖模块,有很多方式,例如使用webpack或者browserify之类的打包工具(建议的方式,但是这里我们先不涉及)。或者我们可以使用浏览器端的模块加载器进行加载,例如我们使用AMD模块规范进行编译,然后用RequireJS进行加载。下面我使用SystemJS来做例子。

首先我们安装es2015-modules-systemjs插件:

$ npm install babel-plugin-transform-es2015-modules-systemjs
然后修改配置文件,在plugins里添加插件:

{
"plugins": ["transform-es2015-modules-systemjs"]
}
我们修改下lib/index.js,把addAll方法导出为模块的方法:

import "babel-polyfill";

export function addAll() {
return Array.from(arguments).reduce((a, b) => a + b);
}
再次对文件进行编译,编译后的lib/index.js变成这样:

"use strict";

System.register(["babel-polyfill"], function (_export, _context) {
"use strict";

return {
setters: [function (_babelPolyfill) {}],
execute: function () {
function addAll() {
return Array.from(arguments).reduce(function (a, b) {
return a + b;
});
}

  _export("addAll", addAll);}

};
});
然后我们需要在HTML里引入system.js。由于SystemJS依赖于Promise,它会加载目录下system-polyfills.js文件,所以我们需要确保这个文件的存在。在加载system.js后,我们就可以使用SystemJS进行模块的加载了:

        System.config({            baseURL: './lib',            map: {                'babel-polyfill': './node_modules/babel-polyfill/dist/polyfill.min.js'            }        });        System.import('index.js').then(function(m) {            console.log(m.addAll(1, 2, 3, 4, 5)); // 15        });

出于性能的考虑,也可以用像Bluebird和es6-promise这样的polyfill做替代,在system.js之前加载。

后记

自此,我们学习到了Babel的一些基础用法,包括安装和运行,以及配置和预设的用法,同时也初探了一些编译后的文件的运行问题。但是要用好Babel,还有很多问题需要继续探讨,期待我的下一篇笔记。

参考

https://babeljs.io/
https://github.com/thejamesky...
https://github.com/systemjs/s...

关键字:babel, JavaScript

版权声明

本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处。如若内容有涉嫌抄袭侵权/违法违规/事实不符,请点击 举报 进行投诉反馈!

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部