babel-runtime 如何縮小打包體積

在這里插入圖片描述

🤖 作者簡介:水煮白菜王,一位前端勸退師 👻
👀 文章專欄: 前端專欄 ,記錄一下平時在博客寫作中,總結出的一些開發技巧和知識歸納總結?。
感謝支持💕💕💕

目錄

    • @babel/preset-env
    • @babel/polyfill
    • babel-runtime
      • 主要功能
      • 補充
    • babel-plugin-transform-runtime
      • 配置
    • 示例
      • 控制引入 babel-runtime
      • 控制 corejs 配置

在前端工程化領域,包體積優化一直是一個備受關注的話題。隨著項目規模擴大和功能迭代,打包后的文件體積逐漸膨脹。而對于網頁加載速度和性能優化來說,減小打包體積是至關重要的一環。
為此,在這篇文章中,將探討如何利用 babel-runtime 這一工具來幫助我們將重復的定義通過模塊導入的方式引入,縮減打包體積以提升項目性能。

Babel 是一個被廣泛使用的 JS 編譯器,用于將新語法轉換為向后兼容的 JS 代碼。一般情況下,我們可以通過安裝預設和插件控制 ****Babel 的代碼轉譯,比如:
預設(Presets 一組預定義的轉換規則的集合)

  1. @babel/preset-env:這是 Babel 官方推薦的預設之一,用于根據目標環境自動確定所需的轉換和 polyfill。
  2. @babel/preset-react:用于支持 React 項目中的 JSX 和其他相關特性的預設。·
  3. @babel/preset-typescript:用于支持 TS 項目中的預設,能夠將 TS 代碼轉換為 JS 代碼。

插件(Plugins 單個轉換規則的集合)
4. @babel/plugin-proposal-class-properties:用于支持 JS 類的屬性初始化器,包括靜態屬性和實例屬性。
5. @babel/plugin-transform-arrow-functions:將箭頭函數轉換為普通函數表達式,以提供更廣泛的兼容性。
6. @babel/plugin-transform-runtime:將 Babel 編譯時注入的輔助函數轉換為引用運行時公共函數的方式,以減小輸出文件的體積。

@babel/preset-env

@babel/preset-env 的主要功能包括:

  • 自動 polyfill:根據目標環境自動導入所需的 polyfill,從而實現對新特性的兼容性支持。

  • 智能轉換:基于目標環境的瀏覽器或 Node 版本來自動轉換 ES6+ 語法或 API。

  • 模塊轉換:支持將模塊轉換為不同類型(CommonJS、AMD、UMD 等)的模塊系統。

  • 按需加載:支持根據需要選擇和加載特定的轉換規則或插件。

使用 @babel/preset-env 的方式也非常簡單,只需要在 .babelrc 或 babel.config.js 中配置該預設即可,下面是一個綜合案例:

