webpack 运行时代码进行调试三遍并理解
调试略
webpack 的模块加载器是如何实现的
首先定义全局缓存对象__webpack_module_cache__
然后定义打包器函数__webpack_require__(moduleId){}
函数中:
首先根据 moduleId 读取全局缓存对象
如果存在缓存,则直接返回缓存模块的 exports 对象
如果不存在缓存,创建新的模块对象,首先根据 moduleId 放入缓存,然后赋值给局部模块对象,此时局部模块对象仅有 exports 属性
然后根据 moduleId 读取全局模块数组,执行该模块函数并传入函数里的局部模块对象,拿到指定模块的 exports 值
最后导出该模块的 exports 值
webpack 的运行时代码做了那些事情
首先定义全局模块数组,将模块用带参数的函数包裹并根据 moduleId 放入数组的第一个位置后,第一个位置为入口模块 __webpack_modules__
然后定义模块加载器,可以根据 moduleId 执行模块,并返回模块的 exports 值 __webpack_require__
(moduleId){}
最后执行模块加载器加载入口模块__webpack_require__(0)
CommonJS 中,如果不对 module 进行缓存有什么问题,即不实现以上的 __webpack_module_cache__
数据结构
阅读 webpack 模块加载器代码,我们在 CommonJS 中使用 module.exports
与 exports
有何区别
module.exports 是访问 module 的 exports 属性的值,exports 是该值的引用,即类似于const exports=module.exports
如何理解 webpack 运行时代码最后是 __webpack_require__(0)
执行打包后的 js 然后打印__webpack_modules__
发现 0 的位置是空的
所以其实 0 只是一个预留位置
解释成是储存入口模块可能更容易理解
且因为__webpack_modules__
是根据文件的依赖关系进行深度优先遍历得来的数组,所以根节点即入口文件即 0 位置的模块