作为前端工程师,我们每天都在和 JSX 打交道 ------ 写着像 HTML 又像 JavaScript 的代码,却很少深究它从「无法被浏览器识别」到「正常运行」的全……
作为前端工程师,我们每天都在和 JSX 打交道 ------ 写着像 HTML 又像 JavaScript 的代码,却很少深究它从「无法被浏览器识别」到「正常运行」的全过程。而 Babel,就是让这一切成为可能的幕后推手。今天就带大家扒开 JSX 编译的神秘面纱,从基础到实战,搞懂 Babel 是如何把 JSX 变成浏览器能读懂的代码。
一、JSX:看起来像 HTML 的 JavaScript,却不能直接跑?
(一)先搞懂:JSX 到底是什么?
JSX 全称是 JavaScript XML,简单说就是「长得像 HTML 的 JavaScript 语法扩展」。比如我们写 React 组件时经常会这样写:
jsx
复制代码
// JSX语法
const App = () => {
return
};
但你要知道:JSX 本质是 React.createElement 的「语法糖」。它存在的意义,是让我们写 UI 代码时更直观(不用嵌套一堆 createElement)。
(二)为什么 JSX 不能独立运行?
浏览器的 JavaScript 引擎只能解析标准 JS 语法,根本不认识
直接在浏览器里运行 JSX 代码,会报错(Uncaught SyntaxError)
必须先通过工具把 JSX 编译成标准 JS------ 这就是 Babel 要做的事
(三)在 Vite 和 React 中,JSX 是怎么被处理的?
1. Vite 中的 JSX:直接转成 React.createElement
Vite 开发环境用 esbuild 快速处理 JSX,最终会转成这样:
js
复制代码
// 编译后的代码(简化版)
const App = () => {
return React.createElement("div", { className: "title" }, "Hello JSX");
};
2. React 环境中,Babel 才是「核心编译工具」
React 官方推荐用 Babel 处理 JSX,除了转 JSX,它还能顺便解决「语法兼容问题」------ 比如把 ES6+ 转成 ES5,让老浏览器也能跑。
二、Babel:让新语法「穿越」到旧环境的神器
(一)Babel 的核心作用:「翻译官」+「兼容大师」
Babel 是一个 JavaScript 编译器,核心功能可以总结为:
把「新语法」转成「旧语法」(比如 ES6 的 let 转成 ES5 的 var)
把「框架语法」转成「标准语法」(比如 JSX 转成 React.createElement)
让我们「大胆用最新语法,不用等浏览器支持」
举几个直观的例子:
原语法(新 / 扩展)
编译后(标准 JS)
let a = 1
var a = 1
() => { return 1 }
function () { return 1 }
async/await
转成基于 Promise 的代码
React.createElement("div", null, "Hello")
这也是为什么 Babel 官网敢说「Make JavaScript Great Again」------ 有了它,我们不用迁就旧环境,放心用新特性。
(二)Babel 的核心包:这两个必须认识
要想用 Babel 编译代码,离不开两个核心包:
@babel/core:Babel 的「心脏」,负责核心的编译逻辑(解析、转换、生成代码)
@babel/cli:Babel 的「命令行工具」,让我们能在终端输入命令执行编译
简单说:@babel/core 是「发动机」,@babel/cli 是「操作面板」。
三、手把手实战:用 Babel 编译 JSX 的完整流程
(一)第一步:安装依赖
首先在项目里安装 Babel 相关包,注意用 -D(开发依赖)------ 因为编译是开发阶段的事,上线后不需要这些工具:
bash
复制代码
# 安装核心包
pnpm i @babel/cli @babel/core -D
# 还需要JSX转换规则(React项目必装)
pnpm i @babel/preset-react -D
@babel/preset-react:专门处理 React/JSX 的「预设规则」(可以理解为「现成的编译方案」)
(二)第二步:配置 Babel 规则
在项目根目录新建 .babelrc 配置文件,告诉 Babel 怎么编译:
json
复制代码
{
"presets": ["@babel/preset-react"] // 使用React预设
}
(三)第三步:用命令行编译 JSX
Babel 的命令行工具在 ./node_modules/.bin/babel,我们可以直接调用它编译文件。
比如我们有一个 src/app.jsx 文件:
jsx
复制代码
// src/app.jsx
const App = () =>
执行编译命令:
bash
复制代码
# 把src/app.jsx编译后输出到dist/app.js
./node_modules/.bin/babel src/app.jsx -o dist/app.js
编译后的 dist/app.js 会变成这样(标准 JS):
js
复制代码
const App = () => React.createElement("div", null, "Hello Babel");
(四)常用命令参数详解
Babel CLI 有很多实用参数,记几个高频的:
参数
作用
例子
-o
指定输出文件(单文件)
babel src/a.jsx -o dist/a.js
-d
指定输出目录(多文件)
babel src -d dist(编译 src 下所有文件到 dist)
-w
监听文件变化(改了自动重新编译)
babel src -d dist -w
-p
指定预设(可以覆盖配置文件)
babel src -o dist.js -p @babel/preset-react
-h
查看所有参数帮助
babel -h
四、总结:为什么前端工程师必须懂 Babel?
JSX 的本质是语法糖,必须通过编译才能运行 ------Babel 是最常用的工具
Babel 不只是处理 JSX,还能解决语法兼容问题(ES6→ES5 等)
掌握编译流程,能帮你排查很多「语法报错」(比如忘记装 preset 导致 JSX 编译失败)
最后想说:前端开发中,「写代码」只是一部分,「知道代码怎么跑起来」更重要。Babel 和 JSX 编译就是这个「背后的逻辑」------ 懂了它,你对前端工程化的理解会更上一层楼。