阅读 92

任务五:Webpack源码

1、Webpack打包后文件分析

image.png

2、单文件打包源码调试

image.png

image.png

3、函数功能说明

4、CommonJS打包

5、esModule打包

6、手写功能函数

当我们使用webpack去打包,最终都会产出一个或者多个目标js文件,而在这些文件当中主要是生成一个自调用函数,这个自调用函数接收一个对象作为的参数,将它称之为模块定义,将它的键作为查询的模块id,将它的值作为要执行的函数,在执行函数的过程就完成了对应模块内容的加载。对于不同的模块类型,webpack还会使用不同的工具方法,如(r、t、n、d)

7、懒加载实现流程

image.png

8、webpack与tapable

tapable是webpack底层工具库,许多功能都与它密不可分

image.png 可以把这三个过程看作成是一种时间驱动型事件流工作机制,负责编译的complier,负责创建bundles的conmpilatuon,都是tapable的实例对象。

image.png

image.png

image.png

image.png

image.png 总结

tapable是一个独立的库,内部提供了不同的类,然后可以实例化不同的hook,hook又可分为同步和异步两大类,不管是哪一类都具备四个执行特点。

9、SyncHook

不懂

10、定位webpack打包入口

image.png

手写打包器需要复现的钩子 image.png

11、编译主流程

image.png

12、EntryOptionPlugin执行分析

image.png

13、run分析

14、compile分析

image.png

15、make前程回顾

一、步骤

  1. 实例化 compiler 对象( 它会贯穿整个webpack工作的过程 )
  2. 由 compiler 调用 run 方法

二、compiler 实例化操作

  1. 01 compiler 继承 tapable,因此它具备钩子的操作能力(监听事件,触发事件,webpack是一个事件流)

  2. 在实例化了 compiler 对象之后就往它的身上挂载很多属性,其中 NodeEnvironmentPlugin 这个操作就让它具备了文件读写的能力(我们的模拟时采用的是 node 自带的 fs )

  3. 具备了 fs 操作能力之后又将 plugins 中的插件都挂载到了 compiler 对象身上

  4. 将内部默认的插件与 compiler 建立关系,其中 EntryOptionPlugin 处理了入口模块的 id

  5. 在实例化 compiler 的时候只是监听了 make 钩子(SingleEntryPlugin)

  • 5-1 在 SingleEntryPlugin 模块的 apply 方法中有二个钩子监听
    复制代码
  • 5-2 其中 compilation 钩子就是让 compilation 具备了利用 normalModuleFactory 工厂创建一个普通模块的能力
    复制代码
  • 5-3 因为它就是利用一个自己创建的模块来加载需要被打包的模块 
    复制代码
  • 5-4 其中 make 钩子 在 compiler.run 的时候会被触发,走到这里就意味着某个模块执行打包之前的所有准备工作就完成了
    复制代码
  • 5-5 addEntry 方法调用()
    复制代码

三、run 方法执行( 当前想看的是什么时候触发了 make 钩子 )

01 run 方法里就是一堆钩子按着顺序触发(beforeRun run compile)

02 compile 方法执行 1 准备参数(其中 normalModuleFactory 是我们后续用于创建模块的) 2 触发beforeCompile 3 将第一步的参数传给一个函数,开始创建一个 compilation (newCompilation) 4 在调用 newCompilation 的内部 - 调用了 createCompilation - 触发了 this.compilation 钩子 和 compilation 钩子的监听 03 当创建了 compilation 对象之后就触发了 make 钩子

04 当我们触发 make 钩子监听的时候,将 compilation 对象传递了过去

四、总结

1 实例化 compiler
2 调用 compile 方法 3 newCompilation 4 实例化了一个compilation 对象(它和 compiler 是有关系) 5 触发 make 监听 6 addEntry 方法(这个时候就带着 context name entry 一堆的东西) 就奔着编译去了.....

16、addEntry分析

01 make 钩子在被触发的时候,接收到了 compilation 对象实现,它的身上挂载了很多内容

02 从 compilation 当中解构了三个值 entry : 当前需要被打包的模块的相对路径(./src/index.js) name: main context: 当前项目的根路径

03 dep 是对当前的入口模块中的依赖关系进行处理

04 调用了 addEntry 方法

05 在 compilation实例的身上有一个 addEntry 方法,然后内部调用了 _addModuleChain 方法,去处理依赖

06 在 compilation 当中我们可以通过 NormalModuleFactory 工厂来创建一个普通的模块对象

07 在 webpack 内部默认启了一个 100 并发量的打包操作,当前我们看到的是 normalModule.create()

08 在 beforeResolve 里面会触发一个 factory 钩子监听【 这个部分的操作其实是处理 loader, 当前我们重点去看 】

09 上述操作完成之后获取到了一个函数被存在 factory 里,然后对它进行了调用

10 在这个函数调用里又触发了一个叫 resolver 的钩子( 处理 loader的,拿到了 resolver方法就意味着所有的Loader 处理完毕 )

11 调用 resolver() 方法之后,就会进入到 afterResolve 这个钩子里,然后就会触发 new NormalModule

12 在完成上述操作之后就将module 进行了保存和一些其它属性的添加

13 调用 buildModule 方法开始编译---》 调用 build ---》doBuild

17、_addModuleChain

18、buildModule

文章分类
前端
文章标签