详解如何添加babel polyfill

 更新时间:2023年06月29日 10:38:38   作者:时倾  
这篇文章主要介绍了详解vue如何添加babel polyfill实现方法,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪

正文

由于 Babel 7.4 之后不再推荐使用 @babel/polyfill,而 @babel/preset-env 和 plugin-transform-runtime 二者都可以设置 corejs 来处理 polyfill

@babel/polyfill废弃的主要原因有:

  • 此包仅仅是引入了 stable core-js 和 regenerator-runtime/runtime,其中后者可以使用插件 @babel/plugin-transform-regenerator 代替。
  • 此包不能从core-js@2 平滑过渡到 core-js@3。

Babel 简介

简单来说,Babel 是一个编译器,主要用于将采用 ECMAScript 2015+ 语法编写的代码转换为向后兼容的 JavaScript 语法,以便能够运行在新旧版本的浏览器等各个环境中。而 Babel 代码转换功能以 plugin 的方式实现,plugin 就是小型的 JavaScript 程序。

preset可以被看作是一组 Babel 插件或 options 配置的可共享模块。

  • plugins 在 presets 前运行;
  • plugins 从前往后顺序执行;
  • presets 根据排列顺序倒序执行;

babel 主要实现的两个功能:

  • 转换新语法。将新版 js 语法用旧版语法实现,从而在对应环境中运行,比如箭头函数;
  • 转换新 API。为旧版运行时打补丁(也被称为polyfill),从而使用在新版 js 中定义但在旧版运行时提供的功能,包括三类:

    • 新定义的内置对象,例如 Promise
    • 原有内置对象新添加的静态方法,例如 Array.from
    • 原有内置对象新添加的实例方法,例如 Array.prototype.includes

preset-env

preset-env 既可以转换新语法,也可以通过配置转换新的 APIpreset-env 的 polyfill 会污染全局环境。

target

这个字段可以填写 browserslist 的查询字符串,官方推荐使用 .browserslistrc 文件去指明编译的 target,这个配置文件还可以和autoprefixerstylelint等工具一起共享配置。所以不推荐在.babelrcpreset-env配置中直接使用targets进行配置。

如果需要单独在这里配置targets的话,preset-env中指明ignoreBrowserslistConfigtrue则忽略.browserslistrc的配置项。

useBuiltIns

是否使用其polyfill功能(全局环境的core-js)。有三个值:

  • false:默认值。在不主动import的情况下不使用preset-env来实现polyfills,只使用其默认的语法转换功能。如果使用默认值false,则应该避免在入口文件引入polyfill,使得打包体积过大。

entry:需要手动在入口处引入 polyfill,根据浏览器目标环境(targets)的配置,引入全部浏览器暂未支持的 polyfill模块,无论在项目中是否使用到。

import "core-js/proposals/string-replace-all"
  • usage: 不需要手动在入口文件引入polyfillBabel将会根据代码使用情况自动注入polyfill,如此一来在打包的时候将会相对地减少打包体积。

corejs

配置core-js,默认值"2.0"。此选项仅在与 useBuiltIns: usage 或 useBuiltIns: entry 一起使用时有效。

core-js: JavaScript 的模块化标准库,包含 PromiseSymbolIterator和许多其他的特性,它可以让你仅加载必需的功能。

  • version: 【string】版本号;
  • proposals: 【boolean】是否实现提案中的特性;
// .babelrc
{
  "presets": [    
    [      
      "@babel/preset-env",      
      {        
        "targets": {          
          "chrome": "80" // 推荐使用 .browserslistrc        
        },        
        "useBuiltIns": "usage",        
        "corejs": {          
          "version": 3, // 2 和 3 版本都需要手动安装库:yarn add core-js@3 
          "proposals": false        
        }      
      }    
    ]  
  ]
}

plugin-transform-runtime

plugin-transform-runtime 主要做了三件事:

  • 当开发者使用异步或生成器的时候,自动引入@babel/runtime/regenerator,开发者不必在入口文件做额外引入;
  • 动态引入 polyfill,提供沙盒环境,避免全局环境的污染;

    如果直接导入 core-js 或 @babel/polyfill 以及它提供的 Promise、Set 和 Map 等内置组件,这些都会污染全局。虽然这不影响应用程序或命令行工具,但如果代码是要发布给其他人使用的库,或者无法准确控制代码将运行的环境,则会出现问题。

  • 所有 helpers 帮助模块都将引用模块 @babel/runtime,以避免编译输出中的重复,减小打包体积;

