@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");// ... 此处省略一大堆的 polyfillrequire("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。

@babel/preset-env相关推荐

  1. JavaScript高级语法打包 - babel插件安装配置报错!Error: Cannot find module ‘@babel/preset-preset.env‘

    目录 1. 插件安装和配置 2. 运行打包 - 报错信息 3. 解决办法 1. 插件安装和配置 安装babel转换器相关的包: npm i babel-loader @babel/core @babe ...

  2. JavaScript的相关知识与问题

    最初的样子 一, 不理解的知识1. 高阶函数' 一,JS的基础 1.查看效果,审查元素-Console 2.声明变量必须使用var关键词 语法一var name;声明变量,uname默认值为undef ...

  3. 【已解决】Couldn‘t find preset “babel/preset-env“ relative to directory

    运行webpack报错 Couldn't find preset "babel/preset-env" relative to directory 解决方法: 1.首先检查是否将依 ...

  4. Babel:plugin、preset的区别与使用

    文章概览 本文主要内容包括:什么是Babel Plugin.Babel Preset,两者的区别与联系.如何使用plugin/preset.如何创建自定义preset.使用注意事项. 本文所有例子可在 ...

  5. 【异常】前端Babel提示 Support for the experimental syntax ‘jsx‘ isn‘t currently enabled

    一.报错内容 17:33:41 - Building for production... 17:34:13 ERROR Failed to compile with 5 errors5:34:09 P ...

  6. babel 7.0.0-0_我们即将接近7.0 Babel版本。 这是我们一直在做的所有很酷的事情。...

    babel 7.0.0-0 by Henry Zhu 朱Henry 我们即将接近7.0 Babel版本. 这是我们一直在做的所有很酷的事情. (We're nearing the 7.0 Babel ...

  7. 为什么我们删除Babel的舞台预设:实验性提案的明确选择加入

    by Henry Zhu 朱Henry 为什么我们删除Babel的舞台预设:实验性提案的明确选择加入 (Why We Removed Babel's Stage Presets: Explicit O ...

  8. html转换成抽象语法树,五分钟了解抽象语法树(AST)babel是如何转换的?

    抽象语法树 什么是抽象语法树? It is a hierarchical program representation that presents source code structure acco ...

  9. import,export的支持[nodejs]

    背景 最近重读阮老师的<ECMAScript 6 入门>,其中 module相关章节,使用import 时报错,测试环境node版本v8.10.0,使用如下代码如下: cat export ...

  10. Vue移动端项目——Vant 移动端 REM 适配

    Vant官方文档 Vant 中的样式默认使用 px 作为单位,如果需要使用 rem 单位,推荐使用以下两个工具: postcss-pxtorem 是一款 postcss 插件,用于将 px 单位转化为 ...

最新文章

  1. leetcode算法题--子集
  2. java程序员修炼之道 pdf_?活动丨和大咖云风来场1对1交流,分享《程序员修炼之道》心得...
  3. linux随机数示例:随机产生以139开头的电话号码
  4. 142-练习8和9 for循环的嵌套调用和随机数的生成
  5. 数据结构实验之栈七:出栈序列判定
  6. python期末考试重点_如何应付大学的python考试而不至于挂科?
  7. android欢迎页圆形倒计时,android 欢迎页圆形进度条倒计时功能
  8. python可以不用主函数吗_python自定义函数可以向前引用不用声明
  9. php css 编译,LAMP环境搭建之php安装
  10. 无法打开登录所请求的数据库 sa。登录失败。 用户 sa 登录失败。
  11. [LeetCode] 3Sum
  12. java excel 导入oracle_java代码导入excel数据至oracle(poi方式)
  13. 阶段3 1.Mybatis_09.Mybatis的多表操作_2 完成account表的建立及实现单表查询
  14. 人工智能挑战教师角色独特性 与教育教学融合显现独特优势
  15. 数据库设计(5)-理解用户需求
  16. linux startx无效_startx命令_Linux startx 命令用法详解:用来启动X Window
  17. 《费马大定理》个人笔记整理
  18. Linux进程的概念
  19. FIFA halts 2026 bids amid scandal 国际足联在丑闻期间停止2026年足球世界杯申请
  20. SUMPRODUCT countif

热门文章

  1. OleDbDataReader Demo
  2. location对象详解
  3. 戴尔科技全面创新,让数字化梦想照见现实
  4. 面试官:聊聊你知道的跨域解决方案
  5. 辛巴巴巴鲁比啦音乐计算机版,辛巴巴巴鲁比啦什么歌
  6. 联通sgip1.2接入笔记
  7. 4.1Adapter模式
  8. uniapp使用安卓原生插件(包含插件带第三方jar)
  9. 开发过程中自己遇到的问题总结
  10. JDBC-MySQL-Tomcat 登录到主页