webpack學(xué)習(xí)筆記三, 關(guān)于 polyfill & babel-plugin-transform-runtime

我們都知道,在ES6中新增了很的方法.

比如下面這些:

  • Array.prototype.forEach
  • Array.prototype.map
  • String.prototype.startWith
  • ......

這些都是在ES6中新增的,如果一個(gè)瀏覽器并不支持ES6的語法,那么肯定也不會(huì)存在這些方法.

但是我們寫代碼的時(shí)候,又希望用到這些方法.

并希望,webpack在打包的時(shí)候,能夠[有誰]可以幫我們判斷一下.

如果當(dāng)前的瀏覽器不支持這些方法的話,就使用平滑后退的方式去處理.

雖然 babel 可以轉(zhuǎn)化 ES6 -> ES5.

但是對于 ES6 里面新增的這些方法,它就無能為力的.

babel 只處理語法層面的問題.不能處理API相關(guān)的問題.

webpack 僅僅是一個(gè)處理文件依賴關(guān)系,并打包的工具.
它更無能為力.


開始例子

首先定義一個(gè) ES6FN.js 的文件.

let moduleName = 'es6方法'
export default {
  moduleName,
  useMap () {
    console.log('usermap')
    let obj = {
      name: '李四',
      age: 22
    }
    // Object.keys() ,map  都是 ES6 新增的方法.
    return Object.keys(obj).map(key => {
      return {
        keyName: key,
        keyValue: obj[key]
      }
    })
  },
  toString () {
    console.log(`${this.keyName} ${this.keyValue}`)
  }
}

首先用 webpack + babel 打包一次.
證明,babel 只能轉(zhuǎn)換語法,不能轉(zhuǎn)化API

查看結(jié)果


babel只能轉(zhuǎn)換語法拂檩,不能轉(zhuǎn)化API
  • let -> var
  • userMap() -> useMap:function(){}

說明語法轉(zhuǎn)換確實(shí)完成.

  • Object.keys() & map() 仍然存在,證明 babel 僅僅只能轉(zhuǎn)化語法.

最終使用 webpack + babel 生成的代碼.
雖然在語法層面成功的從 ES6 -> ES5.
但是由于代碼中使用了 ES6 新增的一些方法.
所以,這份打包好的代碼,最終在一些不支持 ES6特性的瀏覽器中,仍然是無法運(yùn)行和使用的.

所以,僅僅是語法轉(zhuǎn)化是不行的.


使用 babel-polyfill

babel-polyfill 是一個(gè)用于解析目標(biāo)代碼中,是否包含 ES6 新增方法的腳本.
如果它發(fā)現(xiàn)了里面有,就會(huì)以當(dāng)前瀏覽器支持的方式轉(zhuǎn)換這些方法以便可以正常運(yùn)行.

之前在瀏覽器中,我們一般會(huì)這么引用.

<script src='babel-polyfill.js' />
<script src='es6-fn-in-this-file.js'></script>

其實(shí)也是同樣的原理,
我們只需要在我們打包代碼的最前面加載 babel-polyfilljs 代碼即可.

npm i babel-polyfill

關(guān)于 babel-polyfill使用的兩種方式

  • 配置 webpack.config.js 里的 entry 設(shè)置為 entry: ['babel-polyfill',path.join(__dirname, 'index.js')]
webpack.config.js.entry配置成數(shù)組

運(yùn)行打包 npm run build

image.png

打包成功.文件大小 280KB

  • webpack.config.js 配置的主入口 index.js 文件的最頂層鍵入 import 'babel-polyfill'
import 方式導(dǎo)入 babel-polyfill

運(yùn)行打包 npm run build

image.png

同樣也打包成功.文件大小 280KB.

打開其中任意一份打包好的代碼,查看 Object.keys().map() 方法是否仍然存在.

image.png

發(fā)現(xiàn)這些只屬于 ES6的方法仍然是存在的.

那么 babel-polyfill 肯定是通過某種方式(墊片),添加了這些方法,讓我們可以正常的這樣去調(diào)用.

至于這些墊片加載哪,如何做到的..我沒有在原始的代碼中找到相應(yīng)的位置.

本地也沒有低版本的瀏覽器.所以暫時(shí)先不做測試.


使用 babel-plugin-transform-runtime

我們之前利用的 babel-polyfill ,使用墊片支持我們本來使用的ES6語法,
打包成功之后,文件的大小是 280KB

我們在看一下,之前沒有使用 babel-polyfill 之前的打包出來的文件是多大.

image.png

兩則相差大概 81.6倍

原因是 webpackbabel-polyfill 整體全部都打包進(jìn)去了.
babel-polyfill 肯定也實(shí)現(xiàn)了所有 ES6新API的墊片,文件一定不會(huì)小.
所以,文件變的這么大,也在常理之中了.

那么有沒有一種辦法,根據(jù)實(shí)際代碼中用到的 ES6新增API ,來使用對應(yīng)的墊片,而不是全部加載進(jìn)去呢?

使用 babel 提供的 babel-runtime & babel-plugin-transform-runtime 就可以滿足要求.

  • 首先安裝這兩個(gè)包.
    • npm i --save-dev babel-runtime babel-plugin-transform-runtime
  • .babelrc 里配置
    • plugins:["tranform-runtime"]
image.png
    

最后運(yùn)行 npm run build

打包結(jié)果

image.png

