一,为了更明白地使用Babel, 先了解Babel 的发展过程. 现在Babel的版本是6, 相对于以前的版本, 它做了重大更新:

  1, 模块化所有的内部组件都变成了单独的包。打开Babel在GitHub上的地址,  我们看到了Packages(包), 它分为了Core Packages (babel-core) 和 Other 如 (babel-cli, babel-polyfill), 这些都是一个一个单独的包.

  看一下 核心包 babel-core: Babel-core is the Babel compiler itself; it exposes the babel.transform method, where transformedCode = transform(src).code.  babel-core 就是Babel 编译器它自身, 提供了一个方法 babel.transform.

  再看一下包 babel-cli:  Babel-cli is the CLI tool that runs babel-core and helps with outputting to a directory, a file, stdout and more.  Babel-cli 是命令行工具, 它运行 babel-core, 输出目录、文件等,可以看到它依赖 babel- core.

  总结: 每一个内部组件都变成了独立的包,每个包又都定义了一些轻量级的公共API, 可以供其他包使用。 

  2, 插件化: 这就是GitHub页面中提到的 Presets and  Plugins.

 Plugins are the heart of Babel and what make it work.  插件是Babel 的核心, 是插件让Babel 正常工作, 主要是Transform Plugins(转换器插件), 就是它把ES6+ 转换成ES5.  Presets are just simply an array of plugins. 预设仅仅是插件的集合。

二, 写一些简单的代码,加深理解.

  1,  新建一个babel 文件夹, 然后在该文件夹下面 npm init 创建一个package.json 文件, npm init –y 可以快速创建一个package.json 文件。

  2, 创建两个文件夹, src(用于存放编译前的文件), lib(用于放编译后的文件)。在src 目录下新建一个index.js 文件用于编写代码, 这里写一个箭头函数如下:

let sum = (num1, num2) => num1 + num2;
console.log(sum(3, 5))

  3, 这里只想用命令行工具对代码进行编译. 根据上面提到的模块化思想,如果我们只想使用某些内部组件执行某种构建任务,只需要单独的去安装相应的包就可以了. 这里,我们只想用一下babel-cli 命令行工具, 那么我们只需要安装这个包,npm install --save-dev babel-cli, 安装之后,这里用到一个命令,”babel src –d lib”

  4,为了使用这个命令, 我们需要把这个命令放到 npm scripts 中. 打开package.json 文件找到 scripts , 添加 “build”: “babel src –d lib” 以后在 命令行中输入npm run build, 就可以执行编译。

  5, 在命令行中输入npm run dev, 我们看到 lib文件夹多了index.js, 但却是原样输出,并没有转换成es5的语法。 这里就用到了它的插件化思想。

  The transformer[s] used in Babel are the independent pieces of code that transform specific things. 每个转换器插件也都是彻底独立出来。

  After Babel 6, the default transforms were removed; if you don't specify any plugins/presets it will just return the original source code. Babel 6以后, 默认的插件被移除, 如果没有指定一个插件,Babel将后原样输出, 不会进行编译。

  也就是说,即时我们安装了Babel, 它也没有用来转换ES5代码的功能, 还需要安装相应的插件。这里,我们用到了箭头函数,所以安装箭头函数插件:npm install --save-dev babel-plugin-transform-es2015-arrow-functions, 为了方便对插件进行管理,Babel 提供了它自己的配置文件 .babelrc, 这时我们在根目录下建立 .babelrc 文件,写入 {"plugins": ["transform-es2015-arrow-functions"]  }这时再运行 npm run build, 可以看到,编译成功了。

  6, 但是我们看到 let 并没有变化,主要是因为一个插件只做一件事情。如果我们的代码中,大批量的使用es6的特性,那么我们就要列出很多个插件,这非常不方便,所以Babel 提供了插件预设,上面也说了, 预设就是一些插件的集合,这样我们安装预设之后,就是安装了一堆插件,再也不会一个一个安装插件。  npm install --save-dev babel-preset-es2015,通过名字可以看出,这是es2015预设,只要是es2015转换成es5 用到的插件,它都会用装上,这是要在 .babelrc 文件下写 {"presets": ["es2015"]  }

presets 不要忘记s. 这时,彻底转化成es5.

