谨以此专栏向我的老板以及像他一样致力于开源繁荣的大佬致敬!
首先排除摸鱼,因为最近忙死,几乎无鱼可摸。主要两点原因吧,说来有趣:
如果你有个框架作者的老板
是种什么感觉?是的,我的老板就是框架作者!要说周会唯一开心的事儿莫过于他第一个汇报工作,他的汇报总是带着技术分享的,他总是说就是随便讲讲,你会发现他讲的都是思考,都是原理,都是源码,甚至会分析这么干的优劣,还会带着更好的实现思路。
每次请教问题,他都能非常流利的回答,甚至一些官网文档都没提及的特性,它都能如数家珍般的娓娓道来。佩服之余,我觉得我也应该再进一步!
来了我司之后是我的老板让我看到确实有一大帮人在看源码、写源码,并且将技术付诸于业务实践,并非无效卷!g
我在动笔之前,webpack v4 的前半部分源码我看了大概有5/6遍了,持续时长超过2年,中间因为种种原因被打断过好几次,看了忘,忘了看,反反复复的。此外,在 buildModule 递归收集依赖的地方总是会卡住,上周末我看了一个下午,终于递归收集依赖的部分攻克了。
看了很多很多文章,好多文章把关键点都省略掉了,这部分关键点省略之后是看不懂的,同时为了给自己定个目标也是为了好好的梳理,我决定动笔写个专栏,秉持着写只要看就能懂
的源码分享文章,把自己遇到的问题平铺直叙的写出来。
立个 FLAG,2024年内完成这个专栏,我预计应该会在 100 篇左右,预祝各位看官老爷早日成为尊贵的奥迪车主!!!
本专栏讲述的是 webpack v5.x 的源码,至于为啥不讲 webpack v4,答案很简单:我的 webpack 4 没看完😂
上 package.json 文件:
这里提一点,我们的配置是个动态的过程,我们以打包一个 bundle 为例子开始,主要分析 webpack 如何从模块变成 bundle 的过程。
在这个过程中,后面这个配置文件是会成长的,最初的配置就是下面这个样子,其中 loader 部分我们只配置了 babel-loader 和 一个我们自己写的测试 loader!
src 下的目录结构如下,index.js 是整个构建的主入口!
调试环境依旧使用我的 Webstorm 调试环境,不需要配置,开箱即用,如果你 vsc 用户,自己搜一下 vscode 配置 node.js 断点调试(我一直用 webstorm,因为真的太好用了)
你只需要在要调试的代码行号处点击一下即可,点击后行号处出现一个红点,表示断点已经生成:
webpack 调试不能通过右键 debugger 调试某个文件,因为这个文件不是入口,我们需要调试整个构建流程,因此需要以调试方式运行构建命令,你需要在 package.json 中加入 webpack 命令:
我们接下来要调试 build 这个命令,你会发现 webstorm 在 build 行号处有个绿色小三角,点击这个三角,在弹出菜单中选择 Debug 'build'
当代码运行到断点处就会停住,如下图:
在开启正式的代码阅读之前,我们需要你有以下基础知识,相信这一波就够劝退一大票人的:
Tapable
是个发布订阅的事件库。与 event-emitter 不同的是,这个库提供了一种钩子机制(Hook),相当于是个事件名。这些 hook 有的是同步的(SyncHook),有的是异步的(SsyncHook),有的是串行的(SeriesHook),有的是并行(ParallelHook)的,有的有返回(WaterfallHook)值,有的是有熔断(BailHook)的....
关于 Tapable 已经有很多文章再说了,虽然这里不再赘述,但是我们希望你有这部分基础!
webpack 生命周期
:webpack
基于 Tapable
库实现,webpack 中设计了很多 hook,这些钩子可以被任意订阅,而 webpack 的核心工作流也是通过指定的节点去触发指定 hook 来推进的。这些 hook 被称为 webpack 生命周期 hook。
plugin
:插件,上面介绍 hook 的时候说了,webpack 内部注册了很多 hook 供订阅,那么订阅这些钩子的一方实现某些固定的功能的就是一个 webpack 插件了。订阅某个流程节点钩子,webpack 当执行流推进到这个节点时,就会触发这个钩子并且传入一些重要的对象如 Compiler/Compilation/NormalModuleFactory/Parser...
本文详述了后续代码的 demo 和 webpack 源码阅读的基础: