乐闻世界logo
搜索文章和话题

Babel 中的 @babel/preset-env 是如何工作的?useBuiltIns 选项有什么区别?

3月6日 23:08

@babel/preset-env 工作原理

核心概念

@babel/preset-env 是一个智能预设,它根据你指定的目标环境(浏览器或 Node.js 版本)自动确定需要的 Babel 插件和 polyfills,而不需要手动配置每一个转换。

工作机制

javascript
// babel.config.js module.exports = { presets: [ ['@babel/preset-env', { targets: { browsers: ['> 1%', 'last 2 versions', 'not dead'], node: 'current' }, useBuiltIns: 'usage', corejs: 3 }] ] };

工作流程

  1. 目标环境分析:解析 targets 配置
  2. 插件选择:根据目标环境支持情况,确定需要哪些语法转换插件
  3. Polyfill 处理:根据 useBuiltIns 配置处理 polyfills
  4. 代码转换:应用选定的插件进行转换

useBuiltIns 选项详解

1. false(默认值)

不自动添加 polyfills,需要手动引入。

javascript
// babel.config.js { useBuiltIns: false } // 需要手动在入口文件引入 import 'core-js/stable'; import 'regenerator-runtime/runtime';

特点

  • 完全手动控制 polyfills
  • 可能引入不必要的 polyfills
  • 包体积可能较大

2. "entry"

根据目标环境,将 import 'core-js' 替换为具体需要的 polyfills。

javascript
// babel.config.js { useBuiltIns: 'entry', corejs: 3 } // 源代码 import 'core-js/stable'; // 转换后(假设目标环境需要) import 'core-js/modules/es.array.iterator'; import 'core-js/modules/es.promise'; // ... 其他需要的 polyfills

特点

  • 替换入口文件的 core-js 导入
  • 根据目标环境过滤不需要的 polyfills
  • 全局污染(修改原生原型)

3. "usage"

根据代码中实际使用的特性,按需引入 polyfills。

javascript
// babel.config.js { useBuiltIns: 'usage', corejs: 3 } // 源代码 const arr = [1, 2, 3]; arr.includes(2); const promise = Promise.resolve(1); // 转换后 import 'core-js/modules/es.array.includes'; import 'core-js/modules/es.promise'; var arr = [1, 2, 3]; arr.includes(2); var promise = Promise.resolve(1);

特点

  • 按需引入,最小化 polyfill 体积
  • 无需手动导入 core-js
  • 全局污染(修改原生原型)
  • 推荐用于应用程序开发

对比总结

选项引入方式包体积全局污染适用场景
false手动最大库开发(不推荐)
entry入口文件替换中等应用程序
usage按需自动最小应用程序(推荐)

与 @babel/plugin-transform-runtime 的区别

useBuiltIns: 'usage' + core-js

javascript
// 全局污染方式 Array.prototype.includes = ... // 修改全局原型

@babel/plugin-transform-runtime + core-js

javascript
// babel.config.js { plugins: [ ['@babel/plugin-transform-runtime', { corejs: 3 // 使用 core-js 的模块化版本 }] ] }

特点

  • 不污染全局环境
  • 适合库/工具开发
  • 使用沙盒化的 polyfills
javascript
// 转换前 const arr = [1, 2, 3]; arr.includes(2); // 转换后(不污染全局) import _includesInstanceProperty from "@babel/runtime-corejs3/core-js-stable/instance/includes"; var arr = [1, 2, 3]; _includesInstanceProperty(arr).call(arr, 2);

最佳实践

1. 应用程序开发

javascript
// babel.config.js module.exports = { presets: [ ['@babel/preset-env', { targets: { browsers: ['> 1%', 'last 2 versions'] }, useBuiltIns: 'usage', corejs: 3 }] ] };

2. 库/工具开发

javascript
// babel.config.js module.exports = { presets: ['@babel/preset-env'], plugins: [ ['@babel/plugin-transform-runtime', { corejs: 3, helpers: true, regenerator: true }] ] };

3. 配置 browserslist

json
// package.json { "browserslist": [ "> 1%", "last 2 versions", "not dead" ] }

调试技巧

bash
# 查看实际使用的插件和 polyfills DEBUG=* npx babel src/index.js # 仅查看 preset-env 信息 DEBUG=@babel/preset-env npx babel src/index.js
标签:Babel