corejs

配置值:false, 2, 或者 { version: number, proposals: boolean },默认值 false。

corejs安装建议
falsenpm install --save @babel/runtime
2npm install --save @babel/runtime-corejs2
3npm install --save @babel/runtime-corejs3

helpers

配置值 boolean 类型,默认值 true。
是否用对 moduleName 的调用替换内联 Babel 帮助程序(classCallCheck、extends等)。

regenerator

配置值 boolean 类型,默认值 true。
是否将生成器函数转换为使用不污染全局范围的再生器运行时。

useESModules

配置值 boolean 类型,默认值 false。
启用后,转换将使用帮助程序,而不是@babel/plugin-transform-modules-commonjs。这允许在 webpack 等模块系统中进行较小的构建,因为它不需要保留 commonjs 语义。

使用场景与实例分析

@babel/preset-env 和 plugin-transform-runtime 二者都可以设置使用 corejs 来处理polyfill,二者各有使用场景,在项目开发和类库开发的时候可以使用不同的配置。

不要同时为二者配置 core-js,以免产生复杂的不良后果。

项目开发

useBuiltIns 使用 usageplugin-transform-runtime 只使用其移除内联复用的辅助函数的特性,减小打包体积。

{
  "presets": [
    [
      "@babel/preset-env",
      {
        "useBuiltIns": "usage",
        "corejs": {
          "version": 3,
          "proposals": false
        }
      }
    ]
  ],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": false
      }
    ]
  ]
}

类库开发

类库开发尽量不使用污染全局环境的 polyfill,因此 @babel/preset-env 只发挥语法转换的功能, polyfill 由 plugin-transform-runtime 来处理,推荐使用 core-js@3,并且不使用未进入规范的特性。

{
  "presets": ["@babel/preset-env"],
  "plugins": [
    [
      "@babel/plugin-transform-runtime",
      {
        "corejs": {
          "version": 3,
          "proposals": false
        },
        "useESModules": true
      }
    ]
  ]
}

打包分析

测试代码如下:

// syntax
class Person {}
typeof Person
const array = [1, 2, 3]
const fun = () => {}
// api
const a = Array.isArray([3, 5, 8])
const b = array.map(itm => itm * 2)
const p1 = Promise.resolve(true)
const p2 = Promise.reject(false)
Promise.allSettled([p1, p2]).then(() => {
  console.log('then')
}).catch(() => {
  console.log('catch')
}).finally(() => {
  console.log('finally')
})

通过 preset-env 配置 core-js:

"use strict";
var _interopRequireDefault = require("@babel/runtime/helpers/interopRequireDefault");
require("core-js/modules/es.array.is-array.js");
require("core-js/modules/es.array.map.js");
require("core-js/modules/es.object.to-string.js");
require("core-js/modules/es.promise.js");
require("core-js/modules/es.promise.finally.js");
require("core-js/modules/es.array.iterator.js");
require("core-js/modules/esnext.promise.all-settled.js");
require("core-js/modules/es.string.iterator.js");
require("core-js/modules/web.dom-collections.iterator.js");
var _typeof2 = _interopRequireDefault(require("@babel/runtime/helpers/typeof"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime/helpers/createClass"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime/helpers/classCallCheck"));
// syntax
var Person = /*#__PURE__*/(0, _createClass2["default"])(function Person() {
  (0, _classCallCheck2["default"])(this, Person);
});
(0, _typeof2["default"])(Person);
var array = [1, 2, 3];
var fun = function fun() {}; // api
var a = Array.isArray([3, 5, 8]);
var b = array.map(function (itm) {
  return itm * 2;
});
var p1 = Promise.resolve(true);
var p2 = Promise.reject(false);
Promise.allSettled([p1, p2]).then(function () {
  console.log('then');
})["catch"](function () {
  console.log('catch');
})["finally"](function () {
  console.log('finally');
});

通过 plugin-transform-runtime 配置 core-js:

