一、babel是什么
Babel官网上是这样说的:
Babel 是一个通用的多用途 JavaScript 编译器。通过 Babel 你可以使用(并创建)下一代的 JavaScript,以及下一代的 JavaScript 工具。作为一种语言,JavaScript 在不断发展,新的标准/提案和新的特性层出不穷。 在得到广泛普及之前,Babel 能够让你提前(甚至数年)使用它们。Babel 把用最新标准编写的 JavaScript 代码向下编译成可以在今天随处可用的版本。 这一过程叫做“源码到源码”编译, 也被称为转换编译(transpiling,是一个自造合成词,即转换+编译。以下也简称为转译)。
我理解的大概意思就是 JavaScript 不断发展,标准不断更新,但是有些新语法很多浏览器或其他环境是不支持的,为了码农们能够尽早的使用新的标准,又能有很好地兼容性,就能用babel将JavaScript 代码向下编译成可用的版本,即上面说的转译。
但是官网还说, Babel 的用途并不止于此,还支持语法扩展,能支持像 React 所用的 JSX 语法,同时还支持用于静态类型检查的流式语法,但是咱也不知道具体有啥用,就等之后再学吧,目前就先知道它常用来做转译。
另外,babel 本身不具有任何转译功能,主要靠 plugin。因此当我们不配置任何插件时,经过 babel 的代码和输入是相同的。
二、模块
1、babel-core(核心)
babel 的核心 api 都在core这个模块中,这个模块会把我们写的 js 代码抽象成 AST 树,然后再将 plugins 转译好的内容解析为 js 代码,所以要想使用babel就必须安装babel-core。
2、babel-polyfill(内部集成了 core-js 和 regenerator)
babel 几乎可以编译所有时新的 JavaScript 语法,但一些新的 api却不行,polyfill 即是在当前运行环境中用来复制(意指模拟性的复制,而不是拷贝)尚不存在的原生 api 的代码。
3、babel-cli
babel 的 cli 是一种在命令行下使用 babel 编译文件的简单方法,安装之后就可以通过命令 babel xxx.js 进行转译。
4、babel-runtime & babel-plugin-transform-runtime
为了实现 ECMAScript 规范,Babel 转译后的代码需要借助一些函数,但是这些函数就可能重复出现在一些模块里,导致编译后的代码体积变大,babel-runtime
即可供编译模块复用工具函数,启用插件 babel-plugin-transform-runtime
后,Babel 就会使用 babel-runtime
下的工具函数。
5、babel-register
babel-register 模块改写了 require
命令,为它加上一个hook,只要在文件中用require引入的以.js
、.jsx
、.mjs、.es
和 .es6
为后缀的文件,都会先使用 babel 进行转译。
三、怎么用
1、babel-cli
首先需要安装 babel-cli
npm install --global babel-cli(全局安装)
然后随便写了一个Untitled-1.js文件,如下:
// Untitled-1.js
var fn = () => {
console.log('这是一个箭头函数');
};
在终端切换到该文件目录下,执行:
babel Untitled-1.js -o compiled.js
// 或者
// babel Untitled-1.js --out-file compiled.js
可以把Untitled-1.js文件 转译后的代码写到文件,此时只是复制,因为还未配置转译规则,转译后文件如下:
// compiled.js
var fn = () => {
console.log('这是一个箭头函数');
};
2、
构建工具的插件 (如webpack 的 babel-loader, rollup 的 rollup-plugin-babel)
安装依赖:
npm i -D babel-loader @babel/preset-env @babel/core
在build文件下的webpack.config.js文件中添加:
module: {
rules:[
{
test:/\.js$/,
use:{
loader:'babel-loader',
},
exclude:/node_modules/
}
]
}
执行命令:
npm run build
转译并打包后的代码如下:
3、babel-register
首先安装 babel-register
npm install --save-dev @babel/register
使用时先引入require('babel-register'),然后将需要转译的文件通过require()引入,即可
实时转码,但此方法只适合在开发环境使用。
require("babel-register");
require("./index.js");
三、配置 Babel
由于没有配置规则,代码只是复制了一份,并没有变化,常用的配置方法有以下两种:
1、加到.babelrc(其他格式.babelrc.json
, .js
, .cjs
, .mjs)
中
新建.babelrc文件(.babelrc.json写法同
),并在里边加入所需配置,如下:
{
"presets": [],
"plugins": []
}
配置说明:
(1) Preset(预设)
preset就好像是插件的集合,通过使用或创建一个 preset
即可轻松使用一组插件,比如@babel/preset-env就包含了所有跟ES6转换有关的插件,下面是举个🌰:
{
"presets": [
"@babel/preset-env"
]
}
安装依赖:
npm install @babel/preset-env --save-dev
执行命令:
npm run compiler
可以看到箭头函数转译后变成了普通函数:
目前官网上有以下四种,详情移步官网:
- @babel/preset-env
- @babel/preset-flow
- @babel/preset-react
- @babel/preset-typescript
(2) Plugin
plugin即插件,是实现Babel代码转换功能的核心,下面举个🌰:
"plugins": [
"transform-es2015-arrow-functions"
]
执行命令npm run compiler后,可以看到箭头函数转换成了普通函数,因为transform-es2015-arrow-functions插件可以支持我们使用ES6的箭头函数特性。
plugin与preset的执行顺序:
- Plugin 会运行在 Preset 之前
- Plugin 从前到后执行
- Preset从后向前执行
2、加入到babel.config.json(其他格式.js
, .cjs
, .mjs)
写法同上,但是不同的是作用范围不同:
- .babelrc 只会影响本项目中的代码,可以在不同级的文件夹内分别写一个.babelrc文件,邻近的优先级更高
- babel.config 会影响整个项目中的代码,包含node_modules中的代码,一个项目只有一个babel.config文件
- 同时又.babelrc和babel.config时,.babelrc会覆盖babel.config的配置
babel.config.js写法(推荐使用):
module.exports = function(api) {
api.cache(true);
const presets = [...];
const plugins = [...];
return {
presets,
plugins
};
}
其他格式写法在这不一一列举,请移步官网查看。
3、与webpack一起配置,加在options中
下面是使用presets的一个例子,只是代码是打包的:
module: {
rules:[
{
test:/\.js$/,
use:{
loader:'babel-loader',
options:{
presets:['@babel/preset-env']
}
},
exclude:/node_modules/
}
]
}
打包后结果如下:
4、放在package.json中
在package.json中加入如下配置,效果同上:
"babel": {
"presets": [
"@babel/preset-env"
]
}
结语:
好啦,以上就是全部内容,只能说是babel的一个入门学习,没有太深入研究,之后补充。小丁也是边看文档,边查询相关文章,边学习记录,文章中可能写的不是很全面,也可能存在问题,欢迎大家指出哦!一起进步!