精华 在node中使用babel6的一些简单分享
发布于 9 年前 作者 XGHeaven 66403 次浏览 最后一次编辑是 8 年前 来自 分享

什么是Babel

相信很多新手没有听说过BabelES6,如果你是老手的话,那么请自动忽略~

ES6

ES6也就是ECMAScript 6,也就是最新的一代js规范,添加了很多语言的特性,包括模块管理,类,块级作用域等等内容。我最喜欢的就是箭头函数,优雅~

Babel

然而虽然ES6很棒,但是现在几乎没有浏览器或者Node(我记得5.0已经全部支持了es6,可是为啥我试着却不行。。。似乎要开启全部的harmony)能够完全支持es6的代码,那么问题来了,如果我想体验一下es6的代码,怎么办??

一个很简单的思路便是:

我写个程序,将es6代码转换成es5代码进行运行不就好了,很棒

Babel就是干的这个事情。

babel5 和 babel6 的区别

对于Babel来说,现在有了两个版本,一个是5,一个是6,那么两者有什么区别呢?

  • 5对新手更加友好,因为只需要安装一个babel就可以了,而6需要安装比较多的东西和插件才可以。
  • 相比5来说,6将命令行工具和API分开来了,最直观的感觉就是,当你想在代码中运行es6代码的话,需要安装babel-core,而如果你想在终端编译es6或者是运行es6版本的REPL的话,需要安装babel-cli
  • 也许有人问,原先的babel去哪了?是这样的,这个babel的package到了6版本之后虽然还是能安装,但是已经不具有任何的有效的代码了。取而代之的是一段提示文字,提示你需要安装babel-core或者babel-cli。所以你在babel6的情况下,完全不需要安装babel
  • 6将babel插件化,当你第一次安装babel-core并且按照以前的方式来加载require hook的话,你回发现代码无法运行:
    require('babel-core/register');	
    

就是因为babel6整体插件化了,如果你想使用es6语法,需要手动加载相关插件。

这里有一篇文章,建议看一下《The Six Things You Need To Know About Babel 6》


Quick Start

建立空文件夹 babel6

建立空文件夹babel6作为本次的目录,并npm init

安装Babel6

npm install babel-core --save

如果觉得慢,可以使用淘宝镜像cnpm。 此时,基础的babel6就安装完成了,如果你想安装babel5,那么执行如下的代码

npm install babel@5 --save

即可使用babel5,那么在后文的中,统一使用babel6 install-babel6.gif

require hook

安装好之后,问题来了,如何使用呢?

相信使用过coffee的人一定知道register,那么在babel中同样不例外,也可以使用同样的方法。

require('babel-core/register');

require('./app');

大家可能以为这样我就可以在app.js中优雅的使用es6了,在babel5中确实是这样的,但是在babel6中,缺不一样了。

如果你这样写完,并没有任何作用,因为你缺少一个插件。

安装插件

如果想使用es6语法,必须安装一个插件

npm install babel-preset-es2015

然后在文件夹下面创建一个叫.babelrc的文件,并写入如下代码:

{
	"presets": ["es2015"]
}

下面你就可以很优雅的书写你的es6代码了。 install-es2015.gif

书写优雅的ES6代码

下面我们写一段优雅的代码

let first = (size, ...args) => [...args].slice(0, size);

export default first;

console.log(first(2,1,2,3));

Run it

直接运行,不说话~~~ run-it.gif

内容解释

.babelrc

什么是.babelrc文件呢?熟悉linux的同学一定知道,rc结尾的文件通常代表运行时自动加载的文件,配置等等的,类似bashrc,zshrc。同样babelrc在这里也是有同样的作用的,而且在babel6中,这个文件必不可少。

  • 里面可以对babel命令进行配置,以后在使用babel的cli的时候,可以少写一些配置
  • 还有一个env字段,可以对BABEL_ENV或者NODE_ENV指定的不同的环境变量,进行不同的编译操作
“presets”

这个是babel6新加的,就是代表需要启动什么样的预设转码,在babel6中,预设了6种,分别是

  • es2015
  • stage-0
  • stage-1
  • stage-2
  • stage-3
  • react

至于如何安装,请查看balel官网

而且,对.babelrc的设置,你可以存放在package.json中的。如下:

{
	...
	"babel": {
		"presets": ["es2015"]
	},
	...
}

require hook

require hook 的作用就是替换原先的require,以便在加载自动对代码进行编译,运行。

其实这个做的便是重写require.extensions中对应的扩展名的加载程序,并且默认会判断这个文件是否是node_modules中的模块,如果是的话,那么将不会进行转换。否则的话,会进行转换。

CLI

