Babel 预设 #
什么是预设? #
预设(Preset)是一组 Babel 插件的集合,用于支持特定的语法特性或场景。使用预设可以避免手动配置大量插件,简化配置过程。
text
┌─────────────────────────────────────────────────────────────┐
│ Babel Preset │
├─────────────────────────────────────────────────────────────┤
│ │
│ ┌─────────────┐ ┌─────────────┐ ┌─────────────┐ │
│ │ Plugin A │ │ Plugin B │ │ Plugin C │ │
│ └─────────────┘ └─────────────┘ └─────────────┘ │
│ │ │ │ │
│ └────────────────┼────────────────┘ │
│ │ │
│ ┌─────▼─────┐ │
│ │ Preset │ │
│ └───────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
官方预设列表 #
| 预设 | 说明 |
|---|---|
@babel/preset-env |
智能环境预设,按需转换 |
@babel/preset-react |
React JSX 支持 |
@babel/preset-typescript |
TypeScript 支持 |
@babel/preset-flow |
Flow 类型支持 |
@babel/preset-modules |
ES 模块优化 |
@babel/preset-env #
@babel/preset-env 是最重要的预设,它可以根据目标环境智能地确定需要使用的插件。
安装 #
bash
npm install --save-dev @babel/preset-env
基本使用 #
javascript
// babel.config.js
module.exports = {
presets: ['@babel/preset-env']
};
targets 配置 #
targets 用于指定目标运行环境:
javascript
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
// 字符串形式(使用 browserslist 查询语法)
targets: '> 0.25%, not dead',
// 对象形式(指定具体版本)
targets: {
chrome: '80',
firefox: '78',
safari: '14',
edge: '88'
},
// Node.js 环境
targets: {
node: 'current' // 当前 Node.js 版本
},
// 组合配置
targets: {
browsers: ['> 1%', 'last 2 versions', 'not dead'],
node: '12'
}
}]
]
};
targets 查询语法 #
javascript
// 常用查询语法
targets: {
// 全球使用率超过 1% 的浏览器
browsers: ['> 1%'],
// 最近 2 个版本
browsers: ['last 2 versions'],
// 排除已停止维护的浏览器
browsers: ['not dead'],
// 组合使用
browsers: ['> 0.25%', 'not dead'],
// 特定浏览器
browsers: ['Chrome >= 80', 'Firefox >= 78', 'Safari >= 14'],
// 排除特定浏览器
browsers: ['not IE 11']
}
browserslist 配置 #
可以在项目根目录创建 .browserslistrc 文件或 package.json 中配置:
json
// package.json
{
"browserslist": [
"> 1%",
"last 2 versions",
"not dead"
]
}
text
// .browserslistrc
> 1%
last 2 versions
not dead
modules 配置 #
控制模块转换方式:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
// 不转换模块(保留 ES 模块)
modules: false,
// 转换为 CommonJS
modules: 'cjs',
// 转换为 AMD
modules: 'amd',
// 转换为 UMD
modules: 'umd',
// 转换为 SystemJS
modules: 'systemjs',
// 自动检测(默认)
modules: 'auto'
}]
]
};
useBuiltIns 配置 #
控制 polyfill 的引入方式:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
// 不自动引入 polyfill
useBuiltIns: false,
// 根据使用情况按需引入(推荐)
useBuiltIns: 'usage',
// 根据目标环境在入口引入
useBuiltIns: 'entry',
// 必须指定 corejs 版本
corejs: 3
}]
]
};
useBuiltIns: ‘usage’ #
javascript
// 配置
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: 3
}]
]
};
// 源代码
const arr = [1, 2, 3].includes(2);
const promise = Promise.resolve();
// 编译后(自动注入需要的 polyfill)
import "core-js/modules/es.array.includes.js";
import "core-js/modules/es.promise.js";
var arr = [1, 2, 3].includes(2);
var promise = Promise.resolve();
useBuiltIns: ‘entry’ #
javascript
// 配置
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'entry',
corejs: 3
}]
]
};
// 入口文件
import 'core-js/stable';
import 'regenerator-runtime/runtime';
// Babel 会根据目标环境替换为具体的 polyfill
// 例如目标环境是 Chrome 80,则只引入 Chrome 80 不支持的 polyfill
corejs 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: '3', // 使用 core-js@3
corejs: '3.21', // 指定具体版本
corejs: { // 详细配置
version: '3.21',
proposals: true // 启用提案阶段的 polyfill
}
}]
]
};
targets.esmodules #
针对支持 ES 模块的现代浏览器:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
targets: {
esmodules: true // 支持原生 ES 模块的浏览器
}
}]
]
};
spec 配置 #
启用更符合规范的转换:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
spec: true // 更严格但更慢的转换
}]
]
};
loose 配置 #
启用更宽松的转换:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
loose: true // 更宽松但可能不完全符合规范
}]
]
};
shippedProposals 配置 #
启用已进入标准但尚未广泛支持的特性:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
shippedProposals: true
}]
]
};
debug 配置 #
输出调试信息:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
debug: true // 输出使用的插件和 polyfill 信息
}]
]
};
include 和 exclude #
强制包含或排除特定插件:
javascript
module.exports = {
presets: [
['@babel/preset-env', {
include: [
'@babel/plugin-transform-arrow-functions'
],
exclude: [
'@babel/plugin-transform-regenerator'
]
}]
]
};
@babel/preset-react #
用于 React 项目的 JSX 转换。
安装 #
bash
npm install --save-dev @babel/preset-react
基本使用 #
javascript
// babel.config.js
module.exports = {
presets: ['@babel/preset-react']
};
runtime 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-react', {
// 经典转换(需要手动引入 React)
runtime: 'classic',
// 自动转换(自动引入 JSX 运行时)
runtime: 'automatic' // 推荐
}]
]
};
经典转换 vs 自动转换 #
javascript
// 经典转换 (runtime: 'classic')
// 输入
const element = <div>Hello</div>;
// 输出
var element = React.createElement('div', null, 'Hello');
// 需要手动 import React from 'react';
// 自动转换 (runtime: 'automatic')
// 输入
const element = <div>Hello</div>;
// 输出
import { jsx as _jsx } from 'react/jsx-runtime';
var element = _jsx('div', { children: 'Hello' });
// 不需要手动引入 React
development 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-react', {
development: true, // 添加开发辅助信息
development: process.env.NODE_ENV === 'development'
}]
]
};
throwIfNamespace 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-react', {
throwIfNamespace: true // 抛出 XML 命名空间错误
}]
]
};
其他选项 #
javascript
module.exports = {
presets: [
['@babel/preset-react', {
runtime: 'automatic',
development: process.env.NODE_ENV === 'development',
useBuiltIns: true, // 使用内置方法
useSpread: false // 使用 Object.assign 而不是 spread
}]
]
};
@babel/preset-typescript #
用于 TypeScript 项目的类型剥离。
安装 #
bash
npm install --save-dev @babel/preset-typescript
基本使用 #
javascript
// babel.config.js
module.exports = {
presets: ['@babel/preset-typescript']
};
isTSX 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
isTSX: true // 允许在 .js 文件中使用 JSX
}]
]
};
jsxPragma 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
jsxPragma: 'React', // 替换默认的 React
jsxPragmaFrag: 'React.Fragment' // Fragment 替换
}]
]
};
allowNamespaces 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
allowNamespaces: true // 允许 JSX 命名空间
}]
]
};
allowDeclareFields 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
allowDeclareFields: true // 允许 declare 字段
}]
]
};
onlyRemoveTypeImports 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
onlyRemoveTypeImports: true // 只移除类型导入
}]
]
};
optimizeConstEnums 配置 #
javascript
module.exports = {
presets: [
['@babel/preset-typescript', {
optimizeConstEnums: true // 优化 const 枚举
}]
]
};
@babel/preset-flow #
用于 Flow 类型检查项目的类型剥离。
安装 #
bash
npm install --save-dev @babel/preset-flow
基本使用 #
javascript
// babel.config.js
module.exports = {
presets: ['@babel/preset-flow']
};
组合使用预设 #
React + TypeScript #
javascript
// babel.config.js
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-typescript',
['@babel/preset-react', { runtime: 'automatic' }]
]
};
完整 Web 项目 #
javascript
// babel.config.js
module.exports = function(api) {
const isProduction = api.env('production');
return {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead',
useBuiltIns: 'usage',
corejs: 3,
modules: false
}],
'@babel/preset-typescript',
['@babel/preset-react', { runtime: 'automatic' }]
],
plugins: [
'@babel/plugin-transform-runtime',
isProduction && 'babel-plugin-transform-remove-console'
].filter(Boolean)
};
};
Node.js 项目 #
javascript
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
targets: { node: 'current' }
}]
]
};
库开发 #
javascript
// babel.config.js
module.exports = {
presets: [
['@babel/preset-env', {
targets: { node: '12' },
modules: false // 保留 ES 模块
}]
],
plugins: [
['@babel/plugin-transform-runtime', {
useESModules: true
}]
]
};
预设执行顺序 #
text
┌─────────────────────────────────────────────────────────────┐
│ 预设执行顺序 │
├─────────────────────────────────────────────────────────────┤
│ │
│ 配置: │
│ presets: ['a', 'b', 'c'] │
│ │
│ 执行顺序: c -> b -> a(从后往前) │
│ │
│ ┌──────────┐ │
│ │ Plugin │ 先执行所有插件 │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ Preset c │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ Preset b │ │
│ └────┬─────┘ │
│ │ │
│ ▼ │
│ ┌──────────┐ │
│ │ Preset a │ │
│ └──────────┘ │
│ │
└─────────────────────────────────────────────────────────────┘
自定义预设 #
创建自定义预设 #
javascript
// my-preset.js
module.exports = function() {
return {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead',
useBuiltIns: 'usage',
corejs: 3
}]
],
plugins: [
'@babel/plugin-transform-runtime',
'@babel/plugin-proposal-class-properties'
]
};
};
使用自定义预设 #
javascript
// babel.config.js
module.exports = {
presets: [
'./my-preset.js',
'@babel/preset-react'
]
};
发布预设包 #
javascript
// @scope/babel-preset-my-preset/index.js
module.exports = function() {
return {
presets: [...],
plugins: [...]
};
};
// package.json
{
"name": "@scope/babel-preset-my-preset",
"main": "index.js"
}
// 使用
// babel.config.js
module.exports = {
presets: ['@scope/babel-preset-my-preset']
};
预设最佳实践 #
1. 使用 preset-env 的智能转换 #
javascript
// 推荐:让 preset-env 智能选择插件
module.exports = {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead',
useBuiltIns: 'usage',
corejs: 3
}]
]
};
2. 避免重复配置 #
javascript
// 不推荐:同时使用多个预设处理相同语法
module.exports = {
presets: [
'@babel/preset-env',
'@babel/preset-es2015' // 已废弃,不要使用
]
};
// 推荐:只使用 preset-env
module.exports = {
presets: ['@babel/preset-env']
};
3. 合理设置 targets #
javascript
// 不推荐:不设置 targets
module.exports = {
presets: ['@babel/preset-env'] // 会转换所有 ES6+ 语法
};
// 推荐:设置合理的 targets
module.exports = {
presets: [
['@babel/preset-env', {
targets: '> 0.25%, not dead'
}]
]
};
4. 使用 browserslist 配置 #
json
// package.json
{
"browserslist": {
"production": [
"> 1%",
"last 2 versions",
"not dead"
],
"development": [
"last 1 chrome version",
"last 1 firefox version"
]
}
}
常见问题 #
问题一:预设顺序错误 #
javascript
// 错误:preset-react 在 preset-typescript 之前
module.exports = {
presets: [
'@babel/preset-react',
'@babel/preset-typescript' // 不会处理 TSX 文件
]
};
// 正确:preset-typescript 在前
module.exports = {
presets: [
'@babel/preset-typescript',
'@babel/preset-react'
]
};
问题二:polyfill 重复 #
javascript
// 问题:多个入口重复引入 polyfill
// 解决:使用 useBuiltIns: 'usage'
module.exports = {
presets: [
['@babel/preset-env', {
useBuiltIns: 'usage',
corejs: 3
}]
]
};
问题三:模块转换问题 #
javascript
// 问题:使用 webpack 时模块被转换
// 解决:设置 modules: false
module.exports = {
presets: [
['@babel/preset-env', {
modules: false // 保留 ES 模块,让 webpack 处理
}]
]
};
下一步 #
现在你已经掌握了 Babel 预设的使用方法,接下来学习 插件系统 了解如何使用和开发插件!
最后更新:2026-03-28