webpack-bootstrap解析

// 源文件

// 文件 entry.js
const { add } = require("./add");
add(1, 2);
console.log("hello world");

// 文件 add.js
function add(a, b) {
  console.log(a + b);
  return a + b;
}
module.exports = {
  add,
};
复制代码

1. 整体结构:立即执行函数

(function(modules){})({})
复制代码

2. 立即执行函数的实参部分:{}

  • 以文件相对于根目录的路径为key,文件内容为value
  • value都是匿名的函数表达式,该函数会接受三个参数
// 包装函数
(function(module, exports, __webpack_require__){
  // 文件内容
})
复制代码

⁉️ module, exports, __webpack_require__都是什么?

3. 立即执行函数内部逻辑

3.1 整体结构
var installedModules = {}
​
function __webpack_require__(moduleId){}

// 下面这些赋值 当前都么有用
__webpack_require__.m = modules
__webpack_require__.c = installedModules;
__webpack_require__.d = function(exports, name, getter) {}
__webpack_require__.r = function(exports) {}
__webpack_require__.t = function(value, mode) {}
__webpack_require__.n = function(module) {}
__webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
__webpack_require__.p = "";
​
__webpack_require__.s = "./playground/entry.js"
return __webpack_require__("./playground/entry.js")
复制代码
3.2 function _webpack_require__('./playground/entry.js')
// 1. 如果moduleId已缓存在installedModules中,直接返回缓存模块的exports属性
​
// 2. 没有缓存的话, 新建一个module,同时注入到installedModules中
// 新module有三个属性
var module = installedModules['./playground/entry.js'] = {
  i: './playground/entry.js',
  l: false, // loaded
  exports: {}
}
​
// 3. modules[moduleId] --> (function(){ 对应moduleId的文件内容 }) 
// 所以这里就能看到上面的 module, module.exports, __webpack_require__ 分别指什么
// module指当前模块,是一个对象 有三个属性
// module.export 也是一个对象 内部 module.export = {} 都会注入到该对象里,也会在installedModule中缓存下来
// __webpack_require__ 是文件引用的函数,他能通过文件名,找到对应的模块暴露出来的数据
modules[moduleId].call(module.exports, module, module.exports, __webpack_require__))
​
// 上面执行完之后 installedModules['./playground/entry.js'] 也被注入了moduleId对应模块导出的信息,将loaded置为true,表明当前模块以及加载完成
module.l = true
​
// 返回当前模块的导出内容
return module.exports
复制代码

所以到这里主要思路是:

  1. 首先会根据依赖树将所有文件处理生成一个对象,对象的每一项都是 文件路径 + 被函数包装的文件内容
  2. 整体是一个立即执行函数,函数体内定义了模块解析函数__webpack_require__, 然后开始执行__webpack_require__(入口模块路径)
  3. __webpack_require__解析模块时,通过文件路径去步骤1中的对象中寻找对应的包装函数,包装函数里有该路径对应的文件的完整内容
  4. 执行包装函数,即执行文件内容,包装函数内部通过实参的引用的方式将内部的数据导出到外部,并缓存到installedModules
© 版权声明
THE END
喜欢就支持一下吧
点赞0 分享