webpack和webpack-cli是npm包,运行于node环境,执行打包操作时会执行:

    • window环境下,执行yarn webpack实际查找了 node_modules/.bin/webpack.cmd 文件并执行
    • webpack.cmd 内根据安装的cli(两种webpack-cli,webpack-command),实现不同处理逻辑。
    • 我们安装了webpack-cli,因此根据代码 require 了 node_modules/webpack-cli/package.json 中的 bin 入口文件,也就是 ./bin/cli.js
    • cli.js 是个 cli 执行命令行, 内部是 IIFE 函数
      • 函数主要作用处理用户交互信息,require(“webpack”)并调用了 webpack(options)
      • 实例化 Compiler.js类,赋给 compiler变量,compiler继承 tapable 库,贯穿整个编译流程(一般运行文件Compile.js都存在/lib目录下)
      • 给 compiler 设置 Node 文件读写能力
      • 给 compiler 循环挂载 我们自定义的 plugins
      • 处理 webpack内部默认插件,其中最重要的是入口插件 EntryOptionPlugin, 此实例对象主要作用是 埋下一个 make 钩子监听
      • 给 make钩子 回调内部添加 compilation.addEntry 方法,此时钩子回调并未触发,addEntry也不会执行, 重要!
    • 条件处理完成,钩子也埋完后。调用 实例对象 run 方法,即 compiler.run,重要!
      • run方法内部执行 compile 编译方法,compile 方法会 根据 compiler实例 创建一个 compilation 实例,compilation 继承自 tapable库
      • 实例化后,触发上面埋的 make 钩子,执行上面埋的 make 钩子的回调,并传入初始化的 compilation 实例对象
      • 此时执行 compilation.addEntry, 执行模块编译和打包生成dist的操作都在这个方法内, 重要!
      • addEntry 内会 以 normalModuleFactory 模板创建一个 NormalModule 标准模块
      • normalModuleFactory 类模板中有一些操作, (build方法, dobuild方法, 读取内容方法),用于操作编译我们写的模块
      • 此时一个 标准的 NormalModule模块被创建,执行buildMoudle,操作 NormalModule 模块
      • 主要操作就是 读取文件内容,操作 ast 语法树修改文件内容(例如:require改成webpack_require,以及内部的文件引用路径)
      • 将修改后的内容写回到文件中,执行回调,也就是 afterBuild 方法
      • 在afterBuild中我们会判断当前修改的模块是否有依赖,递归判断,将模块的依赖项也进行上述修改
      • 将模块和模块依赖修改后,执行回调,处理chunk问题,模块和模块依赖之间有chunk的关系,同一chunk可以有多个模块,
      • 当前所有的入口模块都被存放在了 compilation 对象的 entries 数组里
      • 所谓封装 chunk 指的就是依据某个入口,然后找到它的所有依赖,将它们的源代码放在一起,之后再做合并
      • 跟谁合并?跟ejs模板文件合并,生成 dist/bundle.js 文件