webpack 内部模块机制

  1. import这种浏览器不认识的关键字替换成了__webpack_require__函数调用
  2. __webpack_require__在实现时采用了类似CommonJS的模块思想。
  3. 一个文件就是一个模块,对应模块缓存上的一个对象。
  4. 当模块代码执行时,会将export的内容添加到这个模块对象上。
  5. 当再次引用一个以前引用过的模块时,会直接从缓存上读取模块。 ```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);

return module.exports; } ```

打包过程

主要步骤为:依赖解析(Dependency Resolution)和 代码打包(Bundling)

Ciqc1GAOlIOAYZLfAAFmQUf14uQ501.png

  1. 读取入口文件
  2. 利用 babel 将代码解析为 AST,产出依赖列表,将代码转为 ES5
  3. 将转换后的依赖存储到一个对象中进行管理,构建出一个依赖图(Dependency Graph)
  4. 将各模块内容 bundle 产出

    CommonJS的模块规范中,Node 在对 JS 文件进行编译的过程中,会对文件中的内容进行头尾包装,在头部添加(function (export, require, modules, __filename, __dirname){``};。我们在单个JS文件内部可以使用这些参数。

代码实现

https://github.com/zxt1996/mini-webpack

资料

  1. 如何实现自己的 webpack
  2. webpack 运行机制
  3. 手写一个webpack,看看AST怎么用
  4. webpack 拍了拍你,给了你一份图解指南(模块化部分)
  5. 解析 Webpack 源码,实现自己的构建工具
  6. 实现一个简易的 webpack