Babel Preset-env

1. 面试题

Q: @babel/preset-env 是什么?如何配置 targets 和 modules?useBuiltIns: 'usage' 有什么作用?

2. 核心解答

@babel/preset-env 是 Babel 最常用的 预设 (Preset)。它根据你指定的 目标环境 (Target),自动决定需要启用哪些 插件 (Plugin),从而避免手动配置一大堆插件。

(1) Target (目标浏览器)

Babel 通过 browserslist (package.json 或 .browserslistrc) 配置目标: "browserslist": ["> 1%", "last 2 versions", "not ie <= 8"] Babel 内部有一个数据库 (compat-table),记录了每个 ES6 特性在不同浏览器版本上的支持情况。 原理:如果目标浏览器已经支持了箭头函数,preset-env 就不会引入 arrow-function 插件,从而减少代码体积。

(2) modules: 'auto' (模块格式)

默认是 'auto'。 如果你的构建工具 (Webpack/Rollup) 支持 ESM (Tree Shaking),你应该显式设置为 falsepresets: [['@babel/preset-env', { modules: false }]] 这样 Babel 就不会把 import/export 转换成 CommonJS require/module.exports,Webpack 才能基于静态分析做 Tree Shaking。

(3) useBuiltIns (Polyfill 策略)

这决定了 Babel 如何处理 API (Polyfill),如 Promise, Array.from

  • entry: 手动在入口引入 import 'core-js',Babel 会把这行代码转换成目标浏览器所需的 所有 polyfill (比如几十个)。体积巨大,不推荐。
  • usage (推荐): 不需要手动引入 core-js。Babel 会在每个文件里 按需引入 你所用到的 polyfill。
    • 代码:const p = new Promise();
    • 结果:import "core-js/modules/es.promise"; const p = new Promise();

(4) corejs: 3

必须配合 useBuiltIns: 'usage' 指定 core-js 版本。v2 已停止维护,通常用 v3。

3. 面试加分项

Q: 为什么有了 Preset 还需要 Plugin?

Preset (预设) 是一组 Plugin 的集合。Babel 官方提供了几个 Preset (如 preset-env, preset-react, preset-typescript)。但有时候你需要用到一些 尚未进入标准 (Stage 0-3) 的新语法 (如 pipeline operator |>),这时候就需要单独安装并配置对应的 Plugin。

4. 总结

  • Target: Browserslist (Determines plugins).
  • Modules: Set false for Tree Shaking.
  • Polyfill: useBuiltIns: 'usage', corejs: 3.