本文在 nodelover.me 同步发布
地址是:http://nodelover.me/#/blog/article/info/589ac0ee128fe10058fc83ff
看完本文,你可以对 babel 的一些插件有一个简单的认识,知道这些插件是干嘛用的,等需要用的时候,你还需要自己对照官网的文档进行配置。
why babel?
看近期的一些视频和文章,大家都知道,我最近是在学习和使用 TypeScript。所以大家可以不理解我为什么还要去学习 Babel 这个转换器。
原因如下
- TS 是 ES 的超集,TS 完全是可以编译成 ES 的样子,然后再通过 Babel 把 ES 编译成浏览器可以运行的 JS 代码。
- TS 除了一些自己的特性外,还包括了 ES 所有的特性。
- 只要 JS 可以运行,那么 TS 就一定可以解决,之所以报错,是因为找不到定义文件的问题,因为 ES 没有静态检测,所有我们可以先写 ES 来验证自己的一些想法。
前段时间我看见有人评价我说,拾人牙慧,都是照着文档读一偏。
当然你能把官网的一些资料阅读的很好,那么你一定很牛逼,呵呵。确实没必要听我废话,因为你都会了,但是你也可以试一试来写教程。
我了解可能大家想要我说出一些我自己的理解,其实在视频里面也有,但是我的理解始终是我的理解,不是你的理解,哪怕我告诉你,你也不一定理解。我能告诉你的是不理解去哪找答案,本着授人以鱼不如授人以渔的道理教大家写代码。
你问我要 ,我只能说抱歉,我没有。还有一些就是纯粹的键盘侠,不鸟就是了。
我认为脱离文档的讲解都是扯淡,视频,文章写了,就会过时,特别是 IT 类的技术文章,今天写的是 1.x 版本。10天后,对不起,官方发布 4.x 版本,预计年底发布 8.x 版本。这可能有点调侃 google 版本帝了。虽然没有那么夸张,但是事实确实如此。
尽管版本更新,但是它的文档也是随着更新的。只要文档不离手,走遍天下我都有。
使用
首先我们进入官网,官方直接给出了如何使用的例子。
安装依赖
npm install --save-dev babel-cli babel-preset-env
创建 .babelrc
文件
{
"presets": ["env"]
}
右边的这一块就是我们 ES2015 的语法新特性,不了解,直接点进去就可以查看。
babel-cli
就是我们的 babel 命令行工具,它会安装一个babel-node
的命令行工具,它可以直接运行 babel 代码。
preset
就是预设的意思,babel-preset-env
就是环境预设。
babel-preset-env 的作用是什么?
英语看不懂,自己用翻译看,谁都想不劳而获,但这是不可能的。
这一个是环境支持表。
大概意思就是,通过 env 这个预设,或者说转换器,他可以根据你配置的选项,自动添加一些其他的转换器,来满足你当前的装换需求。
那么它一定有一些配置选项。
地址在这。
http://babeljs.io/docs/plugins/preset-env/
在页面里面我们可以看到这些配置项。而且下面也有 example,也就是例子。
我简单说一下这些配置项的作用。
- targets.node 支持到哪个版本的 node
- targets.browsers 支持到哪个版本的浏览器
- loose 启动宽松模式,配合 webpack 的 loader 使用
- modules 使用何种模块加载机制
- debug 开启调试模式
- include 包含哪些文件
- exclude 排除哪些文件
- useBuiltIns 是否对 babel-polyfill 进行分解,只引入所需的部分
npm install --save-dev babel-cli babel-preset-env
这一条命令究竟安装了些什么东西呢?
首先查看 .bin 目录
很明显,我们用的上的就是 babel、babel-node 命令。
还安装了 babel-polyfill、babel-register,babel-core 至于作用我们等会再说。
我们新建一个 src/app.js
文件。
写下以下代码
let func = () => {
console.log("hello babeljs");
}
func()
在 package.json 里面添加一些脚本
"scripts": {
"start": "babel-node src/app.js",
"compile": "babel src -d dist"
},
关于如何使用 babel 命令行通过以下命令查看
./node_modules/.bin/babel --help
运行一下这俩个命令。
polyfill
babel 只是会装换语法,而版本对一些对象添加的新 API ,babel-cli 则无能为力。所以我们只能通过 babel-polyfill 这个插件,它的原理就是通过老的方法,实现新 API 提供的功能,然后再挂载到响应的对象上面去。
修改 .babelrc
,添加一些配置项
{
"presets": [
["env", {
"useBuiltIns": true
}]
]
}
修改 src/app.js
import "babel-polyfill"
let func = () => {
console.log("hello babeljs");
}
func()
运行转换命令
默认 import "babel-polyfill"
会转换为 require("babel-polyfill")
,但是经过我们的配置后。
变成了以上的样子。
babel-register
他会修改你的 require 函数,让它具有引入 es2015 代码模块的能力。
新建一个 moduleA.js 文件
export default {
name: "yugo"
}
修改 app.js 文件
// require("babel-register")
const A = require("./moduleA.js")
console.log(A)
运行,它会报错。
解开我们的注释,这样就可以拿到我们的对象了。
babel-core
它是把一个es 代码字符串,编译成 js 代码字符串的工具。
React
假如你用了 React,你可能需要安装这个插件
其他插件
latest 预设 是 es2017,es2016, es2015 的综合体。
还有一些位于草案,提议阶段的功能的插件转移工具。
- Stage 0 - Strawman(展示阶段)
- Stage 1 - Proposal(征求意见阶段)
- Stage 2 - Draft(草案阶段)
- Stage 3 - Candidate(候选人阶段)
- Stage 4 - Finished(定案阶段)
进入 2 阶段,基本上都已经确定要发布了。
在 2015 年进入 stage4 的叫做 es2015
在 2016 年进入 stage4 的叫做 es2016
以此类推
stage-0
stage0 包括,stage1,2,3的特性,还有自己的一些特性,这里的特性是函数绑定与 do 表达式。不懂没关系,自己点进去看例子就明白了。
依次类推,1 包括 2、3的特性。
let a = do {
if(x > 10) {
'big';
} else {
'small';
}
};
// is equivalent to:
let a = x > 10 ? 'big' : 'small';
obj::func
// is equivalent to:
func.bind(obj)
obj::func(val)
// is equivalent to:
func.call(obj, val)
::obj.func(val)
// is equivalent to:
func.call(obj, val)
安装和使用
官方给出了很多使用的例子在这个页面,照着配置就行了。
http://babeljs.io/docs/setup/#installation
这些特性感觉用起来非常的畅快,但是 ts 好像不支持使用这些特性。这就非常尴尬了。