babel从入门到入门

babel从入门到入门

来源 http://www.cnblogs.com/gg1234/p/7168750.htmljavascript

 

博客讲解内容以下:html

  一、babel是什么

  二、javascript制做规范

  三、babel转译器

  四、babel的使用

  五、常见的几种babel转译器和插件

  六、babel最多见配置选项

  七、babel的其余

  八、在webpack中使用babel

  九、总结

凡是看到这个标题点进来的同窗,相信对babel都有了必定的了解。babel使用起来很简单,简单到都没有必要写一篇文章去介绍,直接看看官方文档就能够。因此我也在怀疑到底该不应写这篇文章。想来想去仍是决定动手写写,缘由是很简单,本身在刚开始接触babel也出现过懵逼的状态,因此但愿这篇文档能给其余人以帮助。java

一、babel是什么

babel官网正中间一行黄色大字写着“babel is a javascript compiler”,翻译一下就是babel是一个javascript转译器。为何会有babel存在呢?缘由是javascript在不断的发展,可是浏览器的发展速度跟不上。以es6为例,es6中为javascript增长了箭头函数、块级做用域等新的语法和Symbol、Promise等新的数据类型,可是这些语法和数据类型并不可以立刻被如今的浏览器所有支持,为了能在现有的浏览器上使用js新的语法和新的数据类型,就须要使用一个转译器,将javascript中新增的特性转为现代浏览器能理解的形式。babel就是作这个方面的转化工做。node

二、javascript制做规范

在这里有必要简单讲一下javascript版本,我只是大致讲下,javascript是网景公司开发的一种脚本语言,1996年的时候以ECMAScript的名字正式成为一种标准。2007年的时候发布了版本es5,而后在随后近10年里js并无大的变化。因此如今的浏览器均可以很好的支持es5。这一局面直到2015年被打破。2015年6月,TC39(javascript标准的制定组织)公布了新版本的js语言——ES6。并且从ES6开始,TC39规定每一年都要发布一个js的新版本,新版本将包含年号,都是以ESxxxx的方式进行命名。因此2015年发布的ES6又叫ES2015,2016年发布的新的js版本就叫ES2016,2017年发布的新的js版本就叫ES2017……。react

由于版本都是向前兼容的,就是老版本js版本中规定的语法和api在新版本的js中一样也会合理的。因此咱们能够想到后面的规范确定是包含前面的规范的,也就是ES2016版本的js规范是包含ES2015(ES6)规范的,ES2017是包含ES2016的也包含ES2015的。针对不一样的规范,Babel也提供了对应的转换器。webpack

  • babel-preset-es2015 将es2015版本的js转译为es5。es6

  • babel-preset-es2016 将es2016版本的js转译为es5。web

  • babel-preset-es2017 将es2017版本的js转译为es5。算法

在转译过程当中遇到更高版本的js语法,babel是会直接忽略的。chrome

在这里在简单讲一下js新规范的制做过程。

js规范的制做分4个阶段。

  • Stage0 :任何还没有提交为正式提案的讨论,想法,改变或对已有规范的补充建议都被认为是一个稻草人草案(“strawman” proposal),但只有TC39成员能够提出此阶段的草案。

  • Stage1 :此阶段,稻草人草案升级为正式化的提案,并将逐步解决多部门关切的问题,如与其余提案的相互之间会有什么影响,这一草案具体该如何实施等问题。人们须要对这些问题提供具体的解决方案。stage1的提案一般还须要包括API描述,拥有说明性使用示例,并对语义和算法进行讨论,通常来讲草案在这一阶段会经历巨大的变化。

  • Stage2 :此阶段,草案就有了初始的规范。经过polyfill(打补丁。编写一些代码实现浏览器以前不支持的功能),开发者能够开始使用这一阶段的草案了,一些浏览器引擎也会逐步对这一阶段的规范的提供原生支持,此外经过使用构建工具(相似babel的工具)也能够编译源代码为现有引擎能够执行的代码,这些方法都使得这一阶段的草案能够开始被使用了。

  • State3 :此阶段的规范就属于候选推荐规范了,这一阶段以后变化就不会那么大了,要达到这一阶段须要知足如下条件:

    • 规范的编辑和指定的审阅者必须在最终规范上签字;

    • 用户也应该对该提议感兴趣;

    • 提案必须至少被一个浏览器原生支持;

    • 拥有高效的ployfill,或者被Babel支持;

  • Stage4 :此阶段的提案必须有两个独立的经过验收测试的实现,进入第4阶段的提案将包含在 ECMAScript 的下一个修订版中。

