@babel/preset-env

本文详细介绍了Babel7中@babel/preset-env的使用,如何通过配置targets和useBuiltIns实现按需转换语法和引入polyfill。同时,讲解了@babel/plugin-transform-runtime的作用,避免代码重复。还提到了Babel7不再支持stage-x,以及配置文件查找规则的变化,帮助开发者更好地理解和配置Babel7。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

@babel/preset-env 根据指定的执行环境提供语法装换,也提供配置 polyfill。

Babel 7 已经弃用年份 preset: babel-preset-es2015, babel-preset-es2016, babel-preset-es2017, babel-preset-latest. 直接使用一个 env 搞定。

所以我们需要指定执行环境 Browserslist, Browserslist 的配置有几种方式,并按下面的优先级使用:

  1. @babel/preset-env 里的 targets
  2. package.json 里的 browserslist 字段
  3. .browserslistrc 配置文件

browserslist 是用来给不同的前端工具(Autoprefixer, babel-preset-env)共享 target browsers 和 Node.js versions 配置的. 一般推荐将配置写在 package.json 里的 browserslist 字段。

例如我们配置 .babelrc 如下:

// .babelrc
{
  "presets": [
    [
      "@babel/preset-env",
      {
        "targets": {
          "ie": 10
        }
      }
    ]
  ]
}

源文件:

// index.js
const f = () => {};

new Promise();

class Test {}

编译后是:

"use strict";

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var f = function f() {};

new Promise();

var Test = function Test() {
  _classCallCheck(this, Test);
};

Babel 转换了浏览器不支持的箭头函数和 Class,但是 Promise 并没有变化。这是因为 Babel 只转换不兼容的新语法,而对新的 API,如 Iterator、Generator、Set、Maps、Proxy、Reflect、Symbol、Promise、Object.assign() 等,是不会转换的。这时候就需要 polyfill 了。

polyfill 的使用在 Babel 7 有一些不同:

  • useBuiltIns 提供 false, entry, usage 三种方式
  • @babel/runtime, @babel/plugin-transform-runtime 把 helpers 和 polyfill
    功能拆分了。默认只提供 helpers。

useBuiltIns

"useBuiltIns": false,

此时不对 polyfill 做操作。如果引入 @babel/polyfill,则无视配置的浏览器兼容,引入所有的 polyfill。

"useBuiltIns": "entry",
"corejs": 2,

根据配置的浏览器兼容,引入浏览器不兼容的 polyfill。需要在入口文件手动添加 import ‘@babel/polyfill’,会自动根据 browserslist 替换成浏览器不兼容的所有 polyfill。
这里需要指定 core-js 的版本, 如果 “corejs”: 3, 则 import ‘@babel/polyfill’ 需要改成

import 'core-js/stable';
import 'regenerator-runtime/runtime';

编译结果:

"use strict";

require("core-js/modules/es6.array.copy-within");

// ... 此处省略一大堆的 polyfill

require("core-js/modules/web.immediate");

require("core-js/modules/web.dom.iterable");

require("regenerator-runtime/runtime");

function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }

var f = function f() {};

new Promise();

var Test = function Test() {
  _classCallCheck(this, Test);
};

看上面的编译结果,会发现还有个问题,_classCallCheck 辅助函数是直接内嵌的,如果多个地方使用 Class,那每个地方都会添加这个辅助函数,大量重复。
这时候就需要 @babel/plugin-transform-runtime 了。

@babel/plugin-transform-runtime

配置 .babelrc

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": 2,
        "targets": {
          "ie": 10
        }
      }
    ]
  ],
  "plugins": [
    ["@babel/plugin-transform-runtime"]
  ]
}

编译结果:

"use strict";

var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");

var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));

require("core-js/modules/es6.promise");

require("core-js/modules/es6.object.to-string");

var f = function f() {};

new Promise();

var Test = function Test() {
  (0, _classCallCheck2.default)(this, Test);
};

可以发现,helpers 是通过 require 引入的,这样就不会存在代码重复的问题了。

拾遗

Babel 7 废弃了 stage-x,如果需要用到一些特性,需要自己安装对应的 plugin,然后再配置中配置 plugin。

stage-x 原本是对应 ECMAScript 提案的不同阶段,每个阶段有不同的特性,但是提案一直在变,这些特性可能更进一步,也可能废弃。state-x 是否应该保持和不断更新的提案一致?怎么处理都无法适应变化,所以直接使用 stage-x 对后期的维护造成困惑和风险。

Babel 7 还有个配置文件查找的问题,升级后可能会出现 .babelrc 配置无效的情况,需要根据目录结构和规则调整。简单的说:

  • Babel 7 增加了 root 目录的概念,默认是 cwd 目录
  • Babel 分成项目级配置文件(如:.babel.config.js)和文件级配置文件(如:.babelrc)
  • 项目级目录是默认是在 root 目录查找,可以配置 root 或者 rootMode 来更改查找方式;也可以配置 configFile来指定文件或者关闭项目级配置
  • 文件级配置文件 .babelrc 会根据 babelrcRoots 配置(默认值为 root)的目录查找,且只作用于当前编译目录的package.json

总结

Babel 7 的配置方案:

  1. @babel/preset-env + targets + useBuiltins: usage
  2. @babel/plugin-transform-runtime + @babel/runtime
  3. 引入必要的 plugin

这样就实现了按需引入 polyfill,看起来也是相当完美。
但是想想还是存在问题的,比如:Babel 编译通常会排除 node_modules,所以 “useBuiltIns”: “usage” 存在风险,可能无法为依赖包添加必要的 polyfill。

<think>好的,我现在需要解决用户遇到的@babel/preset-envbabel-loader相关的报错问题。首先,用户提到的是安装配置时出现的错误,比如找不到模块‘@babel/preset-preset.env’。这可能是拼写错误,因为正确的包名应该是@babel/preset-env。所以第一步,我需要检查用户是否正确安装了相关的依赖。 根据引用[1],用户可能安装了babel-loader、@babel/core和@babel/runtime,但可能缺少了@babel/preset-env。这时候需要确认是否执行了正确的安装命令,比如npm install @babel/preset-env -D。另外,查看引用[3]和[4]中的配置示例,preset的名称是否正确写成了"@babel/preset-env",而不是其他拼写错误的形式。 接下来,用户的.babelrc或babel.config.js配置文件是否正确。根据引用[3],预设的配置应该是["@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3 }]。这里需要检查是否有拼写错误,比如corejs的版本是否正确指定为3,并且是否安装了对应的core-js包。根据引用[5],使用useBuiltIns: "usage"需要安装core-js@3,所以用户需要确保已经安装了core-js@3。 另外,查看webpack的配置文件是否正确引用了babel-loader。需要确认在module.rules中,test匹配了.js文件,并且use里配置了babel-loader。同时,要排除node_modules目录,避免不必要的转译。 还有可能的问题是版本兼容性。用户可能使用的Babel 7,而引用的包是否都是兼容的版本。比如@babel/preset-env@babel/core的版本是否匹配。如果用户升级了Babel到版本7,而某些插件还是针对Babel 6的,可能会导致问题。这时候需要检查所有相关依赖的版本是否一致。 最后,全局污染的问题可能出现在库开发中,但用户当前的问题可能更多是配置错误导致的模块找不到。需要用户检查错误信息的具体内容,确认是否还有其他缺失的模块,并根据报错提示安装相应的包。 总结步骤:安装正确依赖、检查配置文件、确认webpack配置、处理版本兼容性。此外,可能需要清理node_modules和lock文件后重新安装,确保依赖正确安装。</think>### 解决@babel/preset-envbabel-loader报错的分步指南 #### 1. **安装正确依赖** 确保已安装以下核心包: ```bash npm install babel-loader @babel/core @babel/preset-env core-js@3 -D ``` - `@babel/preset-env`是Babel的预设环境配置,`core-js@3`是Polyfill的实现库[^4][^5]。 - 若报错提示`Cannot find module '@babel/preset-preset.env'`,检查名称拼写是否正确(应为`@babel/preset-env`)[^1]。 #### 2. **配置`.babelrc`或`babel.config.js`** 在项目根目录创建或修改`.babelrc`文件: ```json { "presets": [ ["@babel/preset-env", { "useBuiltIns": "usage", // 按需引入Polyfill "corejs": 3, // 指定core-js版本 "targets": "> 0.25%, not dead" // 目标浏览器范围 }] ] } ``` - `useBuiltIns: "usage"`自动按需引入Polyfill,减少代码体积。 - `corejs: 3`必须与安装的`core-js@3`版本一致[^3]。 #### 3. **Webpack配置检查** 在`webpack.config.js`中添加babel-loader规则: ```javascript module: { rules: [ { test: /\.js$/, exclude: /node_modules/, use: { loader: 'babel-loader', options: { cacheDirectory: true } // 启用缓存提升性能 } } ] } ``` - `exclude: /node_modules/`避免转译第三方库[^2]。 #### 4. **处理版本兼容性** - 检查`package.json`中Babel相关包的版本是否一致: ```json "devDependencies": { "@babel/core": "^7.18.6", "@babel/preset-env": "^7.18.6", "babel-loader": "^8.2.5", "core-js": "^3.24.1" } ``` - 使用`npm outdated`检查过期依赖并更新。 #### 5. **清理缓存与重装依赖** 若仍报错,尝试: ```bash rm -rf node_modules package-lock.json npm install ``` #### 6. **特殊场景处理** - **库开发**:使用`@babel/plugin-transform-runtime`替代`useBuiltIns`,避免全局污染: ```bash npm install @babel/plugin-transform-runtime @babel/runtime -D ``` 配置`.babelrc`: ```json { "plugins": ["@babel/plugin-transform-runtime"], "presets": ["@babel/preset-env"] } ``` ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值