@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 }] ] };
工作流程:
- 目标环境分析:解析
targets配置 - 插件选择:根据目标环境支持情况,确定需要哪些语法转换插件
- Polyfill 处理:根据
useBuiltIns配置处理 polyfills - 代码转换:应用选定的插件进行转换
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