21天学会写个仿Vue3的轮子:(一)系列介绍

428 阅读6分钟

【连载于我的公众号:奔三程序员Club】

首先,标题起的是很标题党,不用当真。

我还在上大学的时候,《21天学会XXX》这种起名格式就在火,然后一直火到现在,经久不衰。

每当我想不到起什么名字的时候,我就想用21天前缀起名大法。

至于到底多少天,我不知道。

我想通过连载的方式来写完这个造Vue轮子的系列,只有写完了才知道到底是不是21天。

总之,我打算用正向工程,而非逆向工程的方式,帮助下想学习Vue3源码或了解下前端框架的底层技术的童鞋。

如果你自己翻Vue3的代码看不动,或者看其他的解析文章也一头雾水,可以试试跟着一步一步从头撸个像Vue3的轮子。

为什么要正向工程

从Vue1.0时代起,各种源码解析的文章就层出不穷。我不知道你们能不能耐心看完一个系列,反正我是不行。

我宁可直接去翻源码。

当然,大多数情况下,我直接翻源码的情况也很少。

我深入学习一门技术或者框架的方法,主要是造轮子,这是一个减少逆向工程含量,避免硬啃代码的好方法。

因为逆向工程是反人性的。

直接读源码以及很多源码解析文章,等于是根据结果在逆推目的。

如果你不知道当初作者为啥这么写,比如这么写是为了哪个功能,或者修复哪种情况下的bug,

你就很难理解一段代码的真正含义。

这里指的真正含义,不是指把代码翻译成人类的自然语言,而是为什么这里要这么写。

比如: const obj = {a, b, c}

你知道,哦,此处声明了一个对象,并且对象有a,b,c等属性。

这不叫读懂代码,这叫翻译代码。

把代码由简洁的逻辑符号翻译成了相对繁琐的自然语言而已。

很多源码解析的文章也会犯类似的毛病。

当文章作者不了解某个零件在整个机器中的作用时,往往也会含糊的进行翻译式的描述:“哦,这里有个零件,等边三角形的”。

至于这个零件在这里是干什么的就不提了。为什么要是三角形的,还得是等边的呢?

导致阅读体验就不怎么好,能看懂这文章似乎还不如直接去看源码了,字数少还逻辑简洁。

但是对很多人来说,源码硬读起来又往往陷入迷茫而放弃。

单纯的,没有目的的读源码,很容易陷入只见树木,不见森林的问题中。

然后脑子里只剩下一颗颗孤立的树(比如一堆零散的函数),

但是对于整体的架构并没有宏观的把握,至于理解为什么这样设计,学到了什么,那就更别提了。

所以单纯的逆向工程式的学习,很容易陷入“学而不思则罔”。

编程像是骑自行车

还有一种更危险的情况,把看懂如何骑自行车,和会骑自行车当成了一回事。

能用语言描述出来,如何去骑自行车,和自己真正的会骑自行车是两回事。

就好比两个大二的计算机系学生,

一个单纯的把《现代操作系统》这本书背下来,脑子里模模糊糊的似乎对多线程,虚拟内存,scheduler有了概念。

一个真的自己试着在机房里做了个玩具mini操作系统,不懂得地方再查书查资料。

你觉得谁是真正的会骑自行车?

编程是像骑自行车一样,是贴近实践的工程。所以我一直都赞同这样一个观点:造轮子是最好的学习方法。

v2-7c5b94e0ca74a8bd22a74ad29d5bfaa6_r.jpg

只看源码等于跳过了“因为”,直接到了“所以”。如果只停留在记住“所以”的部分,等于略过了正向工程最重要的前两步:

  1. 发现并且定义问题

  2. 设计解决问题的方式和结构

只沾了剩下的第三步代码实现,对技术水平的进阶效果有限。

关于连载计划

我想着利用空余时间,像起点网文小说连载一样,写个仿Vue3造轮子的连载,尽可能的正向工程式的说明如何造个像Vue3的前端框架。

不用担心我断更,在react引入fiber之前(v15.0前?记不清了),以及Vue1.0和2.0的源码我都在从零造轮子的驱动下读过了。

写个仿Vue3的造轮子连载,这就好像重写一遍西游记一样,原书都有,而且结局肯定也是得去雷音寺见如来。

需要权衡的主要是那些哪几个妖怪写详细点,哪几个观众不爱看的可以略过,边写边收集反响吧。

目前我主要把任务分成三大块:

  1. 响应模块:reactivity

  2. 渲染器模块:renderer

  3. 编译器模块:compiler

前两个模块是我肯定会详细讲完的,这属于框架的runtime。

编译器放在最后讲,甚至可能当做DLC。

因为编译器的优化得跟着runtime走,只有写过runtime,才能知道编译器得该做些什么,来优化哪些地方。

而且说实话,编译器模块对日常前端技术的涉及并不大,我猜读者们(假设真有人看)更多的都是写web前端工作的,更需要关心的是runtime里涉及到的东西。

摊煎饼式更新

虽然大纲可以从模块的角度进行划分,但是作为连载不会一个挨一个的讲,非得把reactivity写完了,单元测试全pass了,再讲下一个模块。

这不叫正向工程。

你见过摊煎饼的大妈,先划分好一个三分之一的扇形区域,把这个扇形填满,再用面填下一个扇形,最终三个扇形凑个圆饼出来的吗?披萨都不是这么造的,何况高贵的山东煎饼。

微信截图_20210316220337.png

我会努力像楼下摊杂粮煎饼的大妈学习,先画个小圆,每个区域都涉及,然后一圈一圈的把小圆摊的更大,最后打上鸡蛋。

每一圈我都会在github上的repo,对应的建个新的branch出来。

这样如果你摊当前这个圆的时候有问题,可以很方便的看参考答案。

并且比较branch之间的变化,就知道新开发的功能和进度。

第一个branch我已经建好了,是最基本的开发环境(我简单的用了webpack搭的)和要跑通的第一个demo(在/playground)。

下一个章节的主要任务是,对我们要开发的这个像Vue的框架,进行整体结构的介绍,让各位有个感性上的认知。

并且让这个demo跑起来。

附上链接:

vheel:github.com/yangjiang39…