三, 预设Preset

  看到官方预设preset, 有两种,一个是按年份(babel-preset-2017),一个是按阶段(babel-preset-stage-0)。 这主要是根据tc39 委员会ECMASCRPIT 发布流程来制定的。

  1, 按年份:TC39 委员会决定,从2016年开始,每年都会发布一个版本,它包括每年期限内完成的所有功能,同时ECMAScript的版本号也按年份编制,就有了ES2016, ES2017.  所有也就有了babel-present-2016, babel-preset-2017, 对每一年新增的语法进行转化。babel-preset-latest 就是把所有es2015, es2016, es2017 全部包含在一起了。

  2, 按阶段: 对于ECMAScript 的功能,每一个提案都会经过5个阶段:

  • stage-0 - Strawman: just an idea, possible Babel plugin. (稻草人阶段, 就是一个想法)
  • stage-1 - Proposal: this is worth working on.   (建议阶段,值得去努力)
  • stage-2 - Draft: initial spec. ( 草案阶段, 初始的细节描述)
  • stage-3 - Candidate: complete spec and initial browser implementations. (候选阶段,草案基本完成,浏览器厂商实验性的实现)
  • stage-4 - Finished: will be added to the next yearly release. (完成阶段,添加到下一年的版本中)

  Babel 对应不同的阶段, 提供了不同的预设,babel-preset-stage-0, babel-preset-stage-1, babel-preset-stage-2, babel-preset-stage-3. 这里没有stage-4, 是因为它将添加到下一年的版本中,也就是到了按年份进行预设。所以我们还可以得出其他的几个结论:

    1, 按年份进行的预设,其实是tc39委员会已经批准的,浏览器将要实现的功能,这也对应了官网上的 Each yearly preset only compiles what was ratified in that year(年份预设只编译那一年批准的功能).

    2, stage-X 的预设,实现是没有被批准的功能。Any transforms in stage-x presets are changes to the language that haven’t been approved to be part of a release of Javascript (such as ES6/ES2015).  “Changes to the language are developed by way of a process which provides guidelines for evolving an addition from an idea to a fully specified feature”

     3, stage-0 阶段的预设包含的插件大于stage-1阶段包含的插件,  stage-1 > stage-2,   stage-2 > stage-3,  所以我们安装stage-X预设时,只选装一个就可以了。
     4, 如果没有提供es2015 相关的预设,preset-stage-X 这种阶段性的预设也不能用。

四: 总结

  明白了Babel,使用起来就比较简单了。

  1, 先安装Babel, 就是安装babel-core 这个核心包。如果用 webpack, 我们会看到npm install babel-loader babel-core --save--dev;如果用gulp, 安装gulp-babel插件,其实都是安装的babel-core 这个核心。

  2,选择编译的插件或预设,如果只是在编译几个功能,可以选择插件,如果是大批量的安装插件,那就不如安装预设, npm install babel-preset-2015 --save-dev

  3, 安装好的插件或预设, 就需要在.babelrc 配置文件中进行配置,如果安装插件,就在 plugins 列出,如是安装预设,就在 presets 列出。也可以同时安装插件与预设,预设也可以同时安装多个,安装state-X之前,必须先安装es2015 等。

五:其实Babel 只是转换了ES6+的语法到ES5, 新增的对象如Promise 和 API 如Array.find() 方法,它并没有转换。我们写一个Array.find()应用,npm run build, 我们发现它是原样输出。那么这时候就需要用到了babel-polyfill了。

  简单了解了一个polyfill, 它就是 Replicate(复写) an API using JavaScript (or Flash or whatever) if the browser doesn’t have it natively”。如果浏览器不能原生的支持,我们就把这个API 用JS 重新写出来,那么旧的浏览器就可以使用这个API了。

百度了一下有一个形象的解释:polyfill来自于一个家装产品Polyfilla: Polyfilla是一个英国产品,在美国称之为Spackling Paste(译者注:刮墙的,在中国称为腻子).记住这一点就行:把旧的浏览器想象成为一面有了裂缝的墙.这些[polyfills]会帮助我们把这面墙的裂缝抹平,还我们一个更好的光滑的墙壁(浏览器)。下面的例子是firefox MDN上的,用一个array.find() 方法。

function isBigEnough(element) {
  return element >= 15;
}

var ok = [12, 5, 8, 130, 44].find(isBigEnough);

console.log(ok);

在chrome 控制台下,可以看到输出130, 但在IE10 下报错了,也就是说IE10不支持这个API, 那么需要用js重新写一个这个api, 下面的代码可以清楚地看到我们用现有的方法把这个API实现了,那么下面这段代码就是一个polyfill.

if (!Array.prototype.find) {
  Object.defineProperty(Array.prototype, 'find', {
    value: function(predicate) {
     // 1. Let O be ? ToObject(this value).
      if (this == null) {
        throw new TypeError('"this" is null or not defined');
      }

      var o = Object(this);

      // 2. Let len be ? ToLength(? Get(O, "length")).
      var len = o.length >>> 0;

      // 3. If IsCallable(predicate) is false, throw a TypeError exception.
      if (typeof predicate !== 'function') {
        throw new TypeError('predicate must be a function');
      }

      // 4. If thisArg was supplied, let T be thisArg; else let T be undefined.
      var thisArg = arguments[1];

      // 5. Let k be 0.
      var k = 0;

      // 6. Repeat, while k < len
      while (k < len) {
        // a. Let Pk be ! ToString(k).
        // b. Let kValue be ? Get(O, Pk).
        // c. Let testResult be ToBoolean(? Call(predicate, T, « kValue, k, O »)).
        // d. If testResult is true, return kValue.
        var kValue = o[k];
        if (predicate.call(thisArg, kValue, k, o)) {
          return kValue;
        }
        // e. Increase k by 1.
        k++;
      }

      // 7. Return undefined.
      return undefined;
    }
  });
}

