27行代碼讀懂webpack

我們?cè)谟脀ebpack打包之后泛领,會(huì)生成一個(gè)打包的文件,這個(gè)文件里到底做了什么呢械拍?
就讓我來(lái)一步步為你分解
假如我現(xiàn)在有一個(gè)a.js文件

// a.js
module.exports = 'aaaaaaa'; 

我還有一個(gè)b.js文件

//b.js
var a = require('./a.js')
console.log(a)

那么現(xiàn)在我把b.js作為入口文件,打包出來(lái)的結(jié)果就是下面的代碼,注意:下面的代碼是經(jīng)過(guò)我簡(jiǎn)化之后胡陪,便于你理解webpack的代碼沥寥,只有27行,原始代碼比這個(gè)要多柠座。

var moduleArr = [
  (function(module,exports){
    module.exports = "aaaaa"
  }),(function(module,exports,webpackRequire){
    var a = webpackRequire(0);
    console.log(a)
  })
];
(function(modules){
  var installedModules = {};
  function webpackRequire(moduleId){
    if(installedModules[moduleId]){
      return installedModules[moduleId].exports;
    }else { //為installedModules里增加一個(gè)moduleId邑雅,它指向一個(gè)對(duì)象
      var module = installedModules[moduleId] = {
        i: moduleId,
        l:false,//是否已經(jīng)load的意思
        exports:{}// 這個(gè)模塊到底exports出了什么東西,放到這
    }
    modules[moduleId](module,module.exports,webpackRequire)
    module.l = true //表明已經(jīng)load進(jìn)了installedModules對(duì)象中
    return module.exports;
    }
  }
 webpackRequire(1)
})(moduleArr)
參數(shù)
var moduleArr = [
  (function(module,exports){
    module.exports = "aaaaa"
  }),(function(module,exports,webpackRequire){ //注意這有一個(gè)webpackRequire的參數(shù)
    var a = webpackRequire(0);
    console.log(a)
  })
];

最頂部妈经,我聲明了一個(gè)數(shù)組moduleArr淮野,這個(gè)數(shù)組里有兩個(gè)匿名函數(shù),每個(gè)匿名函數(shù)都需要module和exports吹泡,但其中一個(gè)函數(shù)還需要另外一個(gè)參數(shù)骤星,webpackRequire,這個(gè)參數(shù)是什么呢爆哑?我們看他的函數(shù)體很明顯知道這個(gè)參數(shù)是一個(gè)方法洞难,給它傳了一個(gè)參數(shù)0。而且揭朝,你不覺(jué)得函數(shù)體內(nèi)的代碼就是我上面那兩個(gè)簡(jiǎn)單的a.js和b.js文件中的代碼嗎队贱?

立即執(zhí)行

然后,我們看打包出來(lái)的文件中有一個(gè)立即執(zhí)行函數(shù)潭袱,這個(gè)函數(shù)需要一個(gè)modules的參數(shù)柱嫌,這個(gè)參數(shù)是什么呢?在這個(gè)函數(shù)的最底部屯换,我們把moduleArr傳進(jìn)去了编丘,說(shuō)明這個(gè)參數(shù)是一個(gè)數(shù)組。
然后我們看這個(gè)函數(shù)體彤悔,好多代碼嘉抓,怎么看?
跳過(guò)所有變量聲明和函數(shù)聲明字段蜗巧,只看代碼執(zhí)行字段掌眠,哪個(gè)?就是最底部那行
webpackRequire(1)
這行代碼是要執(zhí)行webpackRequire函數(shù)幕屹,并給它賦予了參數(shù)1蓝丙,然后我么再往回看這個(gè)函數(shù)要做什么。

webpackRequire函數(shù)做了什么

接著拆分

