摘要:在做項目中一直使用的是腳手架搭建的環境,一直沒有仔細的去了解這一工具,這周末抽出一天時間通過官網還有各種博客文章算是了解了一些內容,起碼可以在項目中自己完成的配置了。不過好像目前瀏覽器端對這種諸如之類的方法支持的還不錯了。
在做項目中一直使用的是腳手架搭建的環境,一直沒有仔細的去了解 babel 這一工具,這周末抽出一天時間通過官網還有各種博客文章算是了解了一些內容,起碼可以在項目中自己完成 .babelrc 的配置了。
這篇文章就是把自己的理解和找到的優秀文章的內容做一融合和整理,理解有誤的地方還請大家批評指正~
因為主要是面對項目,所以本文內容主要還是圍繞 .babelrc 展開,與babel 相關的其他工具無關。
Babel 是什么?Babel is a toolchain that is mainly used to convert ECMAScript 2015+ code into a backwards compatible version of JavaScript in old browsers or environments.
由于瀏覽器對 ECMAScript 的支持各有差異,因此 Babel 是一個用來將 ES6 版本以上代碼轉為 ES5 版本代碼的工具,從而使得編寫的代碼可以在指定的環境下運行。
.babelrc 配置文件在項目中我們使用 Babel 做轉碼一般使用配置文件的形式。Babel 的配置文件名為 .babelrc 并且通常放在項目根路徑下,其格式大致如下:
{ "env": { "production": { "presets": [], // 轉碼規則 "plugins": [], // 插件 "ignore": ["node_modules/"] // 轉碼時候忽略的文件 } } }
這里的 env 的值取得是項目中的 process.env.BABEL_ENV 如果該值找不到,則取 process.env.NODE_ENV 最后如果該值還找不到,則設為 development
處理順序plugins 優先于 presets
plugins 從數組第一個到最后一個進行編譯
presets 從數組最后一個到第一個進行編譯 ,這個目的主要為了向后降級
presetspresets 用于設置轉碼的規則,常用的 presets 有 env 和 stage-x
關于 env 后文會提到,先來看看 stage-x
stage-x 是新特性納入標準所經過的幾個階段,x 值越小,表示階段越靠后,靠后的階段包含前面的所有內容,即 stage-0 包含 stage-1/2/3 的所有內容
上圖是 stage-2 的 index.js 文件,可以看到其中直接引用了 stage-3 的所有特性。
實際上來說,presets 就是 plugins 的集合,如果沒有 preset 也是可以完成代碼轉換工作的,如下。
{ "plugins": [ "check-es2015-constants", "es2015-arrow-functions" ] }
但是由于這么配置過于繁瑣,因此 Babel 把一些屬于同一標準的 transform-plugins 劃歸到一個 presets 中,這樣有了 presets 就不用再一個一個地導入 transform-plugins 了。
babel-polyfill & babel-runtimeBabel 默認只轉換 JS 語法,而不轉換新的 API ,新標準中的全局對象和定義在這些全局對象上的方法都不會轉碼,這些 API 很多,具體參考 definitions.js
這就導致了 babel-polyfill 和 babel-runtime 的產生
babel-polyfill把所有的 polyfill 一次性全部引入,不管你在項目中是否真正用到
污染全局對象,可能引發沖突。如果你開發的是一個應用項目,那么這一點可以暫時忽略,但是如果你開發的是一款插件或者別人將來引入的包,那么很有可能會給使用者帶來不便
因為需要在自己的代碼之前運行這些 polyfill 所以該包應該被添加到 dependency
與 webpack 結合使用時候需要放在 entry 數組中 entry: ["babel-polyfill", "app.js"]
babel-runtime與 babel-polyfill 的一次性引入不同,babel-runtime 支持自己手動引入 helper 函數,來完成對某一 API 的轉碼。它更像是一個個分散的 polyfill 模塊。
顯而易見 babel-runtime 的缺點之一就是每次使用 API 的時候,都需要我們進行手動引入,很麻煩;此外,在代碼中直接引入 helper 函數,會導致打包的文件中出現很多重復 helper 代碼。因此現在實際工作中會使用 babel-runtime + babel-plugin-transform-runtime 的形式
babel-plugin-transform-runtime這個包可以幫我們完成 babel-runtime 中 helper 函數的自動引入,并且它還做了公用方法的抽離,你引入的函數都是引用自一個地方,就避免了重復的代碼
該包依賴 babel-runtime ,這也是為什么我們在使用 webpack 配置 babel 的時候,只需要安裝 babel-plugin-transform-runtime 的原因,
即 devDependencies 里只看見了 babel-plugin-transform-runtime
該插件主要做了三件事:
當你使用 generators/async 方法、函數時自動調用 babel-runtime/regenerator
當你使用 ES6 的 Map 或者內置的東西時自動調用 babel-runtime/core-js
移除內聯 babel helpers 并替換使用 babel-runtime/helpers 來替換
優點不會污染全局變量
多次使用只打包一次
依賴按需引入,無重復引入
適合編寫庫類型的代碼
缺點不支持實例化的方法 "foobar".includes("foo") 不能轉化
配置一般直接默認就行,不需要對該插件進行配置
{ "plugins": [ ["transform-runtime", { "polyfill": true, // 是否把新特性轉換為非全局的 polyfill "helpers": true, // 是否用模塊中的 helpers 替換內聯 helpers "regenerator": true, // 是否把生成器函數轉換為非全局的 polyfill "moduleName": "babel-runtime" // 導入 helpers 的時候的模塊路徑 }] ] }一次小測試
.babelrc
轉碼前的 a.js
轉碼后的 a-compiled.js
可以看到實例方法 "foo".includes("f") 并沒有被轉換
再來一個小測試.babelrc
轉碼前的 b.js
使用 babel 轉碼后,Set 轉碼成功,并且可以看到在轉碼后的文件中,打印的并不是原生的 Set ,而是 babel 為我們包裝的一個替代原生 Set 的模塊,避免了全局污染。
當我們把 .babelrc 中改為 polyfill: false 時,再次對 b.js 轉碼,轉碼后,語句沒有被處理。打印的就是原生的 Set ,污染了全局變量。
如果需要對實例方法進行轉碼,可以這么來,當然你需要在 .babelrc 里改為 polyfill: true ,不然沒有這個 polyfill 根本沒有這些方法。
轉碼前:
轉碼后:
如果非要在不支持的環境下使用實例方法的話,就還得借助 babel-polyfill 了(或者你自己實現一個)。不過好像目前瀏覽器端對這種諸如 includes 、repeat 之類的方法支持的還不錯了。
babel-preset-envWithout any configuration options, babel-preset-env behaves exactly the same as babel-preset-latest (or babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017 together).
首先官網上給了公式
沒有任何配置的 env = latest = es2015 + es2016 + es2017
babel-preset-env 由于其靈活的配置和全面的功能,被官網推薦,同時也是目前應用很頻繁的 presets
配置項 targets提供需要支持的環境信息,版本等,默認為 {}
spec通過犧牲轉換時間來支持該 preset 的更多規范兼容性,默認為 false
loose為 preset 中的插件開啟松散轉換
松散模式優點:轉換的代碼更加簡潔,沒有為了接近 ES6 而添加的繁雜邏輯,文件更小,運行速度更快,兼容性更好
缺點:直接使用原生 ES6 可能會有問題
一般不推薦使用松散模式
簡單來說,松散模式轉換后的代碼很容易就能看懂,而且很像我們平時寫的代碼,但這種不嚴謹的轉換可能會造成問題,所以在開發中是不推薦的。
感受一下:
轉碼前:
轉碼后(正常):
轉碼后(松散):
modules把 ES6 模塊語法轉為另一個模塊類型,默認 commonjs
現在的 webpack 4.x 已經把模塊統一的任務完成了,所以這里就不需要 babel 來做了,所以在 vue-cli 這種用 webpack 打包的腳手架里,你會看到 .babelrc 文件中有 module: false 這就是為了防止與 webpack 沖突include
指定一組總是包括的插件,當原生實現有問題,或存在不支持或支持不好的特性時候使用,默認為 []
include 和 exclude 只工作于包含在 preset 里有的插件中,如果要使用 preset 里不包含的插件,直接填在 .babelrc 的 plugins 中exclude
指定一組總是不包括的插件,默認為 []
useBuiltIns默認為 false
會啟用一個插件來根據使用情況去按需加載 polyfill 來替代 import "babel-polyfill" 語句
所有的工具建議都在項目中安裝,而不是采用全局安裝
babel-cli 用于命令行轉碼
babel-node 跟隨 babel-cli 安裝,可直接運行 ES6 代碼,因為采用這種方式是實時轉碼的,轉碼的所有工具都存在內存中,產生大量資源消耗因此只適合在開發中使用
babel-register 改寫 require 命令,每次使用 require 加載 js 文件時候,就會先轉碼,因為是實時轉碼,只適合在開發環境使用
babel-core 提供 Babel 的 API,之后可以采用編程方式使用 Babel
參考鏈接Babel · The compiler for next generation JavaScript
對babel-transform-runtime,babel-polyfill的一些理解
Babel 入門教程 - 阮一峰的網絡日志
babel-polyfill的幾種使用方式
Babel筆記 - Tony’s Blog
Babel的使用
Babel 6 松散模式
文章版權歸作者所有,未經允許請勿轉載,若此文章存在違規行為,您可以聯系管理員刪除。
轉載請注明本文地址:http://specialneedsforspecialkids.com/yun/95666.html
摘要:為了便于您更清晰的理解的體系架構,在這里我將為您展示年開發者知識圖譜,它包含了所有開發過程中的關鍵部分。在數據展示前端導入導出圖表面板數據綁定等場景無需大量代碼開發和測試,可極大節省企業研發成本并降低交付風險。 作為 Vue 的初學者,您或許已經聽過很多關于它的專業術語了,例如:單頁面應用程序、異步組件、服務器端呈現等,您可能還聽過和Vue經常一起被提到的工具和庫,如Vuex、Webp...
摘要:不過,根據伯克利大學的這篇文章來看,擁有豐富的開源庫,是開發者在選擇一門開發語言時,最重要的因素。擁有超過個可用的開源庫,是目前世界上最大的開源庫集合。月份,我們發布了。這和年的情況是相反的。在的調查中,超過的受訪者表示他們正在使用。 showImg(https://segmentfault.com/img/bVblvke?w=693&h=300); 原文標題:This year in...
摘要:安裝然后在的配置文件加入入口文件引入這樣就可以啦,還是可以減少很多代碼量的。是參數,等同于執行正常。這個包很簡單,就是引用了和,然后生產環境把它們編譯到目錄下,做了映射,供使用。 引入 這個問題是對自己的發問,但我相信會有很多跟我一樣的同學。對于 babel 的使用,近半年來一直停留在與 webpack 結合使用,以及在瀏覽器開發環境下。導致很多 babel 的包,我都不清楚他們是干嘛...
摘要:謹記,請勿犯這樣的錯誤。由于在之前的教程中,積累了堅實的基礎。其實,這是有緣由的其復雜度在早期的學習過程中,將會帶來災難性的影響。該如何應對對于來說,雖然有大量的學習計劃需要采取,且有大量的東西需要學習。 前言倘若你正在建造一間房子,那么為了能快點完成,你是否會跳過建造過程中的部分步驟?如在具體建設前先鋪設好部分石頭?或直接在一塊裸露的土地上先建立起墻面? 又假如你是在堆砌一個結婚蛋糕...
閱讀 584·2023-04-25 21:29
閱讀 1111·2023-04-25 21:27
閱讀 1050·2021-11-25 09:43
閱讀 1086·2021-09-29 09:43
閱讀 3619·2021-09-03 10:30
閱讀 2860·2019-08-29 15:26
閱讀 2811·2019-08-29 12:52
閱讀 1748·2019-08-29 11:10