跳到主要内容

Babel

Babel 的核心价值不是“让代码变短”,而是把现代语法和新特性转换成目标运行环境能理解的代码。

什么时候需要 Babel

  • 需要兼容较旧浏览器
  • 项目里在写 JSX、TypeScript、装饰器等非原生浏览器语法
  • 需要按目标环境注入必要的 polyfill

它在构建链路里的位置

源码 -> Babel 转译 -> bundler 处理依赖 -> 输出构建产物

Babel 负责“转译”,不负责完整打包。

最常见的三个能力

@babel/preset-env

根据目标浏览器或 Node 版本,决定要做哪些语法转换。

@babel/preset-react

处理 JSX。

@babel/preset-typescript

移除 TypeScript 类型标注,让代码进入后续构建环节。

一个常见配置

module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['>0.25%', 'not dead'],
},
useBuiltIns: 'usage',
corejs: 3,
},
],
'@babel/preset-react',
'@babel/preset-typescript',
],
plugins: ['@babel/plugin-transform-runtime'],
}

前端项目里怎么接

1. Webpack 项目

这是最经典的接入方式。

module.exports = {
module: {
rules: [
{
test: /\.[jt]sx?$/,
exclude: /node_modules/,
use: 'babel-loader',
},
],
},
}

2. React 项目

React 项目里,Babel 很常见的职责就是处理 JSX、class fields、某些实验语法以及浏览器兼容转换。

3. TypeScript 项目

如果团队希望:

  • tsc 只做类型检查
  • Babel 负责产物转换

@babel/preset-typescript 就会进场。

4. Vite / Next 项目

这类项目里未必需要手配 Babel,但遇到自定义插件、特殊语法或迁移历史代码时,仍然很容易碰到它。

一个更进阶的配置参考

module.exports = {
presets: [
[
'@babel/preset-env',
{
targets: {
browsers: ['defaults', 'not IE 11'],
},
useBuiltIns: 'usage',
corejs: 3,
bugfixes: true,
},
],
['@babel/preset-react', { runtime: 'automatic' }],
'@babel/preset-typescript',
],
plugins: [
['@babel/plugin-transform-runtime', { regenerator: true }],
['@babel/plugin-proposal-decorators', { version: '2023-11' }],
['@babel/plugin-proposal-class-properties', { loose: true }],
['babel-plugin-import', { libraryName: 'antd', style: true }, 'antd'],
],
env: {
production: {
comments: false,
compact: true,
},
},
}

这类配置更常见在:

  • 兼容目标较多的项目
  • 历史 React 工程
  • 组件库或后台系统
  • 需要装饰器、按需加载、复杂 polyfill 策略的项目

Polyfill 这块最容易混

Babel 能处理语法转换,但不天然处理所有运行时 API 兼容。

举个最常见的误区:

  • 语法能转,不代表 PromiseMapArray.prototype.flat 这类能力自动就有

这就是为什么很多项目还会配:

  • core-js
  • useBuiltIns
  • @babel/plugin-transform-runtime

项目里更常见的组织方式

babel.config.js
src/
webpack.config.js

或:

.babelrc
src/

如果是 monorepo,通常更适合把 Babel 配置提到仓库根部统一管理。

几个容易混淆的点

  • Babel 能处理语法转换,但不天然处理所有运行时 API 兼容
  • preset-typescript 不做类型检查,类型检查通常还是交给 tsc
  • Babel 和 bundler 不是一层东西
  • 现代框架可能已经内置 Babel 或替代方案,不一定需要手配

更实际的判断

Babel 现在对很多团队来说,不再是“每天都直接写配置”的工具,而是“遇到兼容目标、语法转换、自定义编译需求时一定会碰到”的那层基础设施。