webpack 的作用是将源代码编译(构建、打包)成最终代码
image.png
image.png

初始化

此阶段,webpack会将CLI参数配置文件默认配置进行融合,形成一个最终的配置对象。
对配置的处理过程是依托一个第三方库yargs完成的
此阶段相对比较简单,主要是为接下来的编译阶段做必要的准备
目前,可以简单的理解为,初始化阶段主要用于产生一个最终的配置

编译

1:创建chunk

chunk是webpack在内部构建过程中的一个概念,译为,它表示通过某个入口找到的所有依赖的统称。
根据入口模块(默认为./src/index.js)创建一个chunk
此处只规定啦一个入口文件 // 入口文件可以有多个 因此chunk可以能有多个
image.png
每个chunk都有至少两个属性:

  • name:默认为main
  • id:唯一编号,开发环境和name相同,生产环境是一个数字,从0开始

    2:构建所有依赖模块

    chunk 就是将入口文件的及入口文件的依赖文件打包到一个文件中
    image.png
    当入口有多个启动js时,chunk的工作就是将依赖入口文件依赖的关系打包成一个文件
    演示案例
    index.js ```javascript console.log(“这是index.js”) import A from “./linkA” import B from “./linkB”; console.log(B) console.log(A)
  1. linkA.js
  2. ```javascript
  3. import B from "./linkB";
  4. console.log(B)
  5. export default "这是导出的A模块"

linkB.js

  1. console.log("这是B模块")
  2. export default "这是导出的B模块";

使用上面的代码开始构建依赖模块
从如空文件开始 也就是index.js
第一步
image.png
发现并没有记录会继续下去
第二步
image.png
第三步
image.png
AST在线测试工具:https://astexplorer.net/
image.png
分析如上图 分析结果为一个树形图
第四步
image.png
dependencise 为一个数组 如下

  1. dependencise = ['./src/linkA.js','./src/linkB.js']

第五步
image.png
读取到index.js的代码为

  1. console.log("这是index.js")
  2. import A from "./linkA"
  3. import B from "./linkB";
  4. console.log(B)
  5. console.log(A)

将其替换依赖函数后为

  1. console.log("这是index.js")
  2. __webpack_require__("./src/linkA.js") // 将此处替换
  3. __webpack_require__("./src/linkB.js") // 将此处替换
  4. console.log(B)
  5. console.log(A)

第六步
image.png
记录的格式
image.png
然后递归 因为index.js 先导入入linkA.js 在导入与 linkB.js
那吗会递归加载linkA.js,按照上述步骤此次进行,会发现linkA.js 中导入啦linkB.js 那吗linkA.js结束后会如构建linkB.js 当linkB.js 结束后index.js 中的导入的了linkB.js 会进行构建,由于已经记录在第一步就停止啦。
整个项目构建后的代码

  1. 模块id : ./src/index.js
  2. 转换后的代码
  3. console.log("这是index.js")
  4. __webpack_require__("./src/linkA.js") // 将此处替换
  5. __webpack_require__("./src/linkB.js") // 将此处替换
  6. console.log(B)
  7. console.log(A)
  8. 模块id : ./src/linkA.js
  9. 转换后的代码
  10. __webpack_require__("./src/linkB.js") // 将此处替换
  11. console.log(B)
  12. export default "这是导出的A模块"
  13. 模块id : ./src/linkB.js
  14. 转换后的代码
  15. console.log("这是B模块")
  16. export default "这是导出的B模块";

构建依赖包最终的简图
image.png

3:产生chunk assets

在第二步完成后,chunk中会产生一个模块列表,列表中包含了模块id模块转换后的代码
接下来,webpack会根据配置为chunk生成一个资源列表,即chunk assets,资源列表可以理解为是生成到最终文件的文件名和文件内容
image.png
chunk hash是根据所有chunk assets的内容生成的一个hash字符串
hash:一种算法,具体有很多分类,特点是将一个任意长度的字符串转换为一个固定长度的字符串,而且可以保证原始内容不变,产生的hash字符串就不变
index.js 最终生成的文件 此处是生成一个因为我没有配置,但是也可以生成多个文件需要配置

  1. 文件名:"./dist/main.js":
  2. 文件内容: (var __webpack_modules__ = ({
  3. "./src/index.js":
  4. ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  5. eval("__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _linkA__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./linkA */ \"./src/linkA.js\");\nconsole.log(\"这是index.js\")\r\n;\r\nconsole.log(_linkA__WEBPACK_IMPORTED_MODULE_0__.default)\r\n\n\n//# sourceURL=webpack://yuanli/./src/index.js?");
  6. }),
  7. "./src/linkA.js":
  8. ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  9. eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n/* harmony import */ var _linkB__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(/*! ./linkB */ \"./src/linkB.js\");\n\r\nconsole.log(_linkB__WEBPACK_IMPORTED_MODULE_0__.default)\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (\"这是导出的A模块\");\r\n\n\n//# sourceURL=webpack://yuanli/./src/linkA.js?");
  10. }),
  11. "./src/linkB.js":
  12. ((__unused_webpack_module, __webpack_exports__, __webpack_require__) => {
  13. eval("__webpack_require__.r(__webpack_exports__);\n/* harmony export */ __webpack_require__.d(__webpack_exports__, {\n/* harmony export */ \"default\": () => __WEBPACK_DEFAULT_EXPORT__\n/* harmony export */ });\n\r\nconsole.log(\"这是B模块\")\r\n/* harmony default export */ const __WEBPACK_DEFAULT_EXPORT__ = (\"这是导出的B模块\");\r\n\n\n//# sourceURL=webpack://yuanli/./src/linkB.js?");
  14. })
  15. });

简图
image.png

4:合并chunk assets

将多个chunk的assets合并到一起,并产生一个总的hash
上面的案例中的chunk 只有一个
image.png

输出

此步骤非常简单,webpack将利用node中的fs模块(文件处理模块),根据编译产生的总的assets,生成相应的文件。
image.png

总过程

image.png
涉及术语

  1. module:模块,分割的代码单元,webpack中的模块可以是任何内容的文件,不仅限于JS
  2. chunk:webpack内部构建模块的块,一个chunk中包含多个模块,这些模块是从入口模块通过依赖分析得来的
  3. bundle:chunk构建好模块后会生成chunk的资源清单,清单中的每一项就是一个bundle,可以认为bundle就是最终生成的文件
  4. hash:最终的资源清单所有内容联合生成的hash值
  5. chunkhash:chunk生成的资源清单内容联合生成的hash值
  6. chunkname:chunk的名称,如果没有配置则使用main
  7. id:通常指chunk的唯一编号,如果在开发环境下构建,和chunkname相同;如果是生产环境下构建,则使用一个从0开始的数字进行编号

生成后的终端提示
image.png