把这段代码放到我们的程序中,可以看到IE10输出130.

  babel-polyfill 就是把所有的上面这种polyfill 放到一起了。我们可以在浏览器中直接使用。npm install babel-polyfill --save--dev, 安装完成后,node_modules/babel-polyfill/dist 下面有polyfill.min.js, 我们直接拿出这个文件,用script标签引进到我们的

html 文件中,就可以了。

<script src="../node_modules/babel-polyfill/dist/polyfill.min.js"></script>
<script src="../lib/index.js"></script>

至此,Babel的基本使用就介绍完了。

  

Babel 学习的更多相关文章

  1. Babel学习小记

    一.babel配置文件中的plugins和presets是什么? 1.首先说说babel是什么,babel是一个JavaScript转码器,帮助我们把浏览器不兼容的ES6语法转换成ES5语法: 2.接 ...

  2. 珠峰 - 郭永峰react课程 node es6 babel学习笔记

    npm install babel-cli -g //安装babel babel index.js -o a.js //等同于 babel index.js --out-file a.js 复制ind ...

  3. 关于babel官网的学习

    提起babel,前端er大概都不陌生.但是为什么要有babel呢?解决了什么问题?怎么使用babel呢?注意点在哪?以下就从这几个方面总结一下我关于babel学习的结果吧. 为什么要有babel呢? ...

  4. 你好,babel

    写在前面 其实学babel是本人2019年Q3的一个计划,因为当时自己做的一个项目需要自己去配babel,也遇到了一些困难,发现自己对babel的了解还是很少的,所以决定好好看下babel:可是后来解 ...

  5. chrome devtools tip(2)--自定义代码片段,构建你的工具箱

    平常开发中,有些代码片段常常用到的,比如,获取 url 参数,rgb转16进制,打印下当前页面的性能数据,给所有的 span 加个样式, 防抖节流,fetch接口,类似 jquery这样的顺手 选择 ...

  6. 学习 React(jsx语法) + es2015 + babel + webpack

    视频学习地址: http://www.jtthink.com/course/play/575 官方地址 https://facebook.github.io/react/ 神坑: 1.每次this.s ...

  7. ES6学习(1)——如何通过babel将ES6转化成ES5

    使用babel编译ES6 babel是一个工具,可以通过多个平台,让js文件从ES6转化成ES5,从而支持一些浏览器并未支持的语法. Insall babel $ sudo npm install b ...

  8. ES6学习之Babel的正确安装姿势

    开始学习ES6,写点东西放上博客^_^ 本文介绍Babel6.x的安装过程~ 首先呢,可以使用Babel在线转换 https://babeljs.io/repl/ 然后进入主题:安装Babel(命令行 ...

  9. Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)

    五  Vue学习-vue-cli脚手架学习(创建只选一个选项:Babel) 1. 项目目录说明 node_modules : 包管理文件夹 public : 静态资源 src : 源代码 gitign ...

随机推荐

  1. sdk命令

    SDK命令 常用sdk命令 开启adb服务:adb start -server 关闭adb服务:adb kill -server 查看模拟器/真机:adb devices 安装/卸载/运行程序: 安装 ...

  2. c++的引用

    /*#include"iostream"using namespace std;void any_function(int & p);//声明函数any_function/ ...

  3. Mysql数据库的使用总结之ERROR 1146 (42S02)

    在使用mysql数据库过程中,遇到了错误ERROR 1146 (42S02):Table doesn't exist,经过了两天,终于解决了这个问题.引起该错误的原因不同,对应的解决方法也不同.这里只 ...

  4. Java多线程学习(二)

    一.定义产生返回值的任务 在上一篇文的介绍中,我们知道了定义任务通常的方法是定义一个实现Runnable接口的类,这个类被我们成为任务.然而也很容易注意到,任务的最重要的一个方法就是run( )方法, ...

  5. linux下使用远程图形界面

    1. 用xrdp的方式(客户端就是windows下的远程桌面程序) http://jingyan.baidu.com/article/d3b74d64bdab5d1f76e60951.html 2. ...

  6. struts2漏洞与修复

    步骤: 1.下载struts-2.3.16.3-all, D:\TEST\struts2.3.16.3 2.替换jar,参考 http://blog.csdn.net/spyjava/article/ ...

  7. VIM配置与管理

    VIM是写代码的神器,个人觉得比sublime更强,详情http://zh.wikipedia.org/wiki/Vim.如果用网游做类比,没有经过打造的VIM,也只能算是一只非常有潜力的0级宠物,经 ...

  8. linux 中更改用户权限和用户组的命令chmod,chgrp实例

    linux 中更改用户权限和用户组的命令实例; 增加权限给当前用户 chmod +wx filename chmod -R 777 /upload 用户组 chgrp -R foldname zdz ...

  9. 自己写的java excel导出工具类

    最近项目要用到excel导出功能,之前也写过类似的代码.因为这次项目中多次用到excel导出.这次长了记性整理了一下 分享给大伙 欢迎一起讨论 生成excel的主工具类: public class E ...

  10. Sql数据库时间的转换格式

    Select CONVERT(varchar(100), GETDATE(), 0): 05 16 2006 10:57AM   Select CONVERT(varchar(100), GETDAT ...