<kbd id="afajh"><form id="afajh"></form></kbd>
<strong id="afajh"><dl id="afajh"></dl></strong>
    <del id="afajh"><form id="afajh"></form></del>
        1. <th id="afajh"><progress id="afajh"></progress></th>
          <b id="afajh"><abbr id="afajh"></abbr></b>
          <th id="afajh"><progress id="afajh"></progress></th>

          Babel7 相關(guān)

          共 6429字,需瀏覽 13分鐘

           ·

          2021-03-16 13:18

          作者:蘋果小蘿卜
          來源:SegmentFault 思否社區(qū)




          @babel/preset-env


          @babel/preset-env 主要的功能是依據(jù)項目經(jīng)過 babel 編譯構(gòu)建后產(chǎn)生的代碼所對應(yīng)運行的目標(biāo)平臺。@babel/preset-env 內(nèi)部依賴了很多插件: @babel/plugin-transform-*。這些插件的工作主要就是 babel 在處理代碼的過程當(dāng)中對于新的 ES 語法的轉(zhuǎn)換,將高版本的語法轉(zhuǎn)化為低版本的寫法。例如 @babel/plugin-transform-arrow-function 是用來轉(zhuǎn)化箭頭函數(shù)語法的。


          基本的配置方法:


          // babel.config.json
          {
            "presets": [
              [
                "@babel/preset-env",
                {
                  // 相關(guān) preset 的配置
                }
              ]
            ]
          }


          對于 web 側(cè)的項目或者 基于 Electron 的項目,一般會搭配著 .browserlistrc (或 package.json 里的 browserslist 字段) 來使用(確定最終構(gòu)建平臺)。


          相關(guān) options 配置


          useBuiltIns


          "usage" | "entry" | false, defaults to false.


          這個配置選項也決定了 @babel/preset-env 如何去引用 polyfills。當(dāng)這個配置選項為:usage 或 entry,@babel/preset-env 會直接建立起對于 core-js 相關(guān) module 的引用。因此這也意味著 core-js 會被解析為對應(yīng)的相對路徑同時需要確保 core-js 在你的項目當(dāng)中已經(jīng)被安裝了。


          因為從 @babel/polyfill 從 7.4.0 版本開始就被棄用了,因此推薦直接配置 corejs 選項,并在項目當(dāng)中直接安裝 core-js。


          useBuiltIns: 'entry'


          使用這種方式的配置需要在你的業(yè)務(wù)代碼當(dāng)中注入:


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


          在 babel 處理代碼的過程當(dāng)中,會引入一個新的插件,同時 @babel/preset-env 會根據(jù)目標(biāo)平臺,例如 target 當(dāng)中的配置,或者是 .browserlistrc 等來引入對應(yīng)平臺所需要的 polyfill :


          In:


          import 'core-js'


          Out(different based on environment):


          import "core-js/modules/es.string.pad-start"
          import "core-js/modules/es.string.pad-end"


          注:其實這里的 useBuiltIns: entry 的配置以及需要在業(yè)務(wù)代碼當(dāng)中需要注入 core-js和 regenerator-runtime/runtime,在業(yè)務(wù)代碼當(dāng)中注入對應(yīng)的 package 從使用上來講更多的是起到了占位的作用,由 @babel/preset-env 再去根據(jù)不同的目標(biāo)平臺去引入對應(yīng)所需要的 polyfill 文件


          同時在使用的過程中,如果是 import 'core-js' 那么在處理的過程當(dāng)中會引入所有的 ECMAScript 特性的 polyfill,如果你只希望引入部分的特性,那么可以:


          In:


          import 'core-js/es/array'
          import 'core-js/proposals/math-extensions'


          Out:


          import "core-js/modules/es.array.unscopables.flat";
          import "core-js/modules/es.array.unscopables.flat-map";
          import "core-js/modules/esnext.math.clamp";
          import "core-js/modules/esnext.math.deg-per-rad";
          import "core-js/modules/esnext.math.degrees";
          import "core-js/modules/esnext.math.fscale";
          import "core-js/modules/esnext.math.rad-per-deg";
          import "core-js/modules/esnext.math.radians";
          import "core-js/modules/esnext.math.scale";


          useBuiltIns: 'usage'


          自動探測代碼當(dāng)中使用的新的特性,并結(jié)合目標(biāo)平臺來決定引入對應(yīng)新特性的 polyfill,因此這個配置是會最大限度的去減少引入的 polyfill 的數(shù)量來保證最終生成的 bundler 體積大小。


          不過需要注意的是:由于 babel 處理代碼本來就是一個非常耗時的過程,因此在我們實際的項目當(dāng)中一般是對于 node_modules 當(dāng)中的 package 進行 exclude 配置給忽略掉的,除非是一些明確需要走項目當(dāng)中的 babel 編譯的 package 會單獨的去 include,所以 useBuiltIns: 'usage' 這種用法的話有個風(fēng)險點就是 node_modules 當(dāng)中的第三方包在實際的編譯打包處理流程當(dāng)中沒有被處理(例如有些 package 提供了 esm 規(guī)范的源碼,同時 package.json 當(dāng)中也配置了 module 字段,那么例如使用 webpack 這樣的打包工具的話會引入 module 字段對應(yīng)的入口文件)


          同時,如果使用 useBuiltIns: 'usage' 配置的話。是會在每個文件當(dāng)中去引入相關(guān)的 polyfill 的,所以這里如果不借助 webpack 這種打包工具的話,是會造成代碼冗余的。


          useBuiltIns: false


          Don't add polyfills automatically per file, and don't transform import "core-js" or import "@babel/polyfill" to individual polyfills.


          corejs


          corejs 的配置選項需要搭配著 useBuiltIns: usage 或 useBuiltIns: entry 來使用。默認(rèn)情況下,被注入的 polyfill 都是穩(wěn)定的已經(jīng)被納入 ECMAScript 規(guī)范當(dāng)中的特性。如果你需要使用一些 proposals 當(dāng)中的 feature 的話,那么需要配置:


          {
            "presets": [
              [
                "@babel/preset-env",
                {
                  // 相關(guān) preset 的配置
                  corejs: {
                    version: 3,
                    proposals: true
                  }
                }
              ]
            ]
          }




          @babel/plugin-transform-runtime


          出現(xiàn)的背景:


          Babel 在編譯處理代碼的過程當(dāng)中會使用一些 helper 輔助函數(shù),例如 _extend。這些輔助函數(shù)一般都會被添加到每個需要的被處理的文件當(dāng)中。


          因此 @babel/plugin-transform-runtime 所要解決的問題就是將所有對于需要這些 helper 輔助函數(shù)的引入全部指向 @babel/runtime/helpers 這個 module 當(dāng)中的輔助函數(shù),而不是給每個文件都添加對應(yīng) helper 輔助函數(shù)的內(nèi)容。


          另外一個目的就是去創(chuàng)建一個沙盒環(huán)境。因為如果你直接引入 core-js,或者 @babel/polyfill 的話,它所提供的 polyfill,例如 Promise,Set,Map 等,是直接在全局環(huán)境下所定義的。因此會影響到所有使用到這些 API 的文件內(nèi)容。所以如果你是寫一個 library 的話,最好使用 @babel/plugin-transform-runtime 來完成相關(guān) polyfill 的引入,這樣能避免污染全局環(huán)境。


          這個插件所做的工作其實也是引用 core-js 相關(guān)的模塊來完成 polyfill 的功能。最終所達到的效果和使用 @babel/polyfill 是一樣的。


          配置方法:


          {
            "plugins": [
              [
                "@babel/plugin-transform-runtime",
                {
                  "corejs": 3
                }
              ]
            ]
          }


          The plugin defaults to assuming that all polyfillable APIs will be provided by the user. Otherwise the corejs option needs to be specified.


          需要注意的是不同 corejs 版本提供的 helpers 有一些功能上的差異:corejs: 2 僅支持全局的定義,例如 Promise,和一些靜態(tài)方法,例如 Array.from,實例上的方法是是不支持的,例如 [].includes。不過 corejs: 3 是支持實例上的方法的。


          默認(rèn)情況下,@babel/plugin-transform-runtime 是不會引入對于 proposals 的 polyfill 的,如果你是使用 corejs: 3 的話,可以通過配置 proposal: true 來開啟這個功能。



          技術(shù)實現(xiàn)細節(jié)


          The transform-runtime transformer plugin does three things:


          1. Automatically requires @babel/runtime/regenerator when you use generators/async functions (toggleable with the regenerator option).
          2. Can use core-js for helpers if necessary instead of assuming it will be polyfilled by the user (toggleable with the corejs option)
          3. Automatically removes the inline Babel helpers and uses the module @babel/runtime/helpers instead (toggleable with the helpers option).

          What does this actually mean though? Basically, you can use built-ins such as Promise, Set, Symbol, etc., as well use all the Babel features that require a polyfill seamlessly, without global pollution, making it extremely suitable for libraries.



          Some tips


          1. 如果使用 @babel/preset-env 走 useBuiltIns: usage 搭配 browserlist 的這種 polyfill 的方式的話,polyfill 是會污染全局的(entry 模式也是污染全局)。不過這種配置的方式會依據(jù)目標(biāo)打包平臺來一定程度上減少不需要被加入到編譯打包流程的 polyfill 的數(shù)量,因此這種方式也對應(yīng)的能較少 bundle 最終的體積大小。
          2. 如果是走 @babel/plugin-transform-runtime 插件的 polyfill 的話不會污染全局。但是這個插件沒法利用 browserlist 的目標(biāo)平臺配置的策略。因此在你代碼當(dāng)中只要是使用了 ES6+ 的新 api,一律都會引入對應(yīng)的 polyfill 文件(而不考慮這個新的 api 是否被目標(biāo)瀏覽器已經(jīng)實現(xiàn)了),這樣也會造成 bundle 體積增大。針對這個問題,官方也嘗試提供一個新的 babel-polyfills package,以及策略去解決類似的問題。詳見對應(yīng)的文檔以及issue



          點擊左下角閱讀原文,到 SegmentFault 思否社區(qū) 和文章作者展開更多互動和交流,掃描下方”二維碼“或在“公眾號后臺回復(fù)“ 入群 ”即可加入我們的技術(shù)交流群,收獲更多的技術(shù)文章~

          - END -


          瀏覽 47
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          評論
          圖片
          表情
          推薦
          點贊
          評論
          收藏
          分享

          手機掃一掃分享

          分享
          舉報
          <kbd id="afajh"><form id="afajh"></form></kbd>
          <strong id="afajh"><dl id="afajh"></dl></strong>
            <del id="afajh"><form id="afajh"></form></del>
                1. <th id="afajh"><progress id="afajh"></progress></th>
                  <b id="afajh"><abbr id="afajh"></abbr></b>
                  <th id="afajh"><progress id="afajh"></progress></th>
                  国产极品人妖ts91热爆 | 天堂网www在线资源网 | 国产操b电影网站在线观看 | 操逼黄色电影 | av777|