跳到主要内容

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 主要解决“语法”,但像 PromiseMapfetch 这类 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 做优化。