1、Webpack打包后文件分析
2、单文件打包源码调试
3、函数功能说明
4、CommonJS打包
5、esModule打包
6、手写功能函数
当我们使用webpack去打包,最终都会产出一个或者多个目标js文件,而在这些文件当中主要是生成一个自调用函数,这个自调用函数接收一个对象作为的参数,将它称之为模块定义,将它的键作为查询的模块id,将它的值作为要执行的函数,在执行函数的过程就完成了对应模块内容的加载。对于不同的模块类型,webpack还会使用不同的工具方法,如(r、t、n、d)
7、懒加载实现流程
8、webpack与tapable
tapable是webpack底层工具库,许多功能都与它密不可分
可以把这三个过程看作成是一种时间驱动型事件流工作机制,负责编译的complier,负责创建bundles的conmpilatuon,都是tapable的实例对象。
总结
tapable是一个独立的库,内部提供了不同的类,然后可以实例化不同的hook,hook又可分为同步和异步两大类,不管是哪一类都具备四个执行特点。
9、SyncHook
不懂
10、定位webpack打包入口
手写打包器需要复现的钩子
11、编译主流程
12、EntryOptionPlugin执行分析
13、run分析
14、compile分析
15、make前程回顾
一、步骤
- 实例化 compiler 对象( 它会贯穿整个webpack工作的过程 )
- 由 compiler 调用 run 方法
二、compiler 实例化操作
-
01 compiler 继承 tapable,因此它具备钩子的操作能力(监听事件,触发事件,webpack是一个事件流)
-
在实例化了 compiler 对象之后就往它的身上挂载很多属性,其中 NodeEnvironmentPlugin 这个操作就让它具备了文件读写的能力(我们的模拟时采用的是 node 自带的 fs )
-
具备了 fs 操作能力之后又将 plugins 中的插件都挂载到了 compiler 对象身上
-
将内部默认的插件与 compiler 建立关系,其中 EntryOptionPlugin 处理了入口模块的 id
-
在实例化 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