"use strict";
var _interopRequireDefault = require("@babel/runtime-corejs3/helpers/interopRequireDefault");
var _isArray = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/array/is-array"));
var _map = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/instance/map"));
var _promise = _interopRequireDefault(require("@babel/runtime-corejs3/core-js-stable/promise"));
var _typeof2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/typeof"));
var _createClass2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/createClass"));
var _classCallCheck2 = _interopRequireDefault(require("@babel/runtime-corejs3/helpers/classCallCheck"));
// syntax
var Person = /*#__PURE__*/(0, _createClass2["default"])(function Person() {
  (0, _classCallCheck2["default"])(this, Person);
});
(0, _typeof2["default"])(Person);
var array = [1, 2, 3];
var fun = function fun() {}; // api
var a = (0, _isArray["default"])([3, 5, 8]);
var b = (0, _map["default"])(array).call(array, function (itm) {
  return itm * 2;
});
var p1 = _promise["default"].resolve(true);
var p2 = _promise["default"].reject(false);
_promise["default"].allSettled([p1, p2]).then(function () {
  console.log('then');
})["catch"](function () {
  console.log('catch');
})["finally"](function () {
  console.log('finally');
});

通过打包后代码分析,以 preset-env 的方式会引入不必须的 polyfill,以 plugin-transform-runtime 的方式只会引入当前页面所需的 polyfill。

以上就是详解如何添加 babel polyfill的详细内容,更多关于添加 babel polyfill的资料请关注脚本之家其它相关文章!

相关文章

  • Vue中的数据监听和数据交互案例解析

    Vue中的数据监听和数据交互案例解析

    这篇文章主要介绍了Vue中的数据监听和数据交互案例解析,在文章开头部分先给大家介绍了vue中的数据监听事件$watch,具体代码讲解,大家可以参考下本文
    2017-07-07
  • vant Cascader级联选择实现可以选择任意一层级

    vant Cascader级联选择实现可以选择任意一层级

    这篇文章主要介绍了vant Cascader级联选择实现可以选择任意一层级方式,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教
    2024-07-07
  • vue2 webpack proxy与nginx配置方式

    vue2 webpack proxy与nginx配置方式

    这篇文章主要介绍了vue2 webpack proxy与nginx配置方式,具有很好的参考价值,希望对大家有所帮助。如有错误或未考虑完全的地方,望不吝赐教
    2022-10-10
  • vue使用技巧及vue项目中遇到的问题

    vue使用技巧及vue项目中遇到的问题

    这篇文章主要介绍了vue使用技巧及vue项目中遇到的问题,本文给大家带来的只是一部分,后续还会持续更新,感兴趣的朋友跟随脚本之家小编一起学习吧
    2018-06-06
  • Node.js使用orm2进行update操作时关联字段无法修改的解决方法

    Node.js使用orm2进行update操作时关联字段无法修改的解决方法

    这篇文章主要给大家介绍了Node.js使用orm2进行update操作时关联字段无法修改的解决方法,文中给出了详细的示例代码供大家参考学习,对大家具有一定的参考学习价值,需要的朋友们下面来一起看看吧。
    2017-06-06
  • ant-design-vue按钮样式扩展方法详解

    ant-design-vue按钮样式扩展方法详解

    这篇文章主要为大家介绍了ant-design-vue按钮样式扩展方法详解,有需要的朋友可以借鉴参考下,希望能够有所帮助,祝大家多多进步,早日升职加薪
    2023-06-06
  • vue click.stop阻止点击事件继续传播的方法

    vue click.stop阻止点击事件继续传播的方法

    今天小编就为大家分享一篇vue click.stop阻止点击事件继续传播的方法,具有很好的参考价值,希望对大家有所帮助。一起跟随小编过来看看吧
    2018-09-09
  • 详解vue 数组和对象渲染问题

    详解vue 数组和对象渲染问题

    这篇文章主要介绍了详解vue 数组和对象渲染问题,小编觉得挺不错的,现在分享给大家,也给大家做个参考。一起跟随小编过来看看吧
    2018-09-09
  • elementui中的el-cascader级联选择器的实践

    elementui中的el-cascader级联选择器的实践

    本文主要介绍了elementui中的el-cascader级联选择器的实践,文中通过示例代码介绍的非常详细,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
    2021-10-10
  • 基于Vue3+TypeScript的全局对象的注入和使用详解

    基于Vue3+TypeScript的全局对象的注入和使用详解

    这篇文章主要介绍了基于Vue3+TypeScript的全局对象的注入和使用,本篇随笔主要介绍一下基于Vue3+TypeScript的全局对象的注入和使用,需要的朋友可以参考下
    2022-09-09

最新评论