Webpack打包后模块分析

测试代码

如下代码为要打包的代码以及相应的模块

// index.js
const calculator = require('./calculator.js');
const sum = calculator.add(2, 3);
console.log('sum', sum);

// calculator.js
module.exports = {
    add: function(a, b) {
        return a + b;
    }
};

打包后的模块

// 立即执行匿名函数
(function(modules) {
    //模块缓存
    var installedModules = {};
    // 实现require
    function __webpack_require__(moduleId) {
        ...
    }
    // 执行入口模块的加载
    return __webpack_require__(__webpack_require__.s = 0);
})({
    // modules:以key-value的形式存储所有被打包的模块
    0: function(module, exports, __webpack_require__) {
        // 打包入口
        module.exports = __webpack_require__("3qiv");
    },
    "3qiv": function(module, exports, __webpack_require__) {
        // index.js内容
    },
    jkzz: function(module, exports) {
        // calculator.js 内容
    }
});

Webpack打包结果分析

这是一个最简单的Webpack打包结果(bundle),但已经可以清晰地展示出它是如何将具有依赖关系的模块串联在一起的。
上面的bundle分为以下几个部分。
(1)最外层匿名函数。它用来包裹整个bundle,并构成自身的作用域。
(2)installedModules对象。每个模块只在第一次被加载的时候执行,之后其导出值就被存储到这个对象里面,当再次被加载的时候webpack会直接从这里取值,而不会重新执行该模块。
(3)webpack_require__函数。对模块加载的实现,在浏览器中可以通过调用__webpack_require_(module_id)来完成模块导入。
(4)modules对象。工程中所有产生了依赖关系的模块都会以key-value的形式放在这里。key可以理解为一个模块的id,由数字或者一个很短的hash字符串构成;value则是由一个匿名函数包裹的模块实体,匿名函数的参数赋予了每个模块导出和导入的能力。

bundle是如何在浏览器中执行的

接下来让我们看看bundle是如何在浏览器中执行的。
1)在最外层匿名函数中初始化浏览器执行环境,包括定义installedModules对象__webpack_require__函数等,为模块的加载和执行做一些准备工作。
2)加载入口模块。每个bundle都有且只有一个入口模块,在上面的示例中,index.js是入口模块,在浏览器中会从它开始执行。
3)执行模块代码。如果执行到了module.exports则记录下模块的导出值;如果中间遇到require函数(准确地说是__webpack_require__),则会暂时交出执行权,进入__webpack_require__函数体内进行加载其他模块的逻辑。
4)在__webpack_require__中判断即将加载的模块是否存在于installedModules中。如果存在则直接取值,否则回到第3步,执行该模块的代码来获取导出值。
5)所有依赖的模块都已执行完毕,最后执行权又回到入口模块。当入口模块的代码执行完毕,也就意味着整个bundle运行结束。
不难看出,第3步和第4步是一个递归的过程。Webpack为每个模块创造了一个可以导出和导入模块的环境,但本质上并没有修改代码的执行逻辑,因此代码执行的顺序与模块加载的顺序是完全一致的,这也是Webpack模块打包的奥秘。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值