利用babel-runtime & babel-plugin-transform-runtime按需加載墊片的方式,最終打包出來的結(jié)果僅僅只是 17.4kb.比之前的 280KB要小了許多.


最后總結(jié):

  • babel 僅僅只能將 es6->es5. 如果源代碼中使用 ES6 新增的API(**Object.keys() & [].map()**),babel就無能為力了.
  • babel-polyfill 可以解決這個(gè)問題,但是會(huì)造成打包的文件大小變的巨大.
    • babel-polyfill 內(nèi)部實(shí)現(xiàn)了所有的新API的墊片功能
    • 在打包的時(shí)候,會(huì)將整個(gè) babel-polyfill 都打包進(jìn)去.
    • 所以最終打包出來的文件,就會(huì)變的很大(280KB).
  • babel-runtime & babel-plugin-transform-runtimebabel 提供的類似 babel-polyfill 功能的一個(gè)插件.
    • 它可以根據(jù)實(shí)際源代碼使用到的 ES6新增API按需打入墊片.
    • 最終打包的大小結(jié)果是 : 17.4KB
  • 最重要的有點(diǎn):不管是使用babel-polyfill
    還是 babel-runtime & babel-plugin-transform-runtime 的目的就是:
    轉(zhuǎn)換那些我們寫在源文件中的ES6方法添加墊片,
    能夠被無法識(shí)別的低瀏覽器也能夠正常運(yùn)行webpack最終打包出來的js文件.

babel 解決 語法層面的問題
babel-runtime & babel-plugin-transform-runtime解決API層面的問題.

?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請聯(lián)系作者
  • 序言:七十年代末,一起剝皮案震驚了整個(gè)濱河市承冰,隨后出現(xiàn)的幾起案子芙盘,更是在濱河造成了極大的恐慌组民,老刑警劉巖,帶你破解...
    沈念sama閱讀 211,376評論 6 491
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件,死亡現(xiàn)場離奇詭異通孽,居然都是意外死亡攘残,警方通過查閱死者的電腦和手機(jī)拙友,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 90,126評論 2 385
  • 文/潘曉璐 我一進(jìn)店門,熙熙樓的掌柜王于貴愁眉苦臉地迎上來歼郭,“玉大人遗契,你說我怎么就攤上這事〔≡” “怎么了牍蜂?”我有些...
    開封第一講書人閱讀 156,966評論 0 347
  • 文/不壞的土叔 我叫張陵,是天一觀的道長泰涂。 經(jīng)常有香客問我鲫竞,道長,這世上最難降的妖魔是什么逼蒙? 我笑而不...
    開封第一講書人閱讀 56,432評論 1 283
  • 正文 為了忘掉前任从绘,我火速辦了婚禮,結(jié)果婚禮上其做,老公的妹妹穿的比我還像新娘顶考。我一直安慰自己,他們只是感情好妖泄,可當(dāng)我...
    茶點(diǎn)故事閱讀 65,519評論 6 385
  • 文/花漫 我一把揭開白布驹沿。 她就那樣靜靜地躺著,像睡著了一般蹈胡。 火紅的嫁衣襯著肌膚如雪渊季。 梳的紋絲不亂的頭發(fā)上,一...
    開封第一講書人閱讀 49,792評論 1 290
  • 那天罚渐,我揣著相機(jī)與錄音却汉,去河邊找鬼。 笑死荷并,一個(gè)胖子當(dāng)著我的面吹牛合砂,可吹牛的內(nèi)容都是我干的。 我是一名探鬼主播源织,決...
    沈念sama閱讀 38,933評論 3 406
  • 文/蒼蘭香墨 我猛地睜開眼翩伪,長吁一口氣:“原來是場噩夢啊……” “哼微猖!你這毒婦竟也來了?” 一聲冷哼從身側(cè)響起缘屹,我...
    開封第一講書人閱讀 37,701評論 0 266
  • 序言:老撾萬榮一對情侶失蹤凛剥,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后轻姿,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體犁珠,經(jīng)...
    沈念sama閱讀 44,143評論 1 303
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 36,488評論 2 327
  • 正文 我和宋清朗相戀三年互亮,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了犁享。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 38,626評論 1 340
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡胳挎,死狀恐怖饼疙,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情慕爬,我是刑警寧澤,帶...
    沈念sama閱讀 34,292評論 4 329
  • 正文 年R本政府宣布屏积,位于F島的核電站医窿,受9級特大地震影響,放射性物質(zhì)發(fā)生泄漏炊林。R本人自食惡果不足惜姥卢,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 39,896評論 3 313
  • 文/蒙蒙 一、第九天 我趴在偏房一處隱蔽的房頂上張望渣聚。 院中可真熱鬧独榴,春花似錦、人聲如沸奕枝。這莊子的主人今日做“春日...
    開封第一講書人閱讀 30,742評論 0 21
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽隘道。三九已至症歇,卻和暖如春,著一層夾襖步出監(jiān)牢的瞬間谭梗,已是汗流浹背忘晤。 一陣腳步聲響...
    開封第一講書人閱讀 31,977評論 1 265
  • 我被黑心中介騙來泰國打工, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留激捏,地道東北人设塔。 一個(gè)月前我還...
    沈念sama閱讀 46,324評論 2 360
  • 正文 我出身青樓,卻偏偏與公主長得像远舅,于是被迫代替她去往敵國和親闰蛔。 傳聞我的和親對象是個(gè)殘疾皇子痕钢,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 43,494評論 2 348

推薦閱讀更多精彩內(nèi)容