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