针对js规范的不一样阶段,babel也提供了对应的转译器

  • Stage0:preset-stage-0

  • Stage1:preset-stage-1

  • Stage2:preset-stage-2

  • Stage3:preset-stage-3

不一样阶段的转译器之间是包含的关系,preset-stage-0转译器除了包含了preset-stage-1的全部功能还增长了transform-do-expressions插件和transform-function-bind插件,一样preset-stage-1转译器除了包含preset-stage-2的所有功能外还增长了一些额外的功能……。

好了,javascript的制做规范大致讲完了,如今咱们来说下babel转译器。

三、babel转译器

为了便于说明,首先咱们来定义两个概念。

  1. 转译插件,转译插件是用来转译单一功能的插件,好比transform-es2015-arrow-functions,这个插件只负责转译es2015新增的箭头函数。

  2. 转译器,转译器是一系列转译插件的集合。好比babel-preset-es2015就包含了es2015新增语法的全部转译插件,好比包含transform-es2015-arrow-functions(es2015箭头函数转译插件)、transform-es2015-classes(es2015 class类转译插件)等。

js规范新增的每一个语法都有对应的babel插件,所以babel插件众多。为了便于管理,会把某些插件集合在一块儿,构成一个转译器。要否则若是咱们想转译es2015的语法就要安装一大堆插件了,有了转译器以后咱们只须要安装一个转译器就能够了。babel的转译器根据用途的不一样也分了不一样给的类,这些类很是多,因此babel看起来很混乱。不过大致上babel的转译器分为3类。

  1. 语法转译器,这些转译器只负责转译js最新的语法,并不负责转译js新增的api和全局对象。这类转译器包括babel-preset-env、babel-preset-es201五、babel-preset-es201六、babel-preset-es201七、babel-preset-latest等,之后确定还会有新的转译器加入,不过你只要理解转译器就是一堆转译插件的集合就能够了。

  2. 补丁转译器,这些转译器只负责转译js最新的api和全局对象。好比浏览器不支持String新增的String.padStart方法和Promise全局对象。经过babel-profill转译,咱们能够经过其余代码来让浏览器实现相似String.padStart和Promise的功能。

  3. jsx和flow插件,这类转译器用来转译JSX语法和移除类型声明的,使用Rect的时候你将用到它,转译器名称为babel-preset-react

另外你能够对babel已有的转译器进行改造或者建立新的转译器。如何建立babel转译器能够点这里

四、babel的使用

babel支持的使用场景很是多,能够在浏览器中使用(browser)也能够在命令行(cli),还能够是咱们常见的gulp和webpack中。

如下以安装babel-cli为例进行说明。babel更多的使用方法请点击这里

4.一、建立bebel项目

在本地磁盘上建立一个文件夹es6(名字任意),在该文件夹下打开命令行工具,初始化项目。

1
D:\webpack\demo\es6>npm init -y

这个命令目的就是建立一个默认的package.json文件。

4.二、本地安装babel命令行工具

安装babel的命令行工具的目的是为了在命令行使用babel。 

babel命令行工具能够全局安装也能够本地安装,官方文档推荐本地安装,缘由有2点;

  1. 本地安装不一样的项目可使用不一样版本的babel,你也能够单独对某个项目的babel进行升级等操做

  2. 每一个项目单独安装的意味着对计算机环境没有依赖,便于移植

在命令行中继续执行以下命令

1
npm  install  --save-dev babel-cli

若是你已经全局安装了babel,可使用以下的命令进行卸载

1
npm uninstall --global babel-cli

这样就已经在本地安装好babel了。

此时个人package.json文件以下(请忽略main字段)。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
   "name" "es6" ,
   "version" "1.0.0" ,
   "description" "" ,
   "main" "arrow.js" //请忽略main字段
   "scripts" : {
     "test" "echo \"Error: no test specified\" && exit 1"
   },
   "keywords" : [],
   "author" "" ,
   "license" "ISC" ,
   "devDependencies" : {
     "babel-cli" "^6.24.1"
   }
}

  

4.三、在命令行中调用babel

本地安装的babel是不可以在直接命令行中运行的,为了在命令行中运行babel,咱们有两个方法,1是须要配置下package.json文件的scripts项。好比以下代码,配置了一个build命令,运行该命令(npm run build)的时候就会在命令行执行babel src -d lib

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
{
   "name" "es6" ,
   "version" "1.0.0" ,
   "description" "" ,
   "main" "arrow.js" ,
   "scripts" : {
     "build" "babel src -d lib"
   },
   "keywords" : [],
   "author" "" ,
   "license" "ISC" ,
   "devDependencies" : {
     "babel-cli" "^6.24.1"
   }
}

  

第2个方法是你须要能够进入node_modules文件夹,再进入.bin文件夹,而后执行在命令行中执行babel src -d lib

推荐使用npm run build的方法。

这里须要解释babel src -d lib这个命令的意思。这个命令目的是把src文件夹下的文件都转译,转译后的文件放到lib目录下。

关于babel的命令行使用方法请点这里

ps:此时不管你是运行npm run build 仍是运行babel src -d lib命令(其实两个方法本质上都是同样的,都是运行babel src -d lib)命令行都会报错,缘由是如今尚未src文件夹。能够先不用管它,稍后咱们再新建src文件夹。

4.四、建立.babelrc配置文件

在cmd中键入如下命令。

1
D:\webpack\demo\es6> type  nul>.babelrc

这个时候你的文件夹里就多了一个.babelrc文件了。windows是不能直接建立空文件名的文件的,因此必须经过命令行建立。

4.五、安装babel的转译器

这里咱们以babel-preset-env为例。

在命令行中执行以下代码就会安装babel-preset-env转译器。

1
D:\webpack\demo\es6>npm  install  babel-preset- env  --save-dev

注意:babel命令行工具(babel-cli)跟babel转译器是两个不一样的东西,命令行工具并不具备转译代码的功能,只是为了在命令行中使用babel。要转码必须安装转译器,好比babel-preset-env转译器或者babel-preset-react转译器。要转译的时候,还要在.babelrc文件或者命令行中配置这些转译器(presets)选项

4.六、配置.babelrc文件

.babelrc用于配置除回调之外的全部babel api 选项。例如plugins和presets。plugins用于配置咱们转译所须要的插件,presets用于配置咱们所须要的转译器。

.babelrc不是必须的,咱们在.babelrc中配置的选项均可以经过命令行添加,好比在命令行执行 babel src -d lib --presets=env 等价于在.babelrc中配置 "presets":["env"]。固然.babelrc要明显方便不少。

babel在转译代码的过程当中会自动读取当前目录.babelrc配置文件,若是当前目录没有的话就遍历整个目录树去寻找,直到找到.babelrc文件或者含有"babel"字段的package.json文件,而后使用这些配置选项来转译代码。

关于.babelrc的注意点以下。

一、若是没有.babelrc文件,或者没有在其余文件中设置过babel的presets的配置选型,而且命令行中也没有配置--presets,那么代码是不会转译的。原es6代码什么样,转译后的代码仍是什么样。

二、若是你的.babelrc或者你的命令行使用了你没有安装的转译器(presets),代码就会报错

三、但.babelrc中的配置跟你在命令行中使用的配置冲突的时候,以.babelrc中的配置为准

1
2
3
{
     "presets" :[ "env" ]
}

  

关于.babelrc文件的更多使用方法请点击这里

4.七、.babelrc的替代方案

若是你不想生成.babelrc文件,你能够在你的package.json文件中对babel进行配置。若是你使用gulp或者webpack之类的管理工具的话,也能够在这里工具的配置选项里添加babel的配置选项。

