淺讀webpack——模塊化原理

前言

又是偷懶了快一年。重新回歸簡(jiǎn)書的原因是一位同事百度async原理時(shí),第一篇竟然是我的文章簇捍。瞬間腰桿挺直,又堅(jiān)定了更博的信念够滑。
webpack模塊化的原理在網(wǎng)上已經(jīng)一搜一片垦写。但是對(duì)著文章讀吕世,始終不是你自己的彰触,切記不能背原理,面試官一深入問命辖,只能嗝屁况毅。

動(dòng)手

準(zhǔn)備2個(gè)JS分蓖。a.js,b.js。
a.js

let a = require('./b');
a()

b.js

module.exports = function(){
  console.log('hello world')
}

進(jìn)行webpack編譯尔许,生成main.js么鹤。
先看看原來(lái)的JS都變成什么樣了

/* 0 */
(function(module, exports, __webpack_require__) {
  let a = __webpack_require__(1); //b.js變成了1
  a()
}),
/* 1 */
(function(module, exports) {
  module.exports = function(){
    console.log('hello world')
  }
})

1、JS被包在一個(gè)函數(shù)里味廊,函數(shù)提供了module, exports,_webpack_require_參數(shù)蒸甜。
2、原來(lái)的require函數(shù)變成了_webpack_require_
3余佛、'b.js'文件名變成了模塊ID
回過來(lái)想也是應(yīng)該的柠新,瀏覽器沒有module和require,為了不報(bào)錯(cuò)辉巡,所以需要函數(shù)來(lái)提供module和require恨憎。
再來(lái)看下main.js的整體架構(gòu)

(function(modules) { //自執(zhí)行函數(shù)。module為包裹了函數(shù)的a.js,b.js
})([
(function(module, exports, __webpack_require__) {
  console.log(module)
  let a = __webpack_require__(1);
  a()
}),
(function(module, exports) {
  module.exports = function(){
    console.log('hello world')
  }
})
])

整體來(lái)說就是個(gè)自執(zhí)行函數(shù)郊楣。經(jīng)過處理的a.js,b.js作為參數(shù)傳入到自執(zhí)行函數(shù)憔恳。

function __webpack_require__(moduleId) {
        // 判斷模塊是否已經(jīng)緩存過
        if(installedModules[moduleId]) {
            return installedModules[moduleId].exports;
        }
        // 沒有就初始化一個(gè)模塊
        var module = installedModules[moduleId] = {
            i: moduleId,
            l: false,
            exports: {}
        };

        //執(zhí)行被函數(shù)包裹后的js
        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

        // 記錄該模塊已經(jīng)被加載
        module.l = true;

        // 返回 module.exports,比如在b.js中module.exports被函數(shù)賦值了 
        return module.exports;
}

到此净蚤,捋一下main.js的執(zhí)行過程
1钥组、_webpack_require_(0)。
2塞栅、模塊0沒有被緩存過者铜,初始化module。
3放椰、從modules數(shù)組中取出0模塊作烟,即a.js。執(zhí)行

modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);

執(zhí)行_webpack_require_(1)砾医,加載b.js拿撩。
4、_webpack_require_函數(shù)return module.exports如蚜。在b.js中

module.exports = function(){
  console.log('hello world')
}

module.exports已經(jīng)被賦值压恒,所以得到函數(shù)
5、至此错邦,依賴加載完畢,代碼也執(zhí)行完成探赫。
同理再看下ES6的Module
a.js

import a from './b'
function c(){
    a()
}
export default c

b.js

export default function(){
    console.log('hello world')
}

進(jìn)行webpack編譯,生成main.js撬呢。
看下原來(lái)的JS編譯后的樣子

[
/* 0 */
(function(module, __webpack_exports__, __webpack_require__) {
"use strict";
// ESM COMPAT FLAG
__webpack_require__.r(__webpack_exports__);
// CONCATENATED MODULE: ./b.js
var b = (function(){
    console.log('hello world')
});
// CONCATENATED MODULE: ./a.js
function c(){
    b()
}
 var a = __webpack_exports__["default"] = (c);
 })
]

在commonjs下伦吠,數(shù)組長(zhǎng)度為2。但在ES6規(guī)范下,數(shù)組長(zhǎng)度是1毛仪。exports被剝掉搁嗓,直接將2個(gè)JS粘合在了一起
_webpack_require_.r

  // define __esModule on exports
__webpack_require__.r = function(exports) {
  if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
    Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
  }
  Object.defineProperty(exports, '__esModule', { value: true });
};

標(biāo)記了這個(gè)模塊屬于ES6 Module。
其他都和commonjs一致箱靴,從_webpack_require_(0)開始

最后腺逛,給自己留個(gè)問題
為什么commonjs數(shù)組分開,而ES module卻直接粘合在一起衡怀。