其实babel也可以当做全局变量来使用的

npm install babel-cli -g

安装上后,会安装如下四个程序到全局环境中:

  • babel
  • babel-node
  • babel-doctor
  • babel-external-helpers
babel

这个就是编译js文件的全局变量,具体如何使用,大家请参照官网。使用方法和coffee,style,less了类似,就不多讲了

babel-node

这里主要说一下这个东西,就是这个的作用就是提供一个node命令相同的REPL环境,不过这个环境会在执行之前讲代码进行编译。

坑1:上文讲到,babel6默认是无法编译es6文件的,需要你手动安装es2015的preset,同样,全局模式下,也需要这个preset。

那么问题来了,我们怎么安装这个preset呢?global?所以这是一个坑,我在babel的issue中找到这样的一条。作者给出这样的回答:我们处理preset和plugin是依据于输入的文件,而你直接运行CLI是没有输入文件的,也就无法定位preset和plugin的位置。言下之意就是不要全局安装,虽然我们给你了你全局安装的方式。然后作者关闭了issue,表示很无奈。。。。

所以,如果大家想体验一下es6的REPL的话,建议安装babel5

npm install babel@5 -g
babel-doctor

就是检查babel状况的, 主要检查以下几个内容

  • 是否发现了.babelrc配置文件
  • 是否有重复的babel安装包,比如说安装了5和6
  • 所有的babel安装包是否已经升级到了最新版
  • 并且 npm >= 3.3.0
babel-external-helpers

就是讲一些公共的帮助函数提取成一个文件,其实就做了这一个作用。。。

总结

这是我的第一篇关于es6的教程,如果大家有什么不好的地方,请及时想我反馈。 Blog

更新

2015-11-15 添加了CLI一节

37 回复

loose 模式貌似还一直有问题

@welefen 你是说babel6的么?

来自炫酷的 CNodeMD 越来越喜欢material design😁

赞,学习了

赞,比较详细

请教下require hook 有什么潜在的坑吗? 比如开发的调试如何,线上用require hook部署好吗?

@whwnow 就是坑到是不多,但是调试确实是一个坑,现在只能用console来调试。关于线上的问题,我具体咨询过成银大哥,他说线上的最好还是要编译过之后。

没有收藏功能?

@rupertqin 什么东西?

我自己试的时候,代码跑起来了没报错,但服务没启动,暂时没找到原因 还得请教下,我看官方文档提到polyfill这是干嘛的,需要require(“babel-polyfill”) ? 调试不能直接加断点了吗?那就这一点,开发没法用了啊

@whwnow 先说第一个问题,就是polyfill是针对编译后的,如果你是直接require-hook的话,是不需要的。还有并没有觉得加断点调试有多方便

直接用typescript

@arden 可以的,但是我觉得ts写起来不爽,要是定义那么多的类型的话,为什么不直接用java呢。而且还增加了学习成本。

@XGHeaven 我刚开始也这么觉得,但用过之后感觉还是好处蛮多的。

@arden 比如说?

请问一下,babel编译的文件,怎么在node下断点调试呢?

@weivea 这个暂时没有办法。其实 node 这种比较容易上手的东西,用逻辑分析一下基本都可以解决问题的。最多配合上 debug, console.log 等等工具就差不多可以了

@XGHeaven 我已经实现啦,webstorm原来支持sourceMap的

@weivea sourcemap不是断点呀😂

node不是原始支持所有es6 features 开启所有harmony也不行 比如import export

来自酷炫的 CNodeMD

最新的node已经支持es6的写法了,后端使用babel是多此一举吧,虽然不支持import 个人觉得require挺好

@Kaijun 你需要开启 --harmony-modules,目测是这样的

@blackjack 如果是写小项目,完全可以不用babel。node5的特性足够了

@XGHeaven 看起来是这样的, 实际没有效果! 因为ES6 Module在V8里还没有具体实现方式, 所以…

@Kaijun 我也发现了,还是老老实实的用 require 或者babel吧

结合楼主的介绍和这个链接(http://www.ruanyifeng.com/blog/2016/01/babel.html)里的入门教程, 可以理解更透彻一些

@XGHeaven 恩,怎么说呢,就是可以在源码上边打断点呀,运行的是编译后的文件

@weivea 还可以这样,这么神奇

mark,用转码器实现没有什么禁忌么?

转换过的代码在浏览器运行出错了,出错能对得上es6源码的行数吗?

如果文件量大的话会导致项目启动很慢,以为要在启动之前babel去编译所有js后在运行,这样导致项目启动很慢很慢,不知道针对这个问题,你是如何解决的,我目前是再外面编译完在运行。

回到顶部