如下以在package.json中配置为例。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
{
   "name" "es6" ,
   "version" "1.0.0" ,
   "description" "" ,
   "main" "arrow.js" ,
   "scripts" : {
     "build" "babel src -d lib --comments=true"
   },
   "babel" :{
     //babel选项
     "presets" :[ "es2015" ],
     "comments" : false
   },
   "keywords" : [],
   "author" "" ,
   "license" "ISC" ,
   "devDependencies" : {
     "babel-cli" "^6.24.1" ,
     "babel-loader" "^7.1.1" ,
     "babel-preset-env" "^1.6.0" ,
     "babel-preset-es2015" "^6.24.1" ,
     "babel-preset-react" "^6.24.1" ,
     "webpack" "^3.2.0"
   }
}​

  

在package.json中配置babel等同于使用.babelrc文件

4.八、编写es6代码

由于咱们使用的babel命令是babel src -d lib 因此咱们须要在目录中建立一个叫src的文件夹。目录结构以下:

|-node_modules
|-src
|-.babelrc
|-package.json

在src文件夹下咱们建立一个person.js文件(文件名任意),编写以下es6代码(代码任意,只有是es6代码便可,方便看出编译后的效果)。编辑好代码后保存。

1
2
3
4
5
6
7
8
9
10
class  Person{
     constructor(){
         this .name= "bigbigStrong"
     }
     sayName(){
         console.log(`my name is ${ this .name}`);
     }
}
var  p =  new  Person();
p.sayName();

4.九、转译es6代码

在命令行工具中执行npm run build 就能够发现目录中多了一个lib文件夹,lib文件夹下有一个person.js的文件,这个文件就是src下的person.js文件转译后的代码。

1
D:\webpack\demo\es6>npm run build

转译后的代码以下:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
"use strict" ;
var  _createClass =  function  () {  function  defineProperties(target, props) {  for  ( var  i = 0; i < props.length; i++) {  var  descriptor = props[i]; descriptor.enumerable = descriptor.enumerable ||  false ; descriptor.configurable =  true if  ( "value"  in  descriptor) descriptor.writable =  true ; Object.defineProperty(target, descriptor.key, descriptor); } }  return  function  (Constructor, protoProps, staticProps) {  if  (protoProps) defineProperties(Constructor.prototype, protoProps);  if  (staticProps) defineProperties(Constructor, staticProps);  return  Constructor; }; }();
function  _classCallCheck(instance, Constructor) {  if  (!(instance  instanceof  Constructor)) {  throw  new  TypeError( "Cannot call a class as a function" ); } }
var  Person =  function  () {
     function  Person() {
         _classCallCheck( this , Person);
         this .name =  "bigbigStrong" ;
     }
     _createClass(Person, [{
         key:  "sayName" ,
         value:  function  sayName() {
             console.log( "my name is "  this .name);
         }
     }]);
     return  Person;
}();
var  p =  new  Person();
p.sayName();

  

五、常见的几种babel转译器和插件

通过上面的步骤咱们已经完成了转译代码的工做,如今咱们介绍下babel中经常使用的转译器和配置选项

5.一、babel-preset-env

转译器,最经常使用的转译器。经过在.babelrc中配置env选项,可让代码兼容不一样版本的浏览器或者node。浏览器或者node已经支持的语法将再也不转译了,不支持的才转译。若是不配置env选项,该转译器等同于babel-preset-latest。更多详情和方法点这里

1
2
3
4
5
6
7
8
9
{
   "presets" : [
     [ "env" , {
       "targets" : {
         "browsers" : [ "last 2 versions" "safari >= 7" ]
       }
     }]
   ]
}

5.二、babel-preset-es2015

转译器,将es2015版本的js代码转译为es5代码,对于es2016版本的代码或者es2017版本的代码不转译。

5.三、babel-preset-latest

转译器,将最新版本的js代码转译为es5代码。不推荐使用,已经废除。建议使用babel-preset-env代替

5.四、babel-preset-react

转译器,剥离流类型并将JSX转换为createElement调用,主要在转译react代码的时候使用。

5.五、兼容ie浏览器的转译器

要兼容老版本的ie浏览器,可使用对应的es3和es5插件

5.六、总结

转译器就是一堆转译插件的集合。babel转译器不少,可是咱们经常使用的就那几个。若是要转译新版本的js的话,只须要使用babel-presets-env这一个转译器就能够了。

