Babel是一個JavaScript編譯器
Babel 是一個工具鏈,主要用於將 ECMAScript 2015+ 版本的代碼轉換爲向後兼容的 JavaScript 語法,以便可以運行在當前和舊版本的瀏覽器或其餘環境中。下面列出的是 Babel 能爲你作的事情:
Presets(預設)
做用:預設目標環境,添加咱們須要的預設環境
babel-preset-env將基於你的實際瀏覽器及運行環境,自動的肯定babel插件及polyfill,編譯ES2015及此版本以上的語言,在沒有配置項的狀況下,
babel-preset-env表現的同
babel-preset-latest同樣(或者能夠說同
babel-preset-es2015, babel-preset-es2016, and babel-preset-es2017結合到一塊兒,表現的一致)。
1 {
2 "presets": ["@babel/preset-env"]
3 }
4
5 {
6 "presets": ["@babel/preset-env」,option]
7 }
經常使用配置字段:
一、targets: String | Array | { [String]: string } 。默認爲{}
這一屬性說明了當前的項目的適用環境。能夠編寫字符串的內容,做爲boswerlist的遍歷條件。例如:"targets": "> 0.25%, not dead" 或者也可使一個對象。來設置對於每個瀏覽器最低版本的控制。例如:{ "targets": { "chrome": "58", "ie": "11" } },其中的瀏覽器關鍵字從以下之中選取:chrome, opera, edge, firefox, safari, ie, ios, android, node, electron
二、 boswerlist:
是在不一樣的前端工具之間共用目標瀏覽器和 node 版本的配置工具,
browserslist能夠在babel之中配置,來告訴babel具體轉化代碼的規則。有三種配置方式:
- 在.babelrc或者babel.config.js中去配置
1 {
2 "presets": [
3 [
4 "@babel/preset-env",
5 {
6 "targets": {
7 "node": "4",
8 "chrome": "58",
9 "ie": "11"
10 }
11 }
12 ]
13 ]
14 }
1 {
2 "browserslist": [
3 "last 1 version", "> 1%",
4 "maintained node versions", "not dead"
5 ]
6 }
- 在工程的根目錄下存在.browerslistrc配置文件
# 註釋是這樣寫的,以#號開頭
last 1 version
> 1%
maintained node versions
not dead
配置文件來源:
browerslist 將使用以下配置文件限定的的瀏覽器和 node 版本範圍:
- 工具 options,例如 Autoprefixer 工具配置中的 browsers 屬性。
- BROWERSLIST 環境變量。
- 當前目錄或者上級目錄的browserslist配置文件。
- 當前目錄或者上級目錄的browserslistrc配置文件。
- 當前目錄或者上級目錄的package.json配置文件裏面的browserslist配置項(推薦)。
- 若是上述的配置文件缺失或者其餘因素致使未能生成有效的配置,browserslist 將使用默認配置> 0.5%, last 2 versions, Firefox ESR, not dead。
實踐經驗:
- 僅僅當你在特定瀏覽器上開發相似於信息亭之類的 web app 的時候,才能夠用相似last 2 Chrome versions的查詢條件來鎖定特別具體的瀏覽器品牌和版本。市面上有各類各樣的瀏覽器,同時瀏覽器的版本碎片化也很嚴重,若是你在開發一款通用的 webapp,那就應該考慮瀏覽器多樣性致使的兼容問題。
- 若是你不想用 browserslsit 的默認設置,推薦使用last 1 version, not dead 和 > 0.2%(或者> 1% in US,> 1% in my stats).僅僅使用last n versions 將添加太多的廢棄瀏覽器到工程裏面來,同時也並無有效的覆蓋那些佔有率仍然很高的老版本瀏覽器。
- 不移除某些瀏覽器,是由於你不瞭解它們的分佈。Opera mini 在非洲有一億用戶,全球範圍內,它也比 微軟的 Edge 瀏覽器更加流行。QQ 瀏覽器的使用量比桌面端的火狐和 Safari 瀏覽器加起來還多。
查詢條件列表:
能夠用以下查詢條件來限定瀏覽器和 node 的版本範圍(大小寫不敏感):
- > 5%: 基於全球使用率統計而選擇的瀏覽器版本範圍。>=,<,<=一樣適用。
- > 5% in US : 同上,只是使用地區變爲美國。支持兩個字母的國家碼來指定地區。
- > 5% in alt-AS : 同上,只是使用地區變爲亞洲全部國家。這裏列舉了全部的地區碼。
- > 5% in my stats : 使用定製的瀏覽器統計數據。
- cover 99.5% : 使用率總和爲99.5%的瀏覽器版本,前提是瀏覽器提供了使用覆蓋率。
- cover 99.5% in US : 同上,只是限制了地域,支持兩個字母的國家碼。
- cover 99.5% in my stats :使用定製的瀏覽器統計數據。
- maintained node versions :全部還被 node 基金會維護的 node 版本。
- node 10 and node 10.4 : 最新的 node 10.x.x 或者10.4.x 版本。
- current node :當前被 browserslist 使用的 node 版本。
- extends browserslist-config-mycompany :來自browserslist-config-mycompany包的查詢設置
- ie 6-8 : 選擇一個瀏覽器的版本範圍。
- Firefox > 20 : 版本高於20的全部火狐瀏覽器版本。>=,<,<=一樣適用。
- ios 7 :ios 7自帶的瀏覽器。
- Firefox ESR :最新的火狐 ESR(長期支持版) 版本的瀏覽器。
- unreleased versions or unreleased Chrome versions : alpha 和 beta 版本。
- last 2 major versions or last 2 ios major versions :最近的兩個發行版,包括全部的次版本號和補丁版本號變動的瀏覽器版本。
- since 2015 or last 2 years :自某個時間以來更新的版本(也能夠寫的更具體since 2015-03或者since 2015-03-10)
- dead :經過last 2 versions篩選的瀏覽器版本中,全球使用率低於0.5%而且官方聲明不在維護或者事實上已經兩年沒有再更新的版本。目前符合條件的有 IE10,IE_Mob 10,BlackBerry 10,BlackBerry 7,OperaMobile 12.1。
- last 2 versions :每一個瀏覽器最近的兩個版本。
- last 2 Chrome versions :chrome 瀏覽器最近的兩個版本。
- defaults :默認配置> 0.5%, last 2 versions, Firefox ESR, not dead。
- not ie <= 8 : 瀏覽器範圍的取反。
- 能夠添加not在任和查詢條件前面,表示取反
注意事項:
Browserslist 會處理瀏覽器的每一個版本,因此應該避免配置這樣的查詢條件Firefox > 0.多個查詢條件組和
在一塊兒以後,其之間的的覆蓋是以OR 的方式,而是否是AND,也就是說只要瀏覽器版本符合篩選條件裏面的
一種便可。
全部的查詢條件均基於
Can I Use的支持列表。例如:last 3 ios versions 可能會返回8.4, 9.2, 9.3(混合了
主版本和次版本),然而last 3 Chrome versions可能返回50, 49, 48(只有主版本),總之一切以 CanIUse網
站收集的瀏覽器版本數據爲準。
不一樣環境的差別化配置:
"browserslist": {
"production": [
"> 1%",
"ie 10"
],
"development": [
"last 1 chrome version",
"last 1 firefox version"
]
}
三、useBuiltIns : "usage"| "entry"| false,默認爲false。
此選項配置
@babel/preset-env如何處理
polyfill。
usage和
entry選項配置上都是增長按需引入的功能。
在文件須要的位置單獨按需引入,能夠保證在每一個bundler中只引入一份。當前模式相似於@babel/plugin-transform-runtime,polyfill局部使用,製造一個沙盒環境,不形成全局污染
在項目入口引入一次(屢次引入會報錯),插件@babel/preset-env會將把@babel/polyfill根據實際需求打散,只留下必須的,例如:
In
import "@babel/polyfill」;
Out (實際引入取決於環境不一樣)
import "core-js/modules/es6.promise";
import "core-js/modules/es7.string.pad-start";
import "core-js/modules/es7.string.pad-end";
import "core-js/modules/es7.array.includes";
四、modules
選項用於模塊轉化規則設置,可選配置包括:"amd" | "umd" | "systemjs" | "commonjs" | false, 默認使用 "commonjs"。即,將代碼中的ES6的import轉爲require。
五、include :Array<string|RegExp>,默認爲[]
轉譯時必須包含的插件
六、exclude: Array<string|RegExp>,默認爲[]
轉譯時排除在外的插件
2、@babel/preset-react(官方preset)
做用:react 語法轉譯
一、默認包含的插件
此 preset 始終包含如下插件:
以及如下開發環境下的選擇輔助開發插件:
PS:通常使用該預設都是默認值,不須要單獨配置插件
配置參數:
string 類型,默認值爲 React.createElement。編譯 JSX 表達式時替用於換所使用的函數(function)。
string 類型,默認值爲 React.Fragment。編譯 JSX 片斷時用於替換所用的組件。
boolean 類型,默認值爲 false。當插件須要某項功能時,此參數用於肯定是使用內置功能仍是經過 polyfill 來模擬。
boolean 類型,默認值爲 true。若是使用了 XML 命名空間標籤,此參數用於設置是否拋出錯誤。例如:<f:image />。雖然 JSX 規範容許這樣作,可是默認狀況下是被禁止的,由於 React 的 JSX 目前並不支持這 種方式。
3、@babel/preset-stage-x
做用:能夠將處於某一階段的js語法編譯爲正式版本的js代碼
一、stage-X: 指處於某一階段的js語言提案。
提案共分爲5個階段:
- stage-0:稻草人-只是一個大膽的想法
- stage-1:提案-初步嘗試
- stage-2:初稿-完成初步規範
- stage-3:候選-完成規範和瀏覽器初步實現
- stage-4:完成-將被添加到下一年發佈
PS: babel-preset-stage-4已經整合入Presets不單獨發佈了
plugins(插件)
Babel 是一個編譯器(輸入源碼 => 輸出編譯後的代碼)。就像其餘編譯器同樣,編譯過程分爲三個階段:解析、轉換和打印輸出。
如今,Babel 雖然開箱即用,可是什麼動做都不作。它基本上相似於 const babel = code => code; ,將代碼解析以後再輸出一樣的代碼。若是想要 Babel 作一些實際的工做,就須要爲其添加插件。
除了一個一個的添加插件,你還能夠以
preset 的形式啓用一組插件。
1、轉換插件
做用:這些插件用於轉換你的代碼。(轉換插件將啓用相應的語法插件,所以你沒必要同時指定這兩種插件。)
一、ES3
二、ES5
三、ES2015(ES6)
四、ES2016
五、ES2017
六、ES2018
七、Modules
八、Experimental
九、Minification
十、React
十一、其餘
2、語法插件
這些插件只容許 Babel 解析(parse) 特定類型的語法(而不是轉換)。(注意:轉換插件會自動啓用語法插件。所以,若是你已經使用了相應的轉換插件,則不須要指定語法插件。)
{
"parserOpts": {
"plugins": [
"jsx",
"flow"
]
}
}
3、插件/Preset路徑
若是插件再 npm 上,你能夠輸入插件的名稱,babel 會自動檢查它是否已經被安裝到 node_modules 目錄下
{ "plugins": ["babel-plugin-myPlugin"] }
你還能夠指定插件的相對/絕對路徑。
{ "plugins": ["./node_modules/asdf/plugin"] }
4、插件的短名稱
若是插件名稱的前綴爲 babel-plugin-,你還可使用它的短名稱:
1 { "plugins": [
2 "myPlugin」,
3 "babel-plugin-myPlugin" // 兩個插件實際是同一個
4 ]
5 }
這也適用於帶有冠名(scope)的插件:
1 { "plugins": [
2 "@org/babel-plugin-name」,
3 "@org/name" // 兩個插件實際是同一個
4 ]
5 }
5、插件順序
- Plugin 會運行在 Preset 以前。
- Plugin 會從第一個開始順序執行。ordering is first to last.
- Preset 的順序則恰好相反(從最後一個逆序執行)。
經常使用插件說明
一、babel-core
//必備的核心庫
二、babel-loader
//webpack loader配置必備
三、babel-preset-env
//有了它,你再也不須要添加201五、201六、2017,全都支持
四、babel-preset-stage-0
//有了它,你再也不須要添加stage-1,stage-2,stage-3,默認向後支持
五、babel-plugin-transform-runtime 、babel-runtime
//支持helpers,polyfill,regenerator配置
babel-plugin-transform-runtime該插件主要作了三件事
- 自動轉換generators/async
- 使用core-js來按需給內置類型打上polyfill。(這一點和useBuiltIns:'usage'同樣)
- 經過helpers 選項自動移除嵌入的babel helper,而且用module引用來代替。不然每一個文件中都會加入這些inline babel helper,形成代碼冗餘。默認爲ture。
@babel/runtime 和
@babel/polyfill 雖然都是爲內置類型打上墊片,可是
@babel/runtime是在模塊內起做用,不會污染全局的Promise,Map...。因此實例的方法不會被
polyfill。
可是若是運行環境很low,好比好比說Android一些老機子,而你有須要大量使用
Promise、Object.assign、Array.find之類的全局對象或者其所屬方法,那麼使用
babel-polyfill,絕對是一勞永逸。
接着,再來講說
babel-runtime,相對而言,它的處理方式比較溫柔,套用步步高的廣告詞就是哪裏須要加哪裏,好比說你須要
Promise,你只須要
import Promise from 'babel-runtime/core-js/promise'便可,這樣不只避免污染全局對象,並且能夠減小沒必要要的代碼。
不過,若是N個文件都須要
Promise,難道得一個個文件的加
import Promise from 'babel-runtime/core-js/promise'麼,顯然不是,Babel已經爲這樣狀況考慮過了,只須要使用
babel-plugin-transform-runtime就能夠輕鬆的幫你省去手動import的痛苦,並且,它還作了公用方法的抽離,哪怕你有100個模塊使用了
Promise,可是
promise的
polyfill僅僅存在1份,全部要的地方都是引用一地方,具體的配置參考以下:
1 // .babelrc
2 {
3 "presets": [
4 "env",
5 "stage-0"
6 ],
7 "plugins": [
8 "transform-runtime"
9 ],
10 "comments": false
11 }
@babel/plugin-transform-runtime 還能夠和
preset-env中的
useBuiltIns一塊兒使用,做用的順序按照plugins --> presets 的順序,也就是先使用
@babel/plugin-transform-runtime 打上墊片,而後再使用
@babel/polyfill 再打上一次墊片。
若是使用react:
一、babel-plugin-transform-decorators-legacy
//支持修飾符語法 @connect
二、babel-preset-react
//支持解析react語法,若是使用vue把react替換成vue就好
若是須要熱更新:
一、react-hot-loader //雖然它長得不像babel,可是它也須要在babelrc作配置
最後總結
主要幾個配置
- presets : 預設,插件的集合,倒序執行
- plugins : 插件,先執行插件,在執行預設,順序執行
- ignore : 忽略的文件
- minify : 壓縮代碼
- common : 是否須要註釋
- env : 設置不一樣的環境,應用不一樣的配置,配置取值:BABEL_ENV,如若沒有取 NODE_ENV 的值,默認爲 development.
常見預設
- env : 用於替換 es2015 / es2016 / es2017 的預設。根據環境引入插件
- react :react的插件集合
- react-optimize : react 代碼優化,如去除 propsType 減小生產上面代碼
- stage-x :草案代碼插件集合
- flow : flow 插件集合
- minify : 代碼優化的集合
- typescript : typescript 插件集合
經常使用插件
- transform-async-to-generator : 異步函數 async/await 插件
- transform-decorators-leagacy : 裝飾器插件
- syntax-dynamic-import :import() 插件
- transform-runtime : 輔助器插件,用於ployfill
- transform-object-rest-spread : 用於合併 var test = {a:1,b2};var t = {...test,n:1}
- transform-funciton-bind : 用於編譯 obj::fun => fun.bind(obj)
資料來源: