babel學習筆記

先是看到前端早讀課【第1065期】再見,babel-preset-2015,據說如今有了babel-preset-env,別的什麼preset都不須要了,還能夠經過useBuiltIns設置成usage,只須要install一下babel-polyfill,其餘全交給babel處理就好了。
看完屁顛屁顛得去拿本身項目開刀把preset換了,把import "babel-polyfill"刪了,把babel-transform-runtime啊,preset-2015啊,preset-stage-2啊這些再也不須要的包都卸了,結果各類報錯,心灰意冷。。。確定是本身哪兒弄錯了,算了仍是忙別的去吧有空再折騰。。。前端

前兩天又看到前端早讀課推了一篇很長的【第1089期】babel到底該如何配置。邊看,邊跟着作了一遍,做者真的很用心,在github上放了配套的demo,看完以後我靠叫一個豁然開朗,回頭再瞅瞅那邊《再見babel-preset-2015》,多少有些遺漏細節,甚至有些誤導人。git

通過一番折騰,總算是把本身項目裏的babel配置調整好了,全部js文件從原來的1.85m縮小到1.62m。效果還挺好的。折騰了很多時間,改動其實就一個地方,就是配置文件.babelrc,記錄一下本身折騰的過程。es6

plugins: ["transform-runtime"] 與 babel-polyfill

最開始沒弄清楚配置文件裏的"plugins": ["transform-runtime"]是幹嗎的,《babel到底該如何配置》說得很是清楚,babel就是經過其各類plugins來實現將指定的js轉換成本身想要的樣子,好比只要轉換箭頭函數,就只須要先安裝對應的plugingithub

npm install --save-dev babel-plugin-transform-es2015-arrow-functions

而後加到plugins裏面web

"plugins": ["transform-es2015-arrow-functions"]

這樣babel就能轉換箭頭函數了。npm

transform-runtime插件和babel-polyfill所實現的結果同樣,能夠轉換像Object.assign啊,Array.prototype.includes啊這類在es原生對象上的擴展方法,但實現的原理徹底不一樣。babel-polyfill是直接在對象的prototype上進行同名方法擴展來實現和es6相同的功能,因此只須要全局引入一次babel-polyfill,本身的代碼就不用作任何處理就能在低版本瀏覽器上執行了。
而transform-runtime插件作的事情,是改寫每個用到es6擴展方法的地方,讓其實現es6方法相同的功能。舉個例子:
在使用babel-polyfill的時候,js裏須要這麼寫:瀏覽器

import "babel-polyfill";
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};
let arr2 = Array.from(arrayLike);

而後就沒而後了,甚至都不用執行babel,只要install過babel-polyfill就夠了。由於babel-polyfill中會用ES3的方式實現一遍Array.from方法,因此,以後整個項目用到Array.prototype.includes的時候,都不會再須要babel作任何事情,直接在低版本上瀏覽器執行includes方法吧,安全省心。安全

換成是用"transform-runtime"插件就是另一回事兒了。咱們的js文件裏不須要引入babel-polyfill,但babel這時候就要開始幹活了,他會把這段代碼改寫成:babel

import _Array$from from 'babel-runtime/core-js/array/from';
let arrayLike = {
  '0': 'a',
  '1': 'b',
  '2': 'c',
  length: 3
};
let arr2 = _Array$from(arrayLike); // ['a', 'b', 'c']

用babel-runtime裏的方法去實現Array.from,而後把js文件裏全部用到Array.from的地方全都替換掉。函數

本覺得那這兩種方式取其一就好了。但後來發現transform-runtime是不會去替換Array.prototype.includes這中實例方法的,因此還得全局引入babel-polyfill,這樣一來transform-runtime感受完全變成了一個多餘的東西,除非整個項目裏不用es6的原生類實例方法。因此最終,直接卸了transform-runtime。

presets 和 "presets": ["env"]

presets的用處也是看《babel到底該如何配置》搞清楚的,大體就是plugins的各類組合。也就是說,沒有presets也無所謂,可是要很是清楚項目裏用到了那些es6甚至更高級的功能,而後找到相應的plugin引入到plugins配置項裏,這樣也OK,但估計不太會有人吃飽了撐的幹這種事情。

以前的presets有2015,2016,stage-1~4(對應處於提案的四個階段的各個功能)等等,其實就是把相應的功能對應的plugins組合一下起個名字。好比要用es6的全部功能,只要在presets裏配置一下

"presets": ["es2015"]

若是要用es6和全部處於提案第二階段的功能

"presets": ["es2015","stage-2"]

好了,到這裏,說說那個困擾我很多時間的babel-preset-env,我覺得這個preset只要告訴他要支持那個版本的瀏覽器,他就會把相關的全部的plugins都引入進來,因此屁顛屁顛把其餘preset和全部plugins都刪了。結果打包的時候報錯了。緣由是我在項目裏用了Vuex裏推薦的處於stage-3階段的對象展開運算符

...mapState({})

可是,babel-preset-env裏沒有對應的babel-plugin-transform-object-rest-spread這個plugin!
因此,要麼在plugins裏把這個plugin再加上,要麼再把stage-3(或者stage-2)加到presets裏面。這感受和想象中的不同啊,說好的一個env搞定一切的呢。。。

babel-polyfill 和 useBuiltIns

第一篇中說只須要安裝babel-polyfill就好了,而後我直接把import "babel-polyfill"這句話刪了,而後IE9上就各類開始報錯,明顯沒自動把polyfill打包進去嘛。後再看了一下官網,仍是說要import的,只是搭配useBuiltIns,打出來的包能小一些。後來再去看第一篇做者本身的博客,評論裏有相同的問題,而後才知道做者在說babel-preset-env@2.0-beta的功能。。。

相關文章
相關標籤/搜索