{"presets": [["@babel/preset-env",{// 目標環境設置為最近的兩個瀏覽器版本以及 Safari 7 及以上版本"targets": {"browsers": ["last 2 versions", "safari >= 7"]},// 將 ES6 模塊轉換為 CommonJS 模塊"modules": "commonjs",// 啟用按需加載 polyfill 的功能"useBuiltIns": "usage",// 使用 core-js 3 版本的 polyfill"corejs": 3,// 打印詳細的調試信息"debug": true}]]
}

注意:useBuiltIns 控制了 polyfill 的導入方式,用來配合 @babel/polyfill 使用,值得注意的是,官方不再推薦 Babel > 7.4.0 時使用 @babel/polyfill,可以選擇使用 core-js。
更多配置規則請參考:https://babeljs.io/docs/babel-preset-env

@babel/polyfill

從 Babel 7.4.0 開始,這個包已經被棄用,取而代之的是直接包含 core-js/stable
在本地 node_module 中,可以看到 @babel/polyfill 的依賴包含了 core-js 和 regenerator-runtime,可以認為 polyfill 本身就是 core-js + regenerator-runtime。

在這里插入圖片描述
在這里插入圖片描述
從 Babel 7.4.0 開始,我們需要用 core-js 替代 babel-polyfill,而 regenerator-runtime 會在安裝 @babel/runtime 時被依賴安裝,因此不用額外安裝。

babel-runtime

babel-runtime 是一個由 Babel 提供的運行時庫,它包括了一些在編譯過程中需要用到的輔助函數和類,例如 ES6/ES7 語法的 polyfill、generator 函數的處理、Promise 的實現等。

主要功能

babel-runtime 的實現主要功能有兩點:

  1. 將轉譯中需要的helper 函數從一個模塊中引入,避免重復定義、減小打包體積

下面是一些常見的輔助函數和類的實現:

  • classCallCheck:用于實現 ES6 類的構造函數中的類檢查。它會檢查是否使用 new 關鍵字來調用類,并在沒有正確調用的情況下拋出錯誤。
  • defineEnumerableProperties:用于定義對象的可枚舉屬性。它接受一個對象和一組屬性描述符,并將這些屬性添加到對象中,并確保它們是可枚舉的。
  • extends:用于實現 ES6 類繼承的輔助函數。它會創建一個新的子類,并確保正確設置原型鏈和構造函數。
  • asyncToGenerator:用于將 generator 函數轉換為基于 Promise 的異步函數的輔助函數。它接受一個 generator 函數并返回一個新的函數,該函數可以像普通的異步函數一樣被調用。
  • regeneratorRuntime:用于支持 generator 函數的運行時庫。它提供了 generator 函數所需的運行時環境,包括狀態機、迭代器和 Promise 的支持。
  1. 開發類庫/工具時,避免生產污染全局空間的方法。

在一個項目中,我們定義了一個 Array 原型鏈上的方法(比如 Array.includes()),項目依賴 babel-polyfill 實現轉譯。此時,項目引入一個依賴,調用的方法需要使用 Array.includes(),那么在打包時,由于 polyfill 導入于全局環境,就會出現沖突,導致出錯。
解決方案就是用 babel-runtime 處理全局內置對象,將其模塊化,并通過模塊導入的方式引入。

補充

然而 @babel/runtime 沒有支持實例方法,只能通過配置 corejs ,使用 babel/runtime-corejs@x
控制相關 polyfill 的引入,然而 core-js2 的 polyfill 覆蓋范圍相對較小,以下陳列了相關包的區別:

  • @babel/polyfill:core-js + regenerator-runtime,Babel 7.4.0后棄用。
  • @babel/runtime:Babel 默認的運行時依賴模塊,提供相關 helpers 函數和regenerator-runtime,不包含任何 polyfill 功能。
  • @babel/runtime-corejs2:基于 @babel/runtime ,提供了 core-js2 支持部分 polyfill。
  • @babel/runtime-corejs3:基于 @babel/runtime ,提供了 core-js3 支持更廣泛的 polyfill。

babel-plugin-transform-runtime

需要注意的是,babel-runtime 只是一個工具庫,需要和 babel-plugin-transform-runtime 配合使用。
babel-plugin-transform-runtime 可以讓 Babel 在編譯過程中, 引用模塊 @babel/runtime提供一些輔助函數和類 ,從而避免在編譯后的代碼中重復出現相同的代碼。

配置

首先,安裝相關包。

npm install --save-dev @babel-plugin-transform-runtime
npm install --save @babel-runtime

其次在 .babelrc 或 babel.config.js 中配置 @babel/plugin-transform-runtime ****插件,corejs 配置項控制是否引入 core-js 或 core-js 的版本。

{"presets": [["@babel/preset-env"],],"plugins": [["@babel/plugin-transform-runtime", {"corejs": false // 可選 false | 2 | 3}]]
}
名稱類型作用使用場景
@babel/preset-envpreset根據目標環境自動確定需要的轉換規則和 polyfill現代 JS 代碼轉換兼容老版本瀏覽器/環境
@babel/polyfill (已廢棄)polyfill提供完整的 ES6+ 環境補丁 (包含 core-js 和 regenerator-runtime)全局注入 polyfill (Babel 7.4+ 推薦直接使用 core-js 和 regenerator-runtime)
babel-runtime (舊版本)運行時依賴提供編譯時的工具函數和 regenerator-runtime配合 transform-runtime 插件減少代碼重復 (已被 @babel/runtime 取代)
babel-plugin-transform-runtime插件自動替換 helper 函數為 runtime 引用,并可配置 core-js 按需 polyfill開發庫時避免污染全局環境,減少代碼體積

接下來我們可以通過觀察不同 corejs 配置和是否引入 babel-runtime 打包的結果理解一下作用。

示例

控制引入 babel-runtime

轉譯代碼:

class Animal {}

接下來我們通過修改是否啟用 babel-plugin-transform-runtime 控制 babel-runtime 的引入:

// 不引入 babel-runtime
function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
var Animal = /*#__PURE__*/_createClass(function Animal() {_classCallCheck(this, Animal);
});// 引入 babel-runtime,corejs:false
/* harmony import */ var _babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime/helpers/createClass */ "./node_modules/.pnpm/@babel+runtime@7.23.9/node_modules/@babel/runtime/helpers/esm/createClass.js");
/* harmony import */ var _babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime/helpers/classCallCheck */ "./node_modules/.pnpm/@babel+runtime@7.23.9/node_modules/@babel/runtime/helpers/esm/classCallCheck.js");var Animal = /*#__PURE__*/(0,_babel_runtime_helpers_createClass__WEBPACK_IMPORTED_MODULE_0__["default"])(function Animal() {(0,_babel_runtime_helpers_classCallCheck__WEBPACK_IMPORTED_MODULE_1__["default"])(this, Animal);
});

可以看到 babel-runtime 是通過引入模塊實現 class 的,避免了多文件時定義了多個工具函數,有效減少了打包體積。

控制 corejs 配置

轉譯代碼

new Promise();
string.trimStart()

為體現 corejs 的差異,我們使用兩種實例方法 Promise、String.trimStart() 進行對比。

// corejs:false
new Promise();
string.trimStart();// corejs:2
/* harmony import */ var _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime-corejs2/core-js/promise */ "./node_modules/.pnpm/@babel+runtime-corejs2@7.23.9/node_modules/@babel/runtime-corejs2/core-js/promise.js");
/* harmony import */ var _babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0__);new (_babel_runtime_corejs2_core_js_promise__WEBPACK_IMPORTED_MODULE_0___default())();
string.trimStart();// corejs:3
/* harmony import */ var _babel_runtime_corejs3_core_js_stable_promise__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! @babel/runtime-corejs3/core-js-stable/promise */ "./node_modules/.pnpm/@babel+runtime-corejs3@7.23.9/node_modules/@babel/runtime-corejs3/core-js-stable/promise.js");
/* harmony import */ var _babel_runtime_corejs3_core_js_stable_promise__WEBPACK_IMPORTED_MODULE_0___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs3_core_js_stable_promise__WEBPACK_IMPORTED_MODULE_0__);
/* harmony import */ var _babel_runtime_corejs3_core_js_stable_instance_trim_start__WEBPACK_IMPORTED_MODULE_1__ = __webpack_require__(/*! @babel/runtime-corejs3/core-js-stable/instance/trim-start */ "./node_modules/.pnpm/@babel+runtime-corejs3@7.23.9/node_modules/@babel/runtime-corejs3/core-js-stable/instance/trim-start.js");
/* harmony import */ var _babel_runtime_corejs3_core_js_stable_instance_trim_start__WEBPACK_IMPORTED_MODULE_1___default = /*#__PURE__*/__webpack_require__.n(_babel_runtime_corejs3_core_js_stable_instance_trim_start__WEBPACK_IMPORTED_MODULE_1__);new (_babel_runtime_corejs3_core_js_stable_promise__WEBPACK_IMPORTED_MODULE_0___default())();
_babel_runtime_corejs3_core_js_stable_instance_trim_start__WEBPACK_IMPORTED_MODULE_1___default()(string).call(string);

依據結果可以看出,
corejs: false 只對ES語法進行了轉換。
corejs:2 為我們的代碼創建了一個沙盒環境,避免了全局空間污染。
corejs: 3 在 corejs: 2的基礎上加入了新的 polyfill 以處理更多的實例方法。
由此總結,對于 Babel < 7.4.0 時,類庫/工具項目應選擇 @babel/runtime,其他項目選擇 @babel/polyfill,當 Babel >= 7.4.0 時,一律使用 @babel/runtime。

在這里插入圖片描述
如果你覺得這篇文章對你有幫助,請點贊 👍、收藏 👏 并關注我!👀
在這里插入圖片描述

本文來自互聯網用戶投稿,該文觀點僅代表作者本人,不代表本站立場。本站僅提供信息存儲空間服務,不擁有所有權,不承擔相關法律責任。
如若轉載,請注明出處:http://www.pswp.cn/diannao/77003.shtml
繁體地址,請注明出處:http://hk.pswp.cn/diannao/77003.shtml
英文地址,請注明出處:http://en.pswp.cn/diannao/77003.shtml

如若內容造成侵權/違法違規/事實不符,請聯系多彩編程網進行投訴反饋email:809451989@qq.com,一經查實,立即刪除!

相關文章

劍指Offer(數據結構與算法面試題精講)C++版——day7