关于babel的更多转译器介绍,能够点击这里查看。你能够点击每个转译器进去查看转译器的适用场景是使用方法

六、babel最多见配置选项

babel的配置选项在命令行的使用规则是babel --name-value 好比咱们使用es2015转译器,咱们的命令就是

1
babel src -d lib --presets=es2015

babel的配置选项很是多,每一个转译器也都有本身的配置选项,关于babel的配置选项的详细功能和使用方法,请点击这里查看。我这里只介绍几个常见的。

6.一、babelrc

默认值为true,用于配置是否适用.babelrc和.babelignore文件,当命令行中添加--no-babelrc选项的时候,表示忽略.babelrc和.babelignore文件。在.babelrc文件中配置babelrc我的测试没有卵用。

6.二、env

默认值为一个空对象{}. env用于配置代码须要兼容的环境,好比你的代码要在chrome52上运行,能够这样配置.babelrc。

1
2
3
4
5
6
7
8
9
{
   "presets" : [
     [ "env" , {
       "targets" : {
         "chrome" : 52
       }
     }]
   ]
}

配置代码兼容最新的node,能够这样设置.babelrc

1
2
3
4
5
6
7
8
9
{
   "presets" : [
     [ "env" , {
       "targets" : {
         "node" "current"
       }
     }]
   ]
}

6.三、ignore

忽略某些文件,默认值为null,好比src文件夹下有person.js和foo.js两个文件,转译的时候你要忽略src文件夹下的foo.js,能够这样配置.babelrc。这样就再也不转译foo.js文件了

1
2
3
4
{
     "presets" :[ "env" ],
     "ignore" :[ "foo.js" ]
}

与ignore相对应的是only选项,only表示只转译某些文件。

6.四、minified

是否压缩转译后的代码,默认值为false

1
2
3
4
5
{
     "presets" :[ "env" ],
     "ignore" :[ "foo.js" ],
     "minified" : true
}

6.五、plugins

配置转译所须要的插件。使用插件的顺序是按照插件在数组中的顺序依次调用的。好比以下命令,转译的时候先使用transform-decorators-legacy转译,再使用transform-class-properties转译

1
2
3
4
5
6
{
   "plugins" : [
     "transform-decorators-legacy" ,
     "transform-class-properties"
   ]
}

6.六、presets

配置你要使用的转译器。使用转译器的顺序是按照转译器在数组中的反顺序进行调用的。先使用数组最末尾的转译器,而后使用倒数第2个,倒数第3个,依次类推。好比使用下面命令的时候,先使用stage-2转译器转译,再react转译器转译,最后使用es2015转译器转译。

1
2
3
4
5
6
7
{
   "presets" : [
     "es2015" ,
     "react" ,
     "stage-2"
   ]
}

6.七、补充:plugins和presets的顺序

详情点这里

  • 若是同时存在plugins和presets,则先使用plugins转译

  • plugin的调用顺序是从第一个到最后一个,

  • presets的调用的顺序是相反的,从最后一个到第一个

七、babel的其余

7.一、babel-node

bable-node是babel-cli自带的命令,提供了一个支持ES6的REPL环境,它支持node的REPL环境的全部功能,并且能够直接运行ES6代码。为了体验下这个功能,咱们须要全局安装babel-cli。而后在命令行执行下面的命令。

安装

1
npm install --save-dev -g babel-cli

执行命令就会输出咱们代码执行的结果

1
D:\webpack\demo\es6>babel-node -e   "var name='tom';console.log(`my name is ${name}`)" //my name is tom;

babel-node的详细用法点击这里

7.二、babel-register

引用自阮一峰babel讲解

babel-register模块会改写require命令,为它加上一个钩子。此后每当使用require加载.js.jsx.es.es6后缀名文件的时候,都会先用babel进行转码

安装

1
$ npm install --save-dev babel-register

使用的时候必须先加载babel-register。

1
2
require( "babel-register" );
require( "./index.js" );

而后,就不须要手动对index.js转码了。

须要注意的是,babel-register只会对require命令加载的文件转码,而不会对当前文件转码。另外,因为它是实时转码,因此只适合在开发环境使用。

