引言
Babel 是现代 JavaScript 开发中不可或缺的工具链核心,它让开发者能够使用最前沿的 JavaScript 特性,同时确保代码能在各种浏览器和环境中运行。
一、理解核心概念
1.1 什么是 Babel?
Babel 是一个 JavaScript 编译器 (更准确说是转译器),主要功能包括:
- 将 ES6+ 代码转换为向后兼容的 JavaScript 版本
- 转换 JSX 语法
- 添加缺失的 polyfill
- 源代码转换(codemods)
1.2 为什么需要 Babel?
- 浏览器兼容性:不同浏览器对新特性支持不一致
- 开发效率:使用最新语法提高开发体验
- 未来兼容:提前使用尚未广泛支持的提案特性
- 生态统一:配合 TypeScript、React 等工具链
1.3 Babel 核心工作流程
- 解析(Parsing):将代码转换为抽象语法树(AST)
- 转换(Transforming):对 AST 进行各种操作
- 生成(Generating):将转换后的 AST 生成新代码
二、Babel 基础配置
2.1 基础安装
bash
npm install --save-dev @babel/core @babel/cli @babel/preset-env
@babel/preset-env
不包含任何未进入 Stage 3 阶段的 JavaScript 语法提案,因为在 TC39 的流程中,未进入 Stage 3 阶段的提案是不会被任何浏览器所实现的。 如果确有需要,可以手动设置。通过设置shippedProposals
参数可以包含进入 Stage 3 阶段并且已经被部分浏览器实现的提案
2.2 基础配置文件 babel.config.json
json
{
"presets": [
[
"@babel/preset-env",
{
"targets": {
"edge": "17",
"firefox": "60",
"chrome": "67",
"safari": "11.1"
},
"useBuiltIns": "usage",
"corejs": "3.6.5"
}
]
]
}
2.3 运行 Babel
bash
npx babel src --out-dir dist
src
: 源文件夹dist
: 输出文件夹
2.4 常用 presets
Preset | 功能 |
---|---|
@babel/preset-env |
智能转换 ES6+ 语法 |
@babel/preset-react |
转换 JSX 语法 |
@babel/preset-typescript |
转换 TypeScript |
三、常用预设@babel/preset-env
3.1 基本配置
json
{
"presets": [
[
"@babel/preset-env",
{
"useBuiltIns": "usage",
"corejs": "3.32"
}
]
]
}
四、自定义转换规则
4.1 插件 vs Preset(预设)
- Preset :插件集合(如
@babel/preset-env
包含几十个插件) - 插件 :单一功能转换(如
@babel/plugin-transform-arrow-functions
)
插件和预设可以组合使用也可以各自单独使用
这意味着如果两个转换插件都将处理"程序(Program)"的某个代码片段,则将根据转换插件或 preset 的排列顺序依次执行。
- 插件在 Presets 前运行。
- 插件顺序从前往后排列。
- Preset 顺序是颠倒的(从后往前)
4.2 单一插件使用示例
箭头函数插件,此插件包含于@babel/preset-env
中。
4.2.1 安装插件
css
npm install --save-dev @babel/plugin-transform-arrow-functions
4.2.2 在babel.config.json
中添加配置
lua
{
"plugins": [["@babel/plugin-transform-arrow-functions", { "spec": true }]]
}
spec
:这个是插件编译的选项,每个插件都有自己不同的编译选项
4.2.3 具体示例
demo.js
// 源文件箭头函数
[1, 2, 3].map(n => n * 2);
javascript
// { "spec": false }]
"use strict";
[1, 2, 3].map(function (n) {
return n * 2;
});
javascript
// { "spec": true }]
"use strict";
var _this = void 0;
function _newArrowCheck(n, r) { if (n !== r) throw new TypeError("Cannot instantiate an arrow function"); }
[1, 2, 3].map(function (n) {
_newArrowCheck(this, _this);
return n * 2;
}.bind(void 0));
结语
如果你喜欢本教程,记得点赞+收藏!关注我获取更多JavaScript开发干货。