Babel 是什么,有什么作用?
面试速答(30 秒版 TL;DR)
- Babel 是什么:一个 JavaScript 编译器(更准确说是“转译器”),把“新语法/方言”(ESNext、JSX、TS 等)转换成目标环境能跑的 JS。
- 核心作用:语法转换、按需注入辅助代码(helpers)、可选地配合 polyfill 做能力补齐。
- 和 ES6 模块的关系:Babel 可以把
import/export转成 CommonJS/AMD 等,也可以选择“保留 ESM”交给打包器做 tree-shaking。
心智模型:Babel 做的是“语法层”的工作
你可以把 Babel 理解为三步流水线:
- 解析:代码 -> AST
- 转换:AST -> AST(插件在这里工作)
- 生成:AST -> 代码
所以它擅长处理“语法形态”,例如把可选链、类字段、JSX、import/export 等改写为等价实现。
Babel 能做什么,不能做什么?
能做
- 把新语法改写成旧语法(例如把
?.、??、class 等转换)。 - 处理 JSX、TypeScript(注意:Babel 只“剥类型”,不做类型检查)。
- 处理模块语法:
- 转成 CommonJS:适合旧环境或某些 Node 构建流程。
- 保留 ESM:更利于 tree-shaking(由 bundler/rollup/webpack 负责)。
不能做(常见误区)
- 只靠 Babel 不等于“全部兼容”:Babel 主要解决“语法”,但像
Promise、Map、fetch这类 API 需要 polyfill 或运行时提供。 - polyfill 不是自动的:是否注入取决于你的 preset/配置(例如 preset-env + core-js 相关配置)。
最小例子:模块语法如何处理
1)把 ESM 转 CommonJS(示意)
源代码:
import {add} from './math.js';
export const answer = add(20, 22);
“转成 CommonJS”后大致会变成(示意):
"use strict";
const {add} = require("./math.js");
exports.answer = add(20, 22);
面试表达要点:语法被改写了,但“模块加载时机/静态分析能力”也可能随之变化,所以是否保留 ESM 需要结合工程目标。
常见追问
Q1:Babel 和 TypeScript 编译器(tsc)有什么区别?
- Babel:更偏“语法转换”,快,插件生态强;但不做类型检查。
- tsc:能类型检查,也能输出 JS;但在某些转换能力、生态上和 Babel 互补。
Q2:Babel 和打包器(webpack/rollup)是什么关系?
- Babel:把“单个文件的语法”变成目标语法。
- 打包器:处理依赖图、合并文件、tree-shaking、代码分割等。
易错点/坑
- 把 “Babel = polyfill” 说成必然:要强调 polyfill 需要额外配置或运行时支持。
- 模块转换的取舍:把 ESM 转 CJS 可能影响 tree-shaking,工程里通常会按环境分别产物。
速记要点(可背诵)
- Babel:代码 -> AST -> 转换 -> 代码,解决“语法兼容”为主。
- 模块:可转 CJS,也可保留 ESM 交给 bundler 做优化。