熟悉前端開發(fā)的朋友,應該對 Babel這個項目并不陌生,早在兩年多以前,阮一峰大大就已經(jīng)寫過文章《Babel 入門教程》 對他進行了介紹,那個時候,其實Babel應該已經(jīng)算得上是網(wǎng)紅開源前端庫了。這兩年,Babel其實也一直在發(fā)展,我這里想說的是我看到的Babel的成長
babel-preset-env
首先是babel-preset-env,詳細的介紹文檔在這里:https://www.babeljs.cn/docs/plugins/preset-env/
我也并不會去介紹怎么去用這個,只是想談談自己的體會。我記得剛開始使用babel的時候,的確有時候會用上一些stage-2,stage-3 的特性,那時候還為了了解這些所謂的stage去看了ECMASCRIPT 新版本發(fā)布的流程,覺得也很有意思。但是雖然有意思,但是配置起來卻的確繁瑣,有時候,你的確需要為了配置這樣一個Babel看好多相關文檔,這無疑算是一個痛點了。現(xiàn)在好了,就如同文檔里面所提到的:
在沒有任何配置選項的情況下,babel-preset-env 與 babel-preset-latest(或者babel-preset-es2015,babel-preset-es2016和babel-preset-es2017一起)的行為完全相同。
babel-polyfill
為什么你這么大
我們都知道,Babel為了存心讓我們配置起來更困難,故意將他的功能分拆成了兩部分,其一是語法上的轉(zhuǎn)化,這個默認情況下他自會幫我們處理。而另外一部分,就是新API的polyfill,需要我們引入babel-polyfill來完成。當然,我前面說,Babel是存心折騰開發(fā)者的確是開玩笑的,畢竟并不是所有的時候我們都需要polyfill的。這有點像是React項目也有兩個核心包,React和ReactDOM類似。
import React from 'react';
import ReactDOM from 'react-dom';
babel-polyfill是好東西,能夠?qū)⑿翧PI作用在老的瀏覽器上,但是我們要注意不要濫用。比如我們隨便在百度上搜索一篇文章,講解如何使用 babel-polyfill的引用和使用,往往都會看到有這樣的描述:
module.exports = {entry: ["babel-polyfill", "./app/js"]};
這樣做,從功能實現(xiàn)上來看當然是沒有錯的。但是,如果我們原來的入口是
module.exports = {entry: ["./app/js"]};
那么很容易就能夠發(fā)現(xiàn)由于入口處增加了babel-polyfill,導致webpack在處理之后,最終的到的入口核心js文件比原來增加了有100kb左右。對于這個問題,也已經(jīng)有issue,不過很奇怪這位網(wǎng)友把issue提到了babel-loader這個項目下。
然后針對這個問題,有老外網(wǎng)友介紹到了transform-runtime等。但是經(jīng)過我的測試,這也并不是一個很好的實踐。
動態(tài)識別
為了polyfill 這件事情,其實是有兩種思路可循的。第一個思路是根據(jù)瀏覽器缺失哪些特性來補全哪些特性,這個思路的代表是 polyfill-service,這個項目 。它能夠根據(jù)瀏覽器的UA來判斷當前瀏覽器缺失哪些特性,進而進行補強。但是經(jīng)過我的調(diào)研,這個項目在天朝可能還存在水土不服的問題,一個很明顯的事實是將安卓微信內(nèi)置的QQ瀏覽器X5交給這個庫來處理,它會認為當前的瀏覽器是safari,原因大概是因為UA上有safari這個字段。考慮到我們天朝還有類似微信這樣很怪異的UA,我認為并不適合在當前這個時間來對此進行實踐。(在這里多說兩句,polyfill-service這個庫和另外一個知名項目fastclick同屬于英國金融時報,而最近我發(fā)現(xiàn)fastclick在現(xiàn)代瀏覽器上也有一些tricky的地方,在他們的issue區(qū)有能夠找到一些吐槽,然而,這個庫已經(jīng)兩年多沒有人維護了)
把polyfill-service仍在一邊,我們接下來說另一個思路。能不能根據(jù)我使用了多少新API,來決定我引入多少polyfill的內(nèi)容呢?比如我只在我的項目中使用了ES6的set,沒有使用其他新API。那么我引入polyfill的時候,能不能只引入set的polyfill呢?答案當然是可以的,這就是babel-7的新特性,沒錯,由于當前穩(wěn)定版是babel-6,因此這個特性還處在測試階段。但是根據(jù)我自己的測試,表現(xiàn)很多。
不過有趣的是,雖然還只是Beta版,Babel卻將之寫入了正式版的文檔當中,結果當時我為了測試這個新特性,都已經(jīng)測試到懷疑人生了。文檔戳這里,感興趣的同學可以去看看??傊?,實際上只是對babel增加一項配置。
"useBuiltIns": "usage"
不過由于涉及到升級Babel,當時我在測試的時候,還是有些不順的。但是一旦遷移成功,應用上useBuiltIns的這項配置,的確能夠讓polyfill的體積大幅度減小。
browserlist
前面的動態(tài)polyfill,的確可以讓webpack生成的js文件體積更小,但是能不能再小一些呢?畢竟我們前端開發(fā)的目的就是極致的用戶體驗,當然可以。這個時候browserlist能夠幫到我們。
關于這個話題,網(wǎng)路上相關的文章非常多,我就不再多談了。
感興趣的同學,可以看看ant-design項目中使用的browserlist。
https://github.com/ant-design/antd-tools/blob/master/lib/getBabelCommonConfig.js