劍指Offer&#xff08;數據結構與算法面試題精講&#xff09;C版——day7 題目一&#xff1a;最多刪除一個字符得到回文題目二&#xff1a;回文子字符串的個數題目三&#xff1a;刪除倒數第k個節點 題目一&#xff1a;最多刪除一個字符得到回文 這里我們可以在經典的字符串回文…

2025年常見滲透測試面試題(題目+回答)

網絡安全領域各種資源&#xff0c;學習文檔&#xff0c;以及工具分享、前沿信息分享、POC、EXP分享。不定期分享各種好玩的項目及好用的工具&#xff0c;歡迎關注。 目錄 常見面試題 一、滲透測試經歷與技術復盤 二、高頻漏洞類型與攻防體系 三、滲透工具鏈與技術特性 四、…

大數據與人工智能之大數據架構(Hadoop、Spark、Flink)

一、核心特性與架構設計 1. Hadoop&#xff1a;分布式批處理的基石 核心組件&#xff1a; HDFS&#xff1a;分布式文件系統&#xff0c;支持大規模數據存儲。MapReduce&#xff1a;基于“分而治之”的批處理模型&#xff0c;適合離線分析。 架構特點&#xff1a; 批處理主導&…

從IoT到AIoT:智能邊界的拓展與AI未來趨勢預測

文章目錄 引言&#xff1a;從連接萬物到感知萬物1. AIoT的本質&#xff1a;將智能嵌入萬物2. AIoT的推動力量與挑戰2.1 推動力量2.2 關鍵挑戰 3. 五大AIoT未來趨勢預測趨勢一&#xff1a;邊緣智能將成為主流架構趨勢二&#xff1a;AI模型將向自適應與多任務演進趨勢三&#xff…

從本地新建文件夾到拉取遠程倉庫 dev 分支的完整步驟

《從本地新建文件夾到拉取遠程倉庫 dev 分支的完整步驟》 下面為你詳細介紹從本地新建文件夾開始&#xff0c;將遠程倉庫的 dev 分支拉取到本地的具體步驟&#xff1a; 1. 創建新文件夾 在本地電腦上新建一個文件夾&#xff0c;作為存放項目代碼的目錄。你可以通過圖形界面操…

python/pytorch雜聊

Dataset 是否需要自己定義&#xff1a;如果你使用的數據集不是 PyTorch 提供的標準數據集&#xff08;如 MNIST、CIFAR-10 等&#xff09;&#xff0c;那么你需要繼承 torch.utils.data.Dataset 類并實現兩個方法&#xff1a;__len__() 和 __getitem__()。__len__() 應該返回數…

PHP 安全 E-mail

PHP 安全 E-mail 引言 隨著互聯網的普及和電子商務的發展,電子郵件成為了人們日常生活中不可或缺的通信工具。PHP作為一種廣泛使用的服務器端腳本語言,也經常被用于發送和接收電子郵件。然而,在PHP中處理電子郵件時,安全性問題不容忽視。本文將深入探討PHP安全發送電子郵…

【夜話系列】DelayQueue延遲隊列(下):實戰應用與面試精講

?? 本文是DelayQueue系列的下篇,聚焦實戰應用場景和性能優化。通過多個真實案例,帶你掌握DelayQueue在項目中的最佳實踐和性能調優技巧。 ?? 系列專欄推薦: JAVA集合專欄 【夜話集】JVM知識專欄數據庫sql理論與實戰小游戲開發文章目錄 一、DelayQueue實戰應用1.1 訂單超…

Redis(筆記)

簡介&#xff1a; 常用數據類型: 常用操作命令&#xff1a; Redis的Java客戶端&#xff1a; 操作字符串類型的數據&#xff1a; 操作Hash類型的數據&#xff1a; 操作列表類型的數據&#xff1a; 操作集合類型的數據&#xff1a; 操作有序集合類型數據&#xff1a; 通用命令…

PhotoShop學習05

1.選區基礎知識 選區&#xff0c;就是選定一些區域&#xff0c;我們對圖片的更改只在選區內生效&#xff0c;這樣可以精細調整圖片的部分而不會影響整體。它的快捷鍵是M。 我們用點擊鼠標后滑動就會出現虛線框&#xff0c;虛線框內的就是我們選定的區域。這時我們再滑動就會創…

