【连载于我的公众号:奔三程序员Club】
首先,标题起的是很标题党,不用当真。
我还在上大学的时候,《21天学会XXX》这种起名格式就在火,然后一直火到现在,经久不衰。
每当我想不到起什么名字的时候,我就想用21天前缀起名大法。
至于到底多少天,我不知道。
我想通过连载的方式来写完这个造Vue轮子的系列,只有写完了才知道到底是不是21天。
总之,我打算用正向工程,而非逆向工程的方式,帮助下想学习Vue3源码或了解下前端框架的底层技术的童鞋。
如果你自己翻Vue3的代码看不动,或者看其他的解析文章也一头雾水,可以试试跟着一步一步从头撸个像Vue3的轮子。
为什么要正向工程
从Vue1.0时代起,各种源码解析的文章就层出不穷。我不知道你们能不能耐心看完一个系列,反正我是不行。
我宁可直接去翻源码。
当然,大多数情况下,我直接翻源码的情况也很少。
我深入学习一门技术或者框架的方法,主要是造轮子,这是一个减少逆向工程含量,避免硬啃代码的好方法。
因为逆向工程是反人性的。
直接读源码以及很多源码解析文章,等于是根据结果在逆推目的。
如果你不知道当初作者为啥这么写,比如这么写是为了哪个功能,或者修复哪种情况下的bug,
你就很难理解一段代码的真正含义。
这里指的真正含义,不是指把代码翻译成人类的自然语言,而是为什么这里要这么写。
比如:
const obj = {a, b, c}
你知道,哦,此处声明了一个对象,并且对象有a,b,c等属性。
这不叫读懂代码,这叫翻译代码。
把代码由简洁的逻辑符号翻译成了相对繁琐的自然语言而已。
很多源码解析的文章也会犯类似的毛病。
当文章作者不了解某个零件在整个机器中的作用时,往往也会含糊的进行翻译式的描述:“哦,这里有个零件,等边三角形的”。
至于这个零件在这里是干什么的就不提了。为什么要是三角形的,还得是等边的呢?
导致阅读体验就不怎么好,能看懂这文章似乎还不如直接去看源码了,字数少还逻辑简洁。
但是对很多人来说,源码硬读起来又往往陷入迷茫而放弃。
单纯的,没有目的的读源码,很容易陷入只见树木,不见森林的问题中。
然后脑子里只剩下一颗颗孤立的树(比如一堆零散的函数),
但是对于整体的架构并没有宏观的把握,至于理解为什么这样设计,学到了什么,那就更别提了。
所以单纯的逆向工程式的学习,很容易陷入“学而不思则罔”。
编程像是骑自行车
还有一种更危险的情况,把看懂如何骑自行车,和会骑自行车当成了一回事。
能用语言描述出来,如何去骑自行车,和自己真正的会骑自行车是两回事。
就好比两个大二的计算机系学生,
一个单纯的把《现代操作系统》这本书背下来,脑子里模模糊糊的似乎对多线程,虚拟内存,scheduler有了概念。
一个真的自己试着在机房里做了个玩具mini操作系统,不懂得地方再查书查资料。
你觉得谁是真正的会骑自行车?
编程是像骑自行车一样,是贴近实践的工程。所以我一直都赞同这样一个观点:造轮子是最好的学习方法。
只看源码等于跳过了“因为”,直接到了“所以”。如果只停留在记住“所以”的部分,等于略过了正向工程最重要的前两步:
-
发现并且定义问题
-
设计解决问题的方式和结构
只沾了剩下的第三步代码实现,对技术水平的进阶效果有限。
关于连载计划
我想着利用空余时间,像起点网文小说连载一样,写个仿Vue3造轮子的连载,尽可能的正向工程式的说明如何造个像Vue3的前端框架。
不用担心我断更,在react引入fiber之前(v15.0前?记不清了),以及Vue1.0和2.0的源码我都在从零造轮子的驱动下读过了。
写个仿Vue3的造轮子连载,这就好像重写一遍西游记一样,原书都有,而且结局肯定也是得去雷音寺见如来。
需要权衡的主要是那些哪几个妖怪写详细点,哪几个观众不爱看的可以略过,边写边收集反响吧。
目前我主要把任务分成三大块:
-
响应模块:reactivity
-
渲染器模块:renderer
-
编译器模块:compiler
前两个模块是我肯定会详细讲完的,这属于框架的runtime。
编译器放在最后讲,甚至可能当做DLC。
因为编译器的优化得跟着runtime走,只有写过runtime,才能知道编译器得该做些什么,来优化哪些地方。
而且说实话,编译器模块对日常前端技术的涉及并不大,我猜读者们(假设真有人看)更多的都是写web前端工作的,更需要关心的是runtime里涉及到的东西。
摊煎饼式更新
虽然大纲可以从模块的角度进行划分,但是作为连载不会一个挨一个的讲,非得把reactivity写完了,单元测试全pass了,再讲下一个模块。
这不叫正向工程。
你见过摊煎饼的大妈,先划分好一个三分之一的扇形区域,把这个扇形填满,再用面填下一个扇形,最终三个扇形凑个圆饼出来的吗?披萨都不是这么造的,何况高贵的山东煎饼。
我会努力像楼下摊杂粮煎饼的大妈学习,先画个小圆,每个区域都涉及,然后一圈一圈的把小圆摊的更大,最后打上鸡蛋。
每一圈我都会在github上的repo,对应的建个新的branch出来。
这样如果你摊当前这个圆的时候有问题,可以很方便的看参考答案。
并且比较branch之间的变化,就知道新开发的功能和进度。
第一个branch我已经建好了,是最基本的开发环境(我简单的用了webpack搭的)和要跑通的第一个demo(在/playground)。
下一个章节的主要任务是,对我们要开发的这个像Vue的框架,进行整体结构的介绍,让各位有个感性上的认知。
并且让这个demo跑起来。
附上链接:
vheel:github.com/yangjiang39…