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 ...
随机推荐
- AIX UNIX 系统管理、维护与高可用集群建设——数据库结构设计
在对数据库类应用进行优化的过程中我们了解到一个原则,即思想上要从结构设计抓起,按照下面的顺序: 1.数据库逻辑结构设计和物理设计. 2.数据库对象部署和SQL代码编写. 3.数据库实例性能调整和优化. ...
- SQLServer中系统存储过程sp_spaceused
sp_spaceused 执行sp_spaceused存储过程的时候可以不用带参数,直接执行,或者exec sp_spaceused都可以,返回两个结果集: 列名 数据类型 描述 database_n ...
- activiti 里面各个方法理解
/** Return the intent that started this activity. */public Intent getIntent() { return mIntent;} pub ...
- Python3.4如何读写Excel
在python3.x(散仙使用的版本是python3.4)里,我们应该如何操作excel. 首先在python3.4里,我们可以使用新的python类库,来支持3.x之后的读写excel 针对 03版 ...
- c#-二分查找-算法
折半搜索,也称二分查找算法.二分搜索,是一种在有序数组中查找某一特定元素的搜索算法. A 搜素过程从数组的中间元素开始,如果中间元素正好是要查找的元素,则搜素过程结束: B 如果某一特定元素大于或者小 ...
- 浅述WinForm多线程编程与Control.Invoke的应用
VS2008.C#3.0在WinForm开发中,我们通常不希望当窗体上点了某个按钮执行某个业务的时候,窗体就被卡死了,直到该业务执行完毕后才缓过来.一个最直接的方法便是使用多线程.多线程编程的方式在W ...
- C# ComBox 垂直滚动条
用到Combox控件两个属性: 1 MaxDorpDownItems 显示条数 2 IntegralHeight 设置 为false 例如:显示最多20条,超过20条显示垂直滚动条 this.comb ...
- AutoHotkey 使用笔记
注意事项 为了支持中文需安装 AutoHotkey_L Notepad2对ahk代码高亮和折叠支持良好,SciTE则能够提供输入提示 绿色版*.ahk关联AutoHotkey.exe就能双击运行 Au ...
- windowsAPI遍历文件夹(速度高于递归)
#region API 遍历文件夹及其子文件夹和子文件 #region 声明WIN32API函数以及结构 ************************************** [DllImpo ...
- 将.NET dll注册到GAC(Global Assembly Cache)中
当发现有多个解决方案引用一个dll时,为了不重复引用所以将.net的一个dll注册到GAC中去. gacutil.exe. 记得使用管理员权限打开 开始菜单-Microsoft Visual Stud ...