Babel 学习
一,为了更明白地使用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 学习的更多相关文章
- Babel学习小记
一.babel配置文件中的plugins和presets是什么? 1.首先说说babel是什么,babel是一个JavaScript转码器,帮助我们把浏览器不兼容的ES6语法转换成ES5语法: 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 ...
- 关于babel官网的学习
提起babel,前端er大概都不陌生.但是为什么要有babel呢?解决了什么问题?怎么使用babel呢?注意点在哪?以下就从这几个方面总结一下我关于babel学习的结果吧. 为什么要有babel呢? ...
- 你好,babel
写在前面 其实学babel是本人2019年Q3的一个计划,因为当时自己做的一个项目需要自己去配babel,也遇到了一些困难,发现自己对babel的了解还是很少的,所以决定好好看下babel:可是后来解 ...
- chrome devtools tip(2)--自定义代码片段,构建你的工具箱
平常开发中,有些代码片段常常用到的,比如,获取 url 参数,rgb转16进制,打印下当前页面的性能数据,给所有的 span 加个样式, 防抖节流,fetch接口,类似 jquery这样的顺手 选择 ...
- 学习 React(jsx语法) + es2015 + babel + webpack
视频学习地址: http://www.jtthink.com/course/play/575 官方地址 https://facebook.github.io/react/ 神坑: 1.每次this.s ...
- ES6学习(1)——如何通过babel将ES6转化成ES5
使用babel编译ES6 babel是一个工具,可以通过多个平台,让js文件从ES6转化成ES5,从而支持一些浏览器并未支持的语法. Insall babel $ sudo npm install b ...
- ES6学习之Babel的正确安装姿势
开始学习ES6,写点东西放上博客^_^ 本文介绍Babel6.x的安装过程~ 首先呢,可以使用Babel在线转换 https://babeljs.io/repl/ 然后进入主题:安装Babel(命令行 ...
- Vue学习笔记-Vue.js-2.X 学习(六)===>脚手架Vue-CLI(项目说明-Babel)
五 Vue学习-vue-cli脚手架学习(创建只选一个选项:Babel) 1. 项目目录说明 node_modules : 包管理文件夹 public : 静态资源 src : 源代码 gitign ...
随机推荐
- Android下OpenCV的环境搭建
目录(?)[-] 前言 系统环境 相关工具 Android ADT环境搭建 Android SDK环境变量的配置 Android NDK的安装与配置 OpenCV for Android 环境搭建 基 ...
- 003-常用的Meta标签写法和作用
页面关键词<meta name="keywords" content="your,tags"/> 页面描述<meta name="d ...
- C#先序遍历2叉树(非递归)
找了下先序遍历二叉树C# 实现貌似没有 顺手些了一个 大致思路是: 传入根节点,然后依次循环其子节点推入到栈中, 当推入的节点没有子节点的时候(叶子)或者所有子节点均已经遍历过后(上一次遍历的节点是该 ...
- Android studio 中的配置编译错误总结
1.编译Andorid 工程的时候,有时候出现gradle 报下面的错误. Error:(1, 0) Cause: com/android/build/gradle/LibraryPlugin : U ...
- js 函数总结
函数的基本语法如下所示: function functionName(arg0, arg1,...,argN) { statements } 函数如果有返回值则return 后的语句将不会被执行,返回 ...
- Qt qml 模拟iphone slide to unlock 的聚光动画文字效果
模拟iphone slide to unlock 的聚光动画文字效果 /底层放淡文字 /前景放高亮文字+半透明遮罩 /动画移动遮罩 Author: surfsky.cnblogs.c ...
- 精益化设计:把敏捷方法和Lean UX相结合
敏捷方法已经成为了主流.同时,Kindle和iPhone等设备取得的巨大成功也推动了体验设计的飞速发展.不过,如何把敏捷方法和UX设计结合起来,一直以来都是一个难题.文章将探讨如何把UX融入到最流行的 ...
- java反射小例子
package com.txwsqk.reflect; public class Car { private String brand; private String color; private i ...
- gulp编译sass
前言:前段时间学习了sass语法,但是一直用的是"考拉"这个软件工具将我写的sass代码编译成css,然后再引用到项目里面去的,随着对sass的更加深入的了解,我开始尝试着将sas ...
- ubuntu java开发环境搭建(jdk+tomcat+eclipse)
一.jdk的安装配置. 1.下载jdk. 下载地址:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-213 ...