webpack模块打包原理

2021-04-01  本文已影响0人  湘兰沅芷
// 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;
  }
);
上面的代码经过Webpack打包后将会成为如下的形式(为了易读性这里只展示代码 的大体结构): 打包代码.png

1 )最外层立即执行匿名函数包裹整个bundle,构成自身的作用域
2 )webpack_module_cache对象。每个模块只在第一次被加载的时候执行,之后其导出值就被存储到这个对象里面,当再次被加载的时候直接从这里取值,而不会重新 执行。
3 ) webpackrequire函数。对模块加载的实现,在浏览器中可以通过调用 webpack require(module id)来完成模块导入
4 )modules对象。工程中所有产生了依赖关系的模块都会以key-value的形式放在 这里。key可以理解为一个模块的id,由数字或者一个很短的hash字符串构成; value则是由一个匿名函数包裹的模块实体,匿名函数的参数则赋予了每个模块 导出和导入的能力。

bundle是如何在浏览器中执行的:
1 )在最外层的匿名函数中会初始化浏览器执行环境,包括定义installedModules对 象、—webpack require函数等,为模块的加载和执行做一些准备工作。
2)加载入口模块。每个bundle都有且只有一个入口模块,在上面的示例中, index.js是入口模块,在浏览器中会从它开始执行。
3 )执行模块代码。如果执行到了 module.exports则记录下模块的导出值;如果中 间遇到require函数(准确地说是webpack require),则会暂时交出执行权,进入 webpack require函数体内进行加载其他模块的逻辑。
4 )在webpack require中会判断即将加载的模块是否存在于installedModules 中。如果存在则直接取值,否则回到第3步,执行该模块的代码来获取导出值。
5)所有依赖的模块都已执行完毕,最后执行权又回到入口模块。当入口模块的代 码执行到结尾,也就意味着整个bundle运行结束。

上一篇下一篇

猜你喜欢

热点阅读