1. <strong id="7actg"></strong>
    2. <table id="7actg"></table>

    3. <address id="7actg"></address>
      <address id="7actg"></address>
      1. <object id="7actg"><tt id="7actg"></tt></object>

        Babel7 相關(guān)

        共 6429字,需瀏覽 13分鐘

         ·

        2021-03-16 13:18

        作者:蘋(píng)果小蘿卜
        來(lái)源:SegmentFault 思否社區(qū)




        @babel/preset-env


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


        基本的配置方法:


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


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


        相關(guān) options 配置


        useBuiltIns


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


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


        因?yàn)閺?nbsp;@babel/polyfill 從 7.4.0 版本開(kāi)始就被棄用了,因此推薦直接配置 corejs 選項(xiàng),并在項(xiàng)目當(dāng)中直接安裝 core-js。


        useBuiltIns: 'entry'


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


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


        在 babel 處理代碼的過(guò)程當(dāng)中,會(huì)引入一個(gè)新的插件,同時(shí) @babel/preset-env 會(huì)根據(jù)目標(biāo)平臺(tái),例如 target 當(dāng)中的配置,或者是 .browserlistrc 等來(lái)引入對(duì)應(yīng)平臺(tái)所需要的 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"


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


        同時(shí)在使用的過(guò)程中,如果是 import 'core-js' 那么在處理的過(guò)程當(dāng)中會(huì)引入所有的 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)探測(cè)代碼當(dāng)中使用的新的特性,并結(jié)合目標(biāo)平臺(tái)來(lái)決定引入對(duì)應(yīng)新特性的 polyfill,因此這個(gè)配置是會(huì)最大限度的去減少引入的 polyfill 的數(shù)量來(lái)保證最終生成的 bundler 體積大小。


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


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


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


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




        @babel/plugin-transform-runtime


        出現(xiàn)的背景:


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


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


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


        這個(gè)插件所做的工作其實(shí)也是引用 core-js 相關(guān)的模塊來(lái)完成 polyfill 的功能。最終所達(dá)到的效果和使用 @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,實(shí)例上的方法是是不支持的,例如 [].includes。不過(guò) corejs: 3 是支持實(shí)例上的方法的。


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



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



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

        - END -


        瀏覽 47
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        評(píng)論
        圖片
        表情
        推薦
        點(diǎn)贊
        評(píng)論
        收藏
        分享

        手機(jī)掃一掃分享

        分享
        舉報(bào)
        1. <strong id="7actg"></strong>
        2. <table id="7actg"></table>

        3. <address id="7actg"></address>
          <address id="7actg"></address>
          1. <object id="7actg"><tt id="7actg"></tt></object>
            操逼1级片 | 亚洲韩国精品 | 喝人奶电影三级 | 啪啪啪网站免费观看 | 成人门 性视频免费站 | 国产蜜臀97一区二区三区 | 欧美性猛交free性丰满 | 一级电影免费观看 | 丰满双乳峰白嫩少妇 | 瑟瑟网 |