Babel Preset 与 Plugin 的关系与顺序

1. 面试题

Q: Babel 的 Plugin 和 Preset 有什么区别?它们的执行顺序是怎样的?

2. 核心解答

Preset (预设) 本质上就是一组 Plugin (插件) 的集合。

(1) 执行顺序

这是 Babel 最容易搞混的点。记住:Plugin 早于 Preset,Plugin 顺序执行,Preset 逆序执行

  1. Plugin 先,Preset 后 (Plugins run before Presets)。
  2. Plugin 从前到后 (Ordering is first to last)。
  3. Preset 从后到前 (Ordering is reversed / last to first)。

示例

{
  "plugins": ["plugin-A", "plugin-B"],
  "presets": ["preset-C", "preset-D"]
}

实际执行顺序A -> B -> D -> C

(2) 为什么 Preset 要逆序执行?

这主要是为了兼容 es2015 以前的规范 (Stage 0 -> Stage 1 -> ...)。 如果你配置了 es2015react 两个 Preset,通常希望 react (JSX -> JS) 先执行,然后再由 es2015 (ES6 -> ES5) 把 JSX 产物里的箭头函数转译掉。 如果在配置里先写了 es2015 再写 react:按照逆序规则,react 会先执行,这是合理的。

(3) 常用的 Preset

  • @babel/preset-env: 智能转换 ES6+ 语法。
  • @babel/preset-react: 转换 JSX。
  • @babel/preset-typescript: 移除类型注解。

3. 面试加分项

Q: 如何判断用 Plugin 还是 Preset?

如果是为了转换某个特定的新语法 (如 Decorator 装饰器),且该语法还处于 Stage 阶段,或者 preset-env 还没覆盖到,就必须单独引入对应的 Plugin。 如果是为了让代码在所有主流浏览器都能跑,直接用 Preset (preset-env) 最省心。

4. 总结

  • Structure: Preset is collection of plugins.
  • Order: Plugins(Forward) -> Presets(Reverse).
  • Stage: Plugins cover latest specs.