babel-register的详细使用方法点击这里

7.三、babel-core

babel-core主要在node等环境中使用,能够用来开发本身的babel转译器。直接调用babel的api对某些代码或者某些文件进行转译。

安装

1
npm install babel-core --save

使用方法

1
2
3
var  babel =require( 'babel-core' );
babel.transform(code,options); //转译程序片断
babel.transform(filename,options,callback);  //转译文件

babel-core的详细使用方法点击这里

八、在webpack中使用babel。

8.一、安装webpack

1
D:\webpack\demo\es6>npm install --save-dev webpack

8.二、安装babel-preset-env和babel-loader。

若是你是跟着我这份教程一路看下来的,那么你babel-preset-env已经安装了。已经安装的话就不用再安装了。记得要安装babel-loader就好。

1
D:\webpack\demo\es6>npm install --save-dev babel-preset-env babel-loader

此时你的package.json以下。确保devDependencies中有babel-loader、babel-preset-env和webpack便可,其余的能够跟我不一样。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
{
   "name" "es6" ,
   "version" "1.0.0" ,
   "description" "" ,
   "main" "arrow.js" ,
   "scripts" : {
     "build" "babel src -d lib"
   },
   "keywords" : [],
   "author" "" ,
   "license" "ISC" ,
   "devDependencies" : {
     "babel-cli" "^6.24.1" ,
     "babel-loader" "^7.1.1" ,
     "babel-preset-env" "^1.6.0" ,
     "babel-preset-react" "^6.24.1" ,
     "webpack" "^3.2.0"
   }
}

  

8.三、建立webpack.config.js文件

在根目录下建立webpack.config.js文件,内容以下。

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
var  path = require( "path" );
module.exports = { 
     entry:  './src/person.js'
     output: { 
         path: path.resolve(__dirname, "lib" ), 
         filename:  'person.compiled.js'
     }, 
     module: { 
         loaders: [{ 
             test: /\.js$/, 
             exclude: /node_modules/, 
             loader:  'babel-loader' ,
             query:{
                 presets:[ "env" ]
            
         }] 
    

  

entry为入口文件,咱们选择当前目录下,src文件夹下的person.js文件做为入口。output为输出选项,path为输出的目录,filename为输出文件名。query选项为.babelrc中的配置选项。在webpack中设置了query字段后,就再也不须要.babelrc文件了。

此时咱们的目录结构是这样子的。

-lib
-node_modules
-src
    -person.js
 -foo.js -package.json -webpack.config.js

 

8.四、运行webpack。

在命令行中执行webpack,webpack会自动读取webpack.config.js文件中的配置。而后对咱们配置的文件进行转译。

1
D:\webpack\demo\es6>webpack

打开lib文件夹,咱们发现多了一个转译后的文件person.compiled.js。

-lib
    -person.compiled.js
-node_modules
-src
 -person.js  -foo.js -package.json -webpack.config.js

8.五、使用webpack转译多个文件

咱们src文件夹下除了有person.js文件外,还有一个foo.js文件。可是咱们上面的操做只转译了person.js文件,为了同时转译foo.js文件咱们须要在person.js文件中引入foo.js

foo.js文件代码以下:

1
2
let  name= "tom" ;
console.log(`my name is ${name}`);

咱们在person.js文件顶部中添加require("./foo");;这样就能够person.js文件中添加对foo.js的依赖。修改后的person.js代码以下:

1
2
3
4
5
6
7
8
9
10
11
require( "./foo" );
class  Person{
     constructor(){
         this .name= "bigbigStrong"
     }
     sayName(){
         console.log(`my name is ${ this .name}`);
     }
}
var  p =  new  Person();
p.sayName();

这样在编译后的文件person.compiled.js文件里,就包含了foo.js的代码。

关于webpack的更多使用方法,请点击查看webpack文档

九、总结

关于babel的知识点大概就这些。

  • babel经常使用的转译器是babel-preset-env。

  • 经常使用的配置选项是plugins和presets

  • 经常使用的使用场景是在webpack中

以上讲的都是经常使用的,关于babel更细的知识点还须要你本身查看babel官方文档

相关文章
相关标签/搜索