function webpackRequire(moduleId){
    if(installedModules[moduleId]){
      return installedModules[moduleId].exports;
    }else { //為installedModules里增加一個(gè)moduleId望拖,它指向一個(gè)對(duì)象
      var module = installedModules[moduleId] = {
        i: moduleId,
        l:false,//是否已經(jīng)load的意思
        exports:{}// 這個(gè)模塊到底exports出了什么東西渺尘,放到這
    }
    modules[moduleId](module,module.exports,webpackRequire)
    module.l = true //表明已經(jīng)load進(jìn)了installedModules對(duì)象中
    return module.exports;
    }

這個(gè)函數(shù)需要一個(gè)moduleId的參數(shù),然后函數(shù)體內(nèi)有一個(gè)條件判斷語(yǔ)句说敏,
然后我們看到了installedModules鸥跟,是什么?再往回看,發(fā)現(xiàn)它是一個(gè)空對(duì)象医咨,那它里面肯定沒(méi)有moduleId這個(gè)key枫匾,然后看else分支做了什么
啊···,現(xiàn)在它直接給installedModules添加屬性了

installedModules[moduleId] = {
        i: moduleId,   // 1
        l:false,//我理解的是這個(gè)模塊是否已經(jīng)load的意思拟淮,如果錯(cuò)了通知我
        exports:{}// 這個(gè)模塊到底exports出了什么東西干茉,放到這
    }

添加完屬性我們接著往下看
咦,modules是什么很泊?就是傳給整個(gè)立即執(zhí)行函數(shù)的參數(shù)角虫,我都快忘了,這才開(kāi)始調(diào)用委造,早干嘛去了戳鹅。
modules[1]對(duì)應(yīng)的是moduleArr的第二個(gè)匿名函數(shù),這里執(zhí)行的時(shí)候,傳給了它三個(gè)參數(shù)昏兆,module就是installedModules[1],module.exports是一個(gè)空對(duì)象枫虏,webpackRequire是一個(gè)參數(shù),竟然把它自己都傳進(jìn)去了亮垫,這個(gè)叫遞歸模软。
然后我們執(zhí)行這個(gè)匿名函數(shù)吧伟骨!

匿名函數(shù)做了什么

我們接著看第二個(gè)匿名函數(shù)

function(module,exports,webpackRequire){ //注意這有一個(gè)webpackRequire的參數(shù)
    var a = webpackRequire(0);
    console.log(a)
}

這個(gè)函數(shù)中根本就沒(méi)有用到module和module.exports饮潦,只用到了webpackRequire,我們看到它又給webpackRequire賦參0,還記得我們第一次調(diào)用webpackRequire這個(gè)函數(shù)是什么時(shí)候嗎携狭?不記得就往回翻翻继蜡。
然后做了什么?再往回看 webpackRequire函數(shù)做了什么這一段逛腿,重復(fù)一遍稀并。
重復(fù)完了嗎,重復(fù)完了我們就應(yīng)該進(jìn)入到了另外一個(gè)匿名函數(shù)

匿名函數(shù)到底做了什么
function(module,exports){
    module.exports = "aaaaa"
}

上面那個(gè)匿名函數(shù)帶我們兜了一圈单默,又把我們帶到了另外一個(gè)匿名函數(shù)碘举,注意,此時(shí)上面那個(gè)匿名函數(shù)還沒(méi)有執(zhí)行完。
然后我們看當(dāng)前這個(gè)匿名函數(shù),這個(gè)函數(shù)體內(nèi)有module豌骏,有exports谜悟,那么傳進(jìn)來(lái)的參數(shù),module,module.exports就可以派上用場(chǎng)了,具體執(zhí)行完就應(yīng)該是這樣

installedModules[0] = {
i:0,
l:false,
exports: "aaaaa"
}

好了巷送,匿名函數(shù)就干了這么點(diǎn)事,然后我們重新回到webpackRequire函數(shù),盡未完之事售滤。

module.l = true //表明已經(jīng)load進(jìn)了installedModules對(duì)象中
return module.exports; // "aaaaa"

這個(gè)return是干嘛用的,還記得我說(shuō) 有一個(gè)匿名函數(shù)并沒(méi)有執(zhí)行完嗎?

function(module,exports,webpackRequire){ //注意這有一個(gè)webpackRequire的參數(shù)
    var a = webpackRequire(0);
    console.log(a)
}

明白了吧完箩,return就是把 “aaaaa” 賦值給了a赐俗,然后再控制臺(tái)打印出a。
這就完了嗎弊知?
沒(méi)呢秃励!

module.l = true //表明已經(jīng)load進(jìn)了installedModules對(duì)象中
return module.exports; // 還是空對(duì)象{}

那這個(gè)return出來(lái)的空對(duì)象又是誰(shuí)的結(jié)果?
還記得我問(wèn)第一次調(diào)用webpackRequire函數(shù)是什么時(shí)候嗎吉捶?
嘿嘿···

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末夺鲜,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子呐舔,更是在濱河造成了極大的恐慌币励,老刑警劉巖,帶你破解...
    沈念sama閱讀 222,000評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件珊拼,死亡現(xiàn)場(chǎng)離奇詭異食呻,居然都是意外死亡,警方通過(guò)查閱死者的電腦和手機(jī)澎现,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,745評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門仅胞,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人剑辫,你說(shuō)我怎么就攤上這事干旧。” “怎么了妹蔽?”我有些...
    開(kāi)封第一講書(shū)人閱讀 168,561評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵椎眯,是天一觀的道長(zhǎng)。 經(jīng)常有香客問(wèn)我胳岂,道長(zhǎng)编整,這世上最難降的妖魔是什么? 我笑而不...
    開(kāi)封第一講書(shū)人閱讀 59,782評(píng)論 1 298
  • 正文 為了忘掉前任乳丰,我火速辦了婚禮掌测,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘产园。我一直安慰自己汞斧,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,798評(píng)論 6 397
  • 文/花漫 我一把揭開(kāi)白布淆两。 她就那樣靜靜地躺著断箫,像睡著了一般。 火紅的嫁衣襯著肌膚如雪秋冰。 梳的紋絲不亂的頭發(fā)上仲义,一...
    開(kāi)封第一講書(shū)人閱讀 52,394評(píng)論 1 310
  • 那天,我揣著相機(jī)與錄音,去河邊找鬼埃撵。 笑死赵颅,一個(gè)胖子當(dāng)著我的面吹牛,可吹牛的內(nèi)容都是我干的暂刘。 我是一名探鬼主播饺谬,決...
    沈念sama閱讀 40,952評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開(kāi)眼,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼谣拣!你這毒婦竟也來(lái)了募寨?” 一聲冷哼從身側(cè)響起,我...
    開(kāi)封第一講書(shū)人閱讀 39,852評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤森缠,失蹤者是張志新(化名)和其女友劉穎拔鹰,沒(méi)想到半個(gè)月后,有當(dāng)?shù)厝嗽跇?shù)林里發(fā)現(xiàn)了一具尸體贵涵,經(jīng)...
    沈念sama閱讀 46,409評(píng)論 1 318
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡列肢,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,483評(píng)論 3 341
  • 正文 我和宋清朗相戀三年,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了宾茂。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片瓷马。...
    茶點(diǎn)故事閱讀 40,615評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡,死狀恐怖跨晴,靈堂內(nèi)的尸體忽然破棺而出欧聘,到底是詐尸還是另有隱情,我是刑警寧澤坟奥,帶...
    沈念sama閱讀 36,303評(píng)論 5 350
  • 正文 年R本政府宣布树瞭,位于F島的核電站,受9級(jí)特大地震影響爱谁,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜孝偎,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,979評(píng)論 3 334
  • 文/蒙蒙 一访敌、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧衣盾,春花似錦寺旺、人聲如沸。這莊子的主人今日做“春日...
    開(kāi)封第一講書(shū)人閱讀 32,470評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至果复,卻和暖如春陈莽,著一層夾襖步出監(jiān)牢的瞬間,已是汗流浹背。 一陣腳步聲響...
    開(kāi)封第一講書(shū)人閱讀 33,571評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工走搁, 沒(méi)想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留独柑,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 49,041評(píng)論 3 377
  • 正文 我出身青樓私植,卻偏偏與公主長(zhǎng)得像忌栅,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子曲稼,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,630評(píng)論 2 359

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

  • Node.js是目前非乘餍鳎火熱的技術(shù),但是它的誕生經(jīng)歷卻很奇特贫悄。 眾所周知者春,在Netscape設(shè)計(jì)出JavaScri...
    w_zhuan閱讀 3,617評(píng)論 2 41
  • Node.js是目前非常火熱的技術(shù)清女,但是它的誕生經(jīng)歷卻很奇特钱烟。 眾所周知,在Netscape設(shè)計(jì)出JavaScri...
    Myselfyan閱讀 4,076評(píng)論 2 58
  • 無(wú)意中看到zhangwnag大佬分享的webpack教程感覺(jué)受益匪淺嫡丙,特此分享以備自己日后查看拴袭,也希望更多的人看到...
    小小字符閱讀 8,178評(píng)論 7 35
  • 本節(jié)大概花你2分鐘。 聲明 常量的值一旦設(shè)定就不能改變曙博,用let來(lái)聲明常量拥刻。變量的值可以隨意更改,用var來(lái)聲明變...
    左藍(lán)閱讀 555評(píng)論 0 1
  • 我問(wèn)過(guò)他未來(lái)想留在哪里父泳,他的回答是般哼,留在自己最喜歡的地方。我繼續(xù)問(wèn)惠窄,那你最喜歡哪里蒸眠?他笑笑說(shuō),沒(méi)有一個(gè)城市是十全十...
    喵喵醬的異想國(guó)度閱讀 130評(píng)論 0 0