Webpack 进阶之源码分析(三)

本文基于webpack 接收的参数 options 为非数组讨论,且只讨论 webpack 主流程。
上一篇文章主要讲了 Tapable,顺带提了 webpack 方法执行流程,但是只是一笔带过,这篇文章会大致了解 webpack 方法的执行流程。

本文深入度不够,有些地方讲的不够深。理解深入后,会再次重写,弥补不够深入的遗憾。

对参数进一步转换

方法内部首先对 options 进行校验,接下来便对 options 进行处理,对一些 webpack 需要的参数,又未设置的参数,进行初始化操作。

options = new WebpackOptionsDefaulter().process(options);

实例化 Compiler

实例化 Compiler,并传入 context,也就是当前工作目录,并在实例化生成的对象 compiler 上挂载 options

准备工作

  1. 注入 NodeEnvironmentPlugin 插件,并给 compiler 对象赋予对象读写能力。具体源码解析可以看这里,作者分析的十分详细。
  2. 注入 options 上定义的 plugins
  3. 调用 WebpackOptionsApply.js 文件的 process 方法。在方法内,主要处理 4 件事情。
    • 根据 options 注入内置插件,并对 options 做进一步的转换。
    • 调用 entryOption 生命周期函数,收集 webpack 配置的入口信息。
    • 调用 afterPlugins 生命周期函数。
    • 调用 afterResolvers 生命周期函数。

构建主流程

视情况运行 runwatch 方法,这里仅以 run 举例说明。

run

  1. 调用 beforeRun 生命周期函数清除缓存,代码位于 NodeEnvironmentPlugin 文件中。
  2. 调用 run 生命周期函数。
  3. 调用 compile 方法。

compile

  1. 通过 this.newCompilationParams() 创建 params 对象,并调用 compiler 上的 normalModuleFactorycontextModuleFactory 生命周期函数。创建的对象上存在 normalModuleFactorycontextModuleFactorycompilationDependencies 属性。
  2. 调用 beforeCompile 生命周期函数,读取 dll 中模块信息( manifest ),代码位于 DllReferencePlugin
  3. 调用 compile 生命周期函数,代码位于 DllReferencePluginExternalsPluginDelegatedPlugin
    • DllReferencePlugin 主要是用来把 manifest 文件作为 externals 来使用,并注入 ExternalModuleFactoryPluginDelegatedModuleFactoryPlugin
    • ExternalsPlugin 的注入是由于传入的 options 上有 externals,注入逻辑在 WebpackOptionsApply.js
    • DelegatedPlugin 暂未发现用在哪,不理解其作用。
  4. 通过 this.createCompilation() 方法创建 compilation 对象后,会调用 thisCompilationcompilation 两个生命周期函数。
  5. 调用 make 生命周期函数,函数内部通过调用 compilationaddEntry 方法添加入口依赖,入口依赖共有四种,分别为 MultiEntryPluginDynamicEntryPluginDllEntryPluginSingleEntryPlugin
  6. 入口依赖添加完成后,会通过调用 _addModuleChain 方法获得此模块的 moduleFactory,并调用其 create 方法,方法中调用 beforeResolve 生命周期函数,对模块位置进行解析。
  7. 调用 buildModule 函数,函数内部会调用 NormalModule 文件中的 doBuild 方法,doBuild 方法中会使用 loader-runnner 库中 runLoader 方法构建模块。
  8. 调用 compilation 对象上 seal 生命周期函数,打包 chunksassets
  9. 调用 emit 生命周期函数,输出编译文件。

最后

webpack 主流程十分复杂,有时候会发现难以理解,经常需要拜读大佬文章,耗时严重,又不知道如何描述,很是头疼。故接下来会把精力投入到 react 源码。

推荐阅读

Webpack 进阶之源码分析文章列表

https://juejin.im/post/5e256ba9f265da3dfc15a6d6

「点点赞赏,手留余香」

    还没有人赞赏,快来当第一个赞赏的人吧!
0 条回复 A 作者 M 管理员
    所有的伟大,都源于一个勇敢的开始!
欢迎您,新朋友,感谢参与互动!欢迎您 {{author}},您在本站有{{commentsCount}}条评论