最后編輯于
?著作權(quán)歸作者所有,轉(zhuǎn)載或內(nèi)容合作請(qǐng)聯(lián)系作者
  • 序言:七十年代末棍矛,一起剝皮案震驚了整個(gè)濱河市,隨后出現(xiàn)的幾起案子抛杨,更是在濱河造成了極大的恐慌茄靠,老刑警劉巖,帶你破解...
    沈念sama閱讀 221,635評(píng)論 6 515
  • 序言:濱河連續(xù)發(fā)生了三起死亡事件蝶桶,死亡現(xiàn)場(chǎng)離奇詭異慨绳,居然都是意外死亡,警方通過查閱死者的電腦和手機(jī)真竖,發(fā)現(xiàn)死者居然都...
    沈念sama閱讀 94,543評(píng)論 3 399
  • 文/潘曉璐 我一進(jìn)店門脐雪,熙熙樓的掌柜王于貴愁眉苦臉地迎上來(lái),“玉大人恢共,你說我怎么就攤上這事战秋。” “怎么了讨韭?”我有些...
    開封第一講書人閱讀 168,083評(píng)論 0 360
  • 文/不壞的土叔 我叫張陵脂信,是天一觀的道長(zhǎng)。 經(jīng)常有香客問我透硝,道長(zhǎng)狰闪,這世上最難降的妖魔是什么? 我笑而不...
    開封第一講書人閱讀 59,640評(píng)論 1 296
  • 正文 為了忘掉前任濒生,我火速辦了婚禮埋泵,結(jié)果婚禮上,老公的妹妹穿的比我還像新娘罪治。我一直安慰自己丽声,他們只是感情好,可當(dāng)我...
    茶點(diǎn)故事閱讀 68,640評(píng)論 6 397
  • 文/花漫 我一把揭開白布觉义。 她就那樣靜靜地躺著雁社,像睡著了一般。 火紅的嫁衣襯著肌膚如雪晒骇。 梳的紋絲不亂的頭發(fā)上霉撵,一...
    開封第一講書人閱讀 52,262評(píng)論 1 308
  • 那天滋饲,我揣著相機(jī)與錄音,去河邊找鬼喊巍。 笑死,一個(gè)胖子當(dāng)著我的面吹牛箍鼓,可吹牛的內(nèi)容都是我干的崭参。 我是一名探鬼主播,決...
    沈念sama閱讀 40,833評(píng)論 3 421
  • 文/蒼蘭香墨 我猛地睜開眼款咖,長(zhǎng)吁一口氣:“原來(lái)是場(chǎng)噩夢(mèng)啊……” “哼何暮!你這毒婦竟也來(lái)了?” 一聲冷哼從身側(cè)響起铐殃,我...
    開封第一講書人閱讀 39,736評(píng)論 0 276
  • 序言:老撾萬(wàn)榮一對(duì)情侶失蹤海洼,失蹤者是張志新(化名)和其女友劉穎,沒想到半個(gè)月后富腊,有當(dāng)?shù)厝嗽跇淞掷锇l(fā)現(xiàn)了一具尸體坏逢,經(jīng)...
    沈念sama閱讀 46,280評(píng)論 1 319
  • 正文 獨(dú)居荒郊野嶺守林人離奇死亡,尸身上長(zhǎng)有42處帶血的膿包…… 初始之章·張勛 以下內(nèi)容為張勛視角 年9月15日...
    茶點(diǎn)故事閱讀 38,369評(píng)論 3 340
  • 正文 我和宋清朗相戀三年赘被,在試婚紗的時(shí)候發(fā)現(xiàn)自己被綠了是整。 大學(xué)時(shí)的朋友給我發(fā)了我未婚夫和他白月光在一起吃飯的照片。...
    茶點(diǎn)故事閱讀 40,503評(píng)論 1 352
  • 序言:一個(gè)原本活蹦亂跳的男人離奇死亡民假,死狀恐怖浮入,靈堂內(nèi)的尸體忽然破棺而出,到底是詐尸還是另有隱情羊异,我是刑警寧澤事秀,帶...
    沈念sama閱讀 36,185評(píng)論 5 350
  • 正文 年R本政府宣布,位于F島的核電站野舶,受9級(jí)特大地震影響易迹,放射性物質(zhì)發(fā)生泄漏。R本人自食惡果不足惜平道,卻給世界環(huán)境...
    茶點(diǎn)故事閱讀 41,870評(píng)論 3 333
  • 文/蒙蒙 一赴蝇、第九天 我趴在偏房一處隱蔽的房頂上張望。 院中可真熱鬧巢掺,春花似錦句伶、人聲如沸。這莊子的主人今日做“春日...
    開封第一講書人閱讀 32,340評(píng)論 0 24
  • 文/蒼蘭香墨 我抬頭看了看天上的太陽(yáng)。三九已至轧苫,卻和暖如春楚堤,著一層夾襖步出監(jiān)牢的瞬間疫蔓,已是汗流浹背。 一陣腳步聲響...
    開封第一講書人閱讀 33,460評(píng)論 1 272
  • 我被黑心中介騙來(lái)泰國(guó)打工身冬, 沒想到剛下飛機(jī)就差點(diǎn)兒被人妖公主榨干…… 1. 我叫王不留衅胀,地道東北人。 一個(gè)月前我還...
    沈念sama閱讀 48,909評(píng)論 3 376
  • 正文 我出身青樓酥筝,卻偏偏與公主長(zhǎng)得像滚躯,于是被迫代替她去往敵國(guó)和親。 傳聞我的和親對(duì)象是個(gè)殘疾皇子嘿歌,可洞房花燭夜當(dāng)晚...
    茶點(diǎn)故事閱讀 45,512評(píng)論 2 359