<output id="qn6qe"></output>

    1. <output id="qn6qe"><tt id="qn6qe"></tt></output>
    2. <strike id="qn6qe"></strike>

      亚洲 日本 欧洲 欧美 视频,日韩中文字幕有码av,一本一道av中文字幕无码,国产线播放免费人成视频播放,人妻少妇偷人无码视频,日夜啪啪一区二区三区,国产尤物精品自在拍视频首页,久热这里只有精品12

      @babel/preset-env使用polyfill遇到的坑

      場景還原

      最近將一個項目由babel@6升級到babel@7,升級后最重要的兩個包:

      • @babel/preset-env: 提供代碼的轉換和API的polyfill的能力
      • @babel/plugin-transform-runtime: 復用babel注入的helper代碼以及提供無污染全局環境的polyfill功能

      基于此,對項目中js語法的transform和API的polyfill進行了調整:

      • 關閉@babel/plugin-transform-runtime的polyfill功能
      • 開啟@babel/preset-env的polyfill和transform功能

      其中,@babel/preset-env的polyfill使用usage形式(不了解的可以查看官方文檔),意思是以項目設置的target環境為前提,根據項目中使用到的api功能進行polyfill;具體babel配置片段如下:

      {
        "plugins": [
          [
            "@babel/plugin-transform-runtime",
            {
              "corejs": false,
              "regenerator": false
            }
          ]
        ],
        "sourceType": "unambiguous",
        "presets": [
          [
            "@babel/preset-env",
            {
              "modules": false,
              "shippedProposals": true,
              "useBuiltIns": "usage",
              "corejs": {
                "version": "3.10",
                "proposals": true
              },
              "targets": {
                  ...
              }
            }
          ]
        ]
      }
      

      然后項目中使用到了Promise.allSettled靜態方法:

      Promise.allSettled([p1, p2, p3]).then(res => console.log(res));
      

      通過webpack打包后運行,js會報錯:

      TypeError: Promise.allSettled is not a function

      不對呀,按照官網就是這么配置的,一度對babel的配置產生懷疑,折騰半天最后都排除掉;沒招了,那就試試斷點調試,別說還真發現問題,直接上圖:

      相信大家能夠看出問題所在,Promise.allSettled的polyfill之后重新引入Promise的polyfill,后面的Promise的polyfill覆蓋了Promise.allSettled的polyfill,導致調用該方法時報錯。

      那會不會是babel的bug導致的呢,于是開起查找問題之旅了。。。

      問題追蹤

      首先,簡要說明下@babel/preset-env實現polyfill的思路:babel會生成代碼的ast,并對其traverse過程中,根據代碼使用的新API來確定需要填充的polyfill。

      遇到這種問題,首先想到會不會是@babel/preset-env的bug,google半天也沒有找到類似問題,于是就開啟debug調試模式。在調試追蹤到babel-plugin-polyfill-corejs3/lib/index.js中的usageGlobal方法,其在解析代碼中使用到了PromiseallSettled的api,如下圖:

      babel會根據代碼用到的api,最終解析出為這些api注入的polyfill,如下圖:

      從圖可以看出最終需要為PromiseallSettled注入的依賴polyfill;但是注入的polyfill存在問題,即es.promisees.promise.all-settled順序反了,后者依賴前者;由此可見是babel的bug已確定無疑了。

      接著進如resolve方法,發現其在確定代碼的相關polyfill依賴后,對與依賴的先后順序存在bug;因為代碼調用Promise.allSettled會依賴:

      • 全局global的Promise api
      • Promise的靜態方法allSettled api

      所以babel在獲取二者對應的polyfill在合并時產生了問題,這可以在babel-plugin-polyfill-corejs/lib/built-in-definitions.js文件中:

      // 所有靜態方法的polyfill
      const StaticProperties = {
          ...
          Promise: {
              all: define(null, PromiseDependenciesWithIterators),
              allSettled: define(null, ["es.promise.all-settled", ...PromiseDependenciesWithIterators]),
              any: define(null, ["esnext.promise.any", ...PromiseDependenciesWithIterators]),
              race: define(null, PromiseDependenciesWithIterators),
              try: define(null, ["esnext.promise.try", ...PromiseDependenciesWithIterators])
            },
        ...
      }
      

      可以看出Promise的相關靜態方法的polyfill都放置到第一位,而define為對該數值進行任何排序:

      const define = (pure, global, name = global[0], exclude) => {
        return {
          name,
          pure,
          global,
          exclude
        };
      };
      

      查到這里可以猜測這個babel-plugin-polyfill-corejs3@0.1.7有bug,查看最新版本0.2.0的代碼發現對這個方法進行了修復:

      var _data = _interopRequireDefault(require("../core-js-compat/data.js"));
      
      const polyfillsOrder = {};
      Object.keys(_data.default).forEach((name, index) => {
        polyfillsOrder[name] = index;
      });
      
      const define = (pure, global, name = global[0], exclude) => {
        return {
          name,
          pure,
          global: global.sort((a, b) => polyfillsOrder[a] - polyfillsOrder[b]),
          exclude
        };
      };
      

      可以看出該方法對注入的polyfill做了排序,進過排序得到正確的依賴順序,于是果斷升級@babel/preset-env@7.13.15,因為之前@babel/preset-env@7.13.10依賴的是babel-plugin-polyfill-corejs3@0.1.7,至此一直困擾我的這個大坑給堵上了。

      出于好奇心,對babel-plugin-polyfill-corejs3代碼進行blame,果然發現這個問題在24天前進行了修復:

      blame.png

      進一步查看發現,之前已經有人提出過類似的bug:The order of promise and promise.finally after compilation seems to be wrong,于是做了修復。

      總結

      困擾我一天的問題算是解決了,分享給大家希望大家避坑。

      不過話說回來,開始遇到這個問題時,換成@babel/preset-enventry模式的polyfill模式不會發生任何問題,但是心中過不去這個坎為啥usage模式不能用,明明后者有一定的體積優勢,最終得到答案;這一過程雖然耗費一定的時間,但是有收獲,值!

      posted @ 2021-04-16 16:12  wonyun  閱讀(3076)  評論(1)    收藏  舉報
      主站蜘蛛池模板: 久久精品夜夜夜夜夜久久| 久久亚洲精品人成综合网| 精品伊人久久久香线蕉| 亚洲欧美牲交| 亚洲精品国产自在现线最新| 无码国内精品久久人妻蜜桃| 国产成人av电影在线观看第一页| 久久国产成人精品国产成人亚洲| 亚洲人成电影网站色mp4| 国产亚洲精品aaaa片app| 欧美老熟妇喷水| 国产成人综合在线观看不卡| 国产一区二区三区不卡观| 少妇精品亚洲一区二区成人| 4虎四虎永久在线精品免费| 黄色免费在线网址| 一个色综合色综合色综合| 国产av一区二区午夜福利| 99RE8这里有精品热视频| 亚洲老妇女亚洲老熟女久| 国产在线观看网址不卡一区 | 成全我在线观看免费第二季| 亚洲欧美日韩在线码| 石楼县| 亚洲国产免费图区在线视频| 中文字幕第55页一区| 国产极品美女高潮无套| 人妻内射视频麻豆| 四虎女优在线视频免费看| 精品人妻少妇一区二区三区| 国产在线观看免费观看不卡| 成人国产精品日本在线观看| 深田えいみ禁欲后被隔壁人妻 | 欧美视频专区一二在线观看| 亚洲熟女乱一区二区三区| 无码熟妇人妻AV在线影片最多| 亚洲av无码精品色午夜蛋壳| 亚洲成a人无码av波多野| 国产不卡av一区二区| 国产精品尤物午夜福利| 国产精品久久久久久av|