使用Redission實現分布式鎖

分布式鎖在分布式系統中非常重要&#xff0c;主要用于解決多個進程/服務并發訪問共享資源時的數據一致性問題。在日常開發中常用于&#xff1a; 1. 防止重復操作&#xff08;冪等性控制&#xff09; 場景&#xff1a;用戶重復提交訂單、重復支付、重復點擊等。 示例&#xff1…

VScode 畫時序圖(FPGA)

1、先安裝插件&#xff1a; 2、然后就可以編寫一個.js文件&#xff0c;如下&#xff1a; {signal: [{name: clk, wave: p.......|..},{name: rstn, wave: 01......|..},{name: din_vld, wave: 0.1.0...|..},{name: din, wave: "x.x...|..", data: ["D0", …

嵌入式學習筆記——I2C

IIC協議詳解 一、IIC協議簡介二、IIC總線結構圖三、IIC通信流程詳解1. 空閑狀態 : 雙高空閑2. 起始信號&#xff08;START&#xff09;: 時高數下開始3. 停止信號&#xff08;STOP&#xff09;: 時高數上結束4. 數據傳輸格式 : 時高數穩&#xff0c;時低數變5. 應答信號 四、寫…

Apifox Helper 與 Swagger3 區別

核心定位差異 Apifox Helper 定位&#xff1a;基于 IDEA 的代碼注釋解析工具&#xff0c;與 Apifox 平臺深度集成&#xff0c;實現文檔自動生成接口管理測試協作的一體化流程。 特點&#xff1a; 通過解析 Javadoc、KDoc 等注釋生成文檔&#xff0c;代碼零侵入&#xff08;無…

單片機實現多線程的方法匯總

在單片機上實現“多線程”的方法有幾種&#xff0c;下面按照從簡單到復雜、從輕量到系統性來列出常見的方案&#xff1a; &#x1f9f5; 一、偽多線程&#xff08;最輕量&#xff09; 方法&#xff1a;主循環 狀態機 / 定時器輪詢 主循環中輪流調用各個任務的處理函數&#x…

網絡:華為數通HCIA學習:靜態路由基礎

文章目錄 前言靜態路由基礎靜態路由應用場景 靜態路由配置靜態路由在串行網絡的配置靜態路由在以太網中的配置 負載分擔配置驗證 路由備份&#xff08;浮動靜態路由&#xff09;配置驗證 缺省路由配置驗證 總結 華為HCIA 基礎實驗&#xff0d;靜態路由 & eNSP靜態路由 基礎…

[項目總結] 在線OJ刷題系統項目技術應用(下)

&#x1f338;個人主頁:https://blog.csdn.net/2301_80050796?spm1000.2115.3001.5343 &#x1f3f5;?熱門專欄: &#x1f9ca; Java基本語法(97平均質量分)https://blog.csdn.net/2301_80050796/category_12615970.html?spm1001.2014.3001.5482 &#x1f355; Collection與…

Qt音頻輸出:QAudioOutput詳解與示例

1. 簡介 QAudioOutput是Qt多媒體框架中的一個關鍵類&#xff0c;它提供了將PCM&#xff08;脈沖編碼調制&#xff09;原始音頻數據發送到音頻輸出設備的接口。作為Qt多媒體組件的一部分&#xff0c;QAudioOutput允許開發者在應用程序中實現音頻播放功能&#xff0c;支持多種音…

【計算機網絡】Linux配置SNAT/DNAT策略

什么是NAT&#xff1f; NAT 全稱是 Network Address Translation&#xff08;網絡地址轉換&#xff09;&#xff0c;是一個用來在多個設備共享一個公網 IP上網的技術。 NAT 的核心作用&#xff1a;將一個網絡中的私有 IP 地址&#xff0c;轉換為公網 IP 地址&#xff0c;從而…

Redis淘汰策略詳解!

目錄 一、為什么需要淘汰策略&#xff1f; &#x1f914;二、Redis 的淘汰策略詳解 &#x1f447;三、如何選擇合適的淘汰策略&#xff1f; &#x1f914;???四、如何切換 Redis 的淘汰策略&#xff1f; ??&#x1f527;五、總結 &#x1f389; &#x1f31f;我的其他文章…