webpack 内部模块机制
- 将
import
这种浏览器不认识的关键字替换成了__webpack_require__
函数调用 __webpack_require__
在实现时采用了类似CommonJS
的模块思想。- 一个文件就是一个模块,对应模块缓存上的一个对象。
- 当模块代码执行时,会将
export
的内容添加到这个模块对象上。 - 当再次引用一个以前引用过的模块时,会直接从缓存上读取模块。 ```javascript // 加载完毕的所有模块。 var installedModules = {};
function webpack_require(moduleId) { // 如果模块已经加载过了,直接从Cache中读取。 if (installedModules[moduleId]) { return installedModules[moduleId].exports; }
// 创建新模块并添加到installedModules。 var module = installedModules[moduleId] = { id: moduleId, exports: {} };
// 加载模块,即运行模块的生成代码, modules[moduleId].call( module.exports, module, module.exports, webpack_require);
打包过程
主要步骤为:依赖解析(Dependency Resolution)和 代码打包(Bundling)
- 读取入口文件
- 利用 babel 将代码解析为 AST,产出依赖列表,将代码转为 ES5
- 将转换后的依赖存储到一个对象中进行管理,构建出一个依赖图(Dependency Graph)
- 将各模块内容 bundle 产出
CommonJS
的模块规范中,Node 在对 JS 文件进行编译的过程中,会对文件中的内容进行头尾包装,在头部添加(function (export, require, modules, __filename, __dirname){``};
。我们在单个JS文件内部可以使用这些参数。
代码实现
https://github.com/zxt1996/mini-webpack