最新公告
  • 欢迎您光临起源地模板网,本站秉承服务宗旨 履行“站长”责任,销售只是起点 服务永无止境!立即加入钻石VIP
  • polyfill 在babel7时代何去何从

    正文概述 掘金(粘贴大神)   2021-02-20   890

    一、前言

    • babel 的核心功能是转译代码(新语法,如箭头函数,类等)和polyfill能力(新内置对象,api等),本文主要讨论polyfill能力。

    • babel7.4之后,官方已经废弃@babel/polyfill 。@babel/runtime 在7.0.0后也去除了polyfill能力的core-js。polyfill作为前端垫片,铺平各浏览器差异的类库,前端开发者该何去何从,如何选择呢

    二、babel-polyfill 、babel-runtime、 babel/preset-env

    1、babel-polyfill

    它的初衷是模拟(emulate)一整套 ES2015+ 运行时环境,所以它的确会以全局变量的形式 polyfill Map、Set、Promise 之类的类型,也的确会以类似 Array.prototype.includes() 的方式去注入污染原型

    优点:

    1、解决了Babel不转换新api的问题,能解决runtime无法转换内置对象新的实例方法。

    缺点:

    1、在代码中插入帮助函数,污染了全局环境。引入新的全局对象,修改了原型方法。

    2、不同文件中存在重复代码,,编译后体积较大。

    举个例子, 我在项目中定义了跟规范不一致的Array.from()函数,同时引入了一个库(依赖babel-polyfill),此时,这个库可能覆盖了自定义的Array.from()函数,导致出错。 这就是babel-runtime存在的原因。它将开发者依赖的全局内置对象等,抽取成单独的模块,并通过模块导入的方式引入,避免了对全局作用域的修改(污染)。

     const obj = {}
     Object.assign(obj, { age: 30 });
     
    //转译后
    
    'use strict';
    // 使用了 core-js 提供的 assign
    var _assign = require('babel-runtime/core-js/object/assign');   
    var _assign2 = _interopRequireDefault(_assign);
    function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { default: obj }; }
    var obj = {};
    (0, _assign2.default)(obj, {
      age: 30
    });
    

    2、babel-runtime

    此处首先说明的是babel-runtime(babel6) 而不是@babel/runtime(babel7) 在babel 6时代的runtime 包含 工具方法(helper)和polyfill功能core-js,可以通过配置babel-plugin-transform-runtime的属性来决定polyfill能力。

     plugins: [
            [
                "transform-runtime", //babel-plugin-transform-runtime简写
                {
                    "absoluteRuntime": false,
                    "corejs": 2,
                    "helpers": true,
                    "regenerator": true,
                    "useESModules": false,
                    "version": "7.0.0-beta.0"
                }
            ]
        ]
    

    babel进入7.0.0后,@babel/runtime的core-js被移除,不在支持polyfill的作用,因此只能提供编译的一些工具方法。垫片能力被放到 @babel/preset-env的 useBuiltIns完成。下文讨论。

    本节主要讨论6时代的polyfill的优缺点。

    优点:

    1)避免了babel-polyfill全局污染

    2)结合babel-plugin-transform-runtime的ast分析,实现了内置对象,的静态方法的按需加载。

    缺点:

    只支持到static方法,全局内置对象等。

    babel-polyfill与babel-runtime相比虽然有各种缺点,但在某些情况下仍然不能被babel-runtime替代, 例如, [1, 2, 3].includes(3),Array,Object以及其他”实例”下es6的方法,babel-runtime是无法支持的, 因为babel-runtime只支持到 static 的方法,对于应用项目还需要结合babel-prolyfill使用。 而一些工具库,可以用runtime处理,使用方统一polyfill。

    基于此,@babel/preset-env的 useBuiltIns方式 在babel7应用中便诞生了。他继承了babel-runtime不污染全局的特征,并且完善了runtime对原型方法支持不足的缺点。因此是目前应用的主要配置方式。

    3、 @babel/preset-env之 useBuiltIns

    useBuiltIns影响 编译过程中的polyfill处理,不影响babel调用的插件

    false:
        "presets": [
            [
                "@babel/preset-env",
                {
                    "useBuiltIns": false,  //布尔类型,
                    "corejs": 3,
                    "debug": true,
                    "modules": false 
                }
            ]
        ]
    

    测试结果 babel 不做polyfill转化处理。(不管有没有引入core-js,都不会做polyfill处理) webpack打包依赖import引入,完全按import来

    entry
        "presets": [
            [
                "@babel/preset-env",
                {
                    "useBuiltIns": "entry",
                    "corejs": 3,
                    "debug": true,
                    "modules": false 
                }
            ]
        ]
    

    需要配合引入

    import "core-js";  // 引入es,esnext,以及一些web处理的polyfill
    import  "core-js/stable"/ /稳定的polyfill
    import   "core-js/proposals"  //提案阶段的polyfill
    import  "core-js/stage/4.js"  // 指定提案级别高的的polyfill
    import "regenerator-runtime/runtime"
    

    若不引入core,则不会polyfill 测试结果 Replaced core-js entries with the following polyfills babel会根据import 进行引入polyfill。 优点:在不考虑包大小情况下,引入简单。 缺点: 1)若引入core-js 会引入所有的polyfill,大部分的polyfill都是无用的,包的体积也大大增加了 2)若指定引入细分,则要求开发则对调用的函数,core-js本身要够熟悉,学习成本大,引入难度大。

    usage "presets": [ [ "@babel/preset-env", { "useBuiltIns": "usage", "corejs": 3, "debug": true, "modules": false } ] ] 不引入core.js

    测试结果: 1、有条件的按需加载(es),esnext不会自动加载,因此使用时一定要注意是不是esnext级别的提案。,

    import "core-js/modules/esnext.math.radians.js"; import "core-js/modules/esnext.string.replace-all"; 可以通过node_modules/core-js/modules中查看是不是esnext

    2、引不引入corejs,babel结果是一样。

    3、esnext手动引入会被webpack进来

    三、core2js 、core3js、 es 、esnext

    在不传corejs 版本时,corejs默认按core2js获取文件,若安装3.0 ,则会报错,因为core2js、和core3js的文件结构已经发生变化。

        "presets": [
            [
                "@babel/preset-env",
                {
                    "useBuiltIns": "usage",
                     // "corejs": 2,
                    "debug": true,
                    "modules": false 
                }
            ]
        ]
    

    core2js 文件结构

    polyfill 在babel7时代何去何从

    core3js 文件结构

    polyfill 在babel7时代何去何从

    1、 corejs2 es6后提案功能被统一放到core-js/es7中。 目前corejs2,开发分支已经锁死,新特征不再更新完善,所有新提案在core3js上提交。 corejs3 新提案在 core-js/modules/esnext中实现。当 "useBuiltIns": "usage"时,esnext中的方法不会被polyfill,只能手动import。支持ECMAScript稳定功能,引入core-js@3冻结期间的新功能,比如flat

    2、加入到ES2016-ES2019中的提案,现在已经被标记为稳定功能

    3、更新了提案的实现,增加了proposals配置项,由于提案阶段不稳定,需要谨慎使用

    4、增加了对一些web标准的支持,比如URL 和 URLSearchParams

    5、现在支持原型方法,同时不污染原型

    6、删除了过时的特性

    四、总结

    @babel/polyfill 由于其污染性,引入不灵活等弊端,babel7.4后已经被官方deprecated。babel-runtime由于其不支持原型方法,还要结合polyfill使用, babel-runtime 在7.0.0后也移除了其polyfill的core-js 。babel7通过预制env 的useBuiltIns配置来实现polyfill。继承了runtime的有点。弥补了原型方法支持不足的问题。

    presets: [
      ["@babel/preset-env", {
        useBuiltIns: "entry",
        corejs: 3,
      }]
    ]
    
    import "core-js/stable";
    import "regenerator-runtime/runtime";
    

    通过corejs 引入后,实现了无污染的polyfill,使用 useBuiltIns: "usage" 可以实现按需加载。

    1、脚本

      "scripts": {
        "clean": "rimraf dist",
        "build": "rimraf dist && npx webpack",
        "babel": "rimraf babel_result && npx babel src -d babel_result",
        "node": "node dist/index.js",
        "start": "webpack-dev-server --inline --progress --config webpack.config.js"
      },
    

    npm run babel 查看babel 的结果,
    "debug": true可以看到babel 构建过程。

    • 2、@bebel/*** 类库说明
     @babel/runtime  //单独的包babel-runtime用以提供编译模块的工具函数,新版本功能被削弱
     @babel/plugin-transform-runtime //合并runtime的调用
     @babel/preset-env  //bebel7 新预制env
     @babel/core   //babel内核
     core-js  //polyfill api的差异
     regenerator-runtime/runtime  // async await  yeild iterator等
     @babel/polyfill  //core-js 和     regenerator-runtime/runtime
    

    起源地下载网 » polyfill 在babel7时代何去何从

    常见问题FAQ

    免费下载或者VIP会员专享资源能否直接商用?
    本站所有资源版权均属于原作者所有,这里所提供资源均只能用于参考学习用,请勿直接商用。若由于商用引起版权纠纷,一切责任均由使用者承担。更多说明请参考 VIP介绍。
    提示下载完但解压或打开不了?
    最常见的情况是下载不完整: 可对比下载完压缩包的与网盘上的容量,若小于网盘提示的容量则是这个原因。这是浏览器下载的bug,建议用百度网盘软件或迅雷下载。若排除这种情况,可在对应资源底部留言,或 联络我们.。
    找不到素材资源介绍文章里的示例图片?
    对于PPT,KEY,Mockups,APP,网页模版等类型的素材,文章内用于介绍的图片通常并不包含在对应可供下载素材包内。这些相关商业图片需另外购买,且本站不负责(也没有办法)找到出处。 同样地一些字体文件也是这种情况,但部分素材会在素材包内有一份字体下载链接清单。
    模板不会安装或需要功能定制以及二次开发?
    请QQ联系我们

    发表评论

    还没有评论,快来抢沙发吧!

    如需帝国cms功能定制以及二次开发请联系我们

    联系作者

    请选择支付方式

    ×
    迅虎支付宝
    迅虎微信
    支付宝当面付
    余额支付
    ×
    微信扫码支付 0 元