想看源码但是无从下口怎么办?

news/2024/11/15 6:11:04/文章来源:https://www.cnblogs.com/heavenYJJ/p/18301249

前言

相信不少同学都有欧阳这种情况,年初的时候给自己制定了一份关于学习英语源码的详细年度计划。但是到了实际执行的时候因为各种情况制定的计划基本都没有完成,年底回顾时发现年初制定的计划基本都没完成。痛定思痛,第二年年初决定再次制定一份学习英语源码的详细年度计划,毫无疑问又失败了。

经过多年的摸索,对于如何查看源码欧阳终于有了一些自己的心得。有的同学还想问英语有什么心得没,不要问,再问欧阳哭给你看。

关注公众号:【前端欧阳】,给自己一个进阶vue的机会

一看源码就头晕

网上有一种说法是从头开始看,假如源码是一个线团,那么找到线团的头子,顺着头子向下捋就能将源码了解的七七八八了。

这种方法对于查看小项目的源码是没有问题,因为小项目的分支逻辑不多,复杂度也不高,顺着线团的头子向下捋确实能够搞清楚整个项目。

但是对于vue这种大型项目就不适用了,大型项目里面的分支逻辑特别多,而且每个分支的复杂度也很高。大型项目的源码就像是一棵树,那么我们找的线团的头子只是这棵树的根节点。

看源码的时候你从树的根节点向下走,下面有多个子节点。选了一个子节点接着向下走,结果发现这个子节点下面又有多个子节点。再次选了一个子节点向下走,结果发现还是有很多子节点,重复几次后你可能就把自己给搞的头晕了。

出现这个问题的原因是你查看源码的时候没有一个明确的目标,因为大型项目的源码分支流程是超级多的。没有明确的目标一头扎进源码中就会迷失在源码的海洋中,这个明确的目标就是我们查看vue源码要搞清楚的问题。

如何接手一个复杂的新项目

想想你平时接手一个不熟悉并且很复杂的新项目你会怎么办?

我的做法是先查看项目的README.md,了解项目是如何运行起来的。

然后再查看项目的目录,对整个项目的结构有一点了解。

接着就是找到了解项目的测试或者产品,让他给我讲讲项目的大体流程和重要概念,这个时候可能听不懂或者听了就忘了,没关系,有个印象就可以了。

最后就是接到项目的迭代需求,从需求对应的代码出发开始了解项目。等需求做得足够多时,基本就将整个项目的代码过了一遍,此时我们已经完全接手这个项目了。

像接手新项目一样搞清楚源码

我们这里以vue举例,vue其实也是一个普通的js项目。本质上和我们的工作中接手的新项目没什么区别,对于查看vue源码我们也可以复用上面这个套路。

第一步:查看contributing.md文件

查看源码的contributing.md文件,这个文件就像是我们项目中的README.md。开源项目希望更多的人参与进来所以一般都会有个contributing.md文件。这个文件里面会教你源码项目是如何跑起来,项目结构是什么样的,怎么参与进来开发。

第二步:查看源码结构

第二步和接手新项目是一样的,查看vue源码的目录,让你对整个vue源码的结构有一些了解。

第三步:对源码大体流程和重要概念有初步印象

到了第三步就有问题了,不可能叫尤大充当测试或者产品的角色过来给我讲vue的大体流程和重要概念吧?此时我们可以换个思路,网上有很多讲解vue源码的文章或者书籍。可以让这些源码文章或者书籍充当测试和产品的角色。通过阅读这些vue源码文章或者书籍,你就能对vue的大体流程和重要概念有了初步的印象。

网上的文章都参差不齐,如何挑选出优质文章呢?

以掘金为例,你就在掘金上面去搜索vue源码。然后找出时间最近的,点赞和收藏最多的文章,这样找出来的文章基本都是优质且未过时文章(墙裂推荐欧阳的vue源码文章)。

当然如果你在之前没有接触过vue源码,第一次看vue源码文章或者书籍可能看不懂或者比较吃力。没关系,我们这一步只是让你对vue源码有个初步的印象就可以了。

第四步:带着问题去debug源码

直到这一步之前我们所做的事情都是让自己对源码有个大致的印象,最终想要看得懂源码还是得要自己上手去debug。

做项目时我们是通过不断的做业务需求,从而了解整个项目。在vue源码这里就是从一个你想要了解的具体问题出发,通过debug调试vue源码将这个问题搞清楚。这个问题就是我们在查看源码时的目标,和这个问题不相关的源码全部都忽略。

这种情况你带着问题去debug查看源码,此时的源码对于你来说就不是一棵树了,而是围绕着这个问题的一条线。我们的目标也很单纯,只是将这条线上面的源码搞清楚就行了。当你把这个问题搞清楚了后,在你的脑子里面关于vue源码就有一条线了。

还有一个进阶玩法,将“通过debug源码把某个问题搞清楚的过程”用自己的话说出来,这就形成了一篇优秀的源码文章,欧阳的所有源码文章都是这样写出来的

每个问题在我们脑子里都是一条关于vue源码的一条线,当我们搞清楚足够多问题时,这些线连到一起就形成了一棵vue源码树。

看到这里有的小伙伴就有疑问了,那么问题又从哪里来啊?

我们每天写代码就在用vue,vue提供了很多黑魔法,难道你对这些黑魔法不感兴趣吗?

举个例子,在vue的文档中有写defineProps是一个宏函数。所以我们使用他的时候不需要从vue中import导入,那么你有没有好奇过为什么他不需要从vue中import导入呢?

为了搞清楚这个问题,我们需要先找到线团的线头子。而这个线头子毫无疑问就是@vitejs/plugin-vue插件,vue文件就是由这个插件处理的。给这个线头子打上断点,顺着断点向下走,只关心和defineProps相关的代码。最终我们就找到在一个compileScript函数中,会将源代码中的defineProps宏函数给remove掉,并且同时会生成一个props属性,由于defineProps宏函数经过编译后已经被remove掉了,所以就不需要从vue中import导入。

我们知道vue是一个编译时和运行时同时存在的框架,编译时说白了就是代码运行在nodejs阶段,运行时代码跑在在浏览器中。所以在debug源码的时候有时是在编译时进行,有时是在运行时进行。

在接下来的文章中我们会给你讲一些编译时和运行时debug源码的小技巧,如果你有更好用的技巧欢迎在评论区留言。

编译时debug源码小技巧

想要在编译时debug源码,首先我们需要启动一个debug终端。这里以vscode举例,打开终端然后点击终端中的+号旁边的下拉箭头,在下拉中点击Javascript Debug Terminal就可以启动一个debug终端。
debug-terminal

在debug终端执行对应的启动命令,比如yarn dev,断点将会停留在我们打断点的代码处。此时会有这样一排操作按钮,如下图:
step

上面的一排操作按钮欧阳平时debug源码时一般就使用了前四个,分别是:Continue(继续)、Step Over(单步跳过)、Step Into(单步调试)、Step Out(单步跳出)。

  • 第一个按钮Continue(继续):点击这个按钮后会让代码执行到下一个断点。

  • 第二个按钮Step Over(单步跳过):执行到下一条语句,如果下一条语句是函数,不会走进函数内部。

  • 第三个按钮Step Into(单步调试):执行到下一条语句,如果下一条语句是函数,将会走进函数内部。

  • 第四个按钮Step Out(单步跳出):跳出当前函数内部,断点将会走到外部调用当前函数的地方。

不一定每个问题你都能找到对应的线头子,这时你就不知道从哪里开始打断点了。比如还是defineProps宏函数,假如你不知道应该从@vitejs/plugin-vue插件开始打断点,那这种情况我们应该怎么办呢?

答案很简单,在源码中去搜索defineProps关键字,将搜索到的结果都打上断点。然后启动项目,发现代码走进了我们打的断点中,如下图:
call-stack

此时左侧的Call Stack调用栈就能派上用场了,他里面存了当前函数的所有调用栈。比如当前断点是停留在processDefineProps函数中,从Call Stack调用栈我们就能知道这个函数就是由compileScript调用的,而compileScript函数又是由resolveScript函数调用的。并且可以通过点击函数名就可以跳转到对应的函数中,并且恢复当时的上下文。

整个Call Stack调用栈是一条线,我们要找的问题的线头子就在这条线中。我们带着问题去debug源码的时候只需要将在Call Stack调用栈中,线头子后面的一系列函数逻辑搞清楚就行了。

运行时debug源码小技巧

大家都知道vue文件经过编译后会变成js文件,那么如何找到编译后的js文件给他打上断点呢?
network

很简单在network面板中找到对应的请求,这里我想找的是index.vue文件。然后右键,在弹出的菜单中选择第一个Open In Sources Panel。浏览器将会切换到source面板中,并且自动打开编译后的index.vue文件,然后我们就可以在这个文件中给对应的代码打断点。

关于Continue、Step Over这几个按钮,还有Call Stack调用栈都是和编译时是一样的,在这里我们就不赘述了,欢迎补充其他小技巧。

总结

大型项目的源码可以理解为是一棵树,如果我们直接从树的根节点开始去看源码肯定会被源码的各种分支逻辑搞的头晕。此时我们可以换个思路,按照以下四步去查看源码:

  • 查看源码的contributing.md文件,这个文件里面会教你源码项目是如何跑起来,项目结构是什么样的,怎么参与进来开发。

  • 通过查看源码目录让你对源码结构有个初步的印象。

  • 通过查看源码文章或者书籍让你对源码大体流程和重要概念有初步印象。

  • 带着你想要了解的问题去debug调试源码,和问题不相关的源码全部忽略掉。此时的源码就不再是一棵树,而是一条线,我们只需要将这条线的源码搞清楚就行了。当我们搞清楚足够多问题时,这些线将会汇聚成一棵树。

关注公众号:【前端欧阳】,给自己一个进阶vue的机会

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.hqwc.cn/news/743940.html

如若内容造成侵权/违法违规/事实不符,请联系编程知识网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

C++11标准库 互斥锁 mutex 梳理

目录<mutex>std::call_once函数例程:使用call_once实现的单例模式std::mutex类 -- 独占互斥锁成员函数std::recursive_mutex类 -- 递归互斥锁使用注意:描述:std::timed_mutex类 -- 超时互斥锁描述:成员函数:std::recursive_timed_mutex类std::lock_guard模板类函数原型:s…

【译】The danger of TaskCompletionSource class

来自 Sergey Tepliakov的另一篇 https://devblogs.microsoft.com/premier-developer/the-danger-of-taskcompletionsourcet-class/#comments当使用async/await时,如果您想手动控制任务的生存期,TaskCompletionSource<T>类是一个非常有用的工具。下面是TaskCompletionSo…

Windows版PostgreSQL数据库下载及安装教程(关系型数据库管理系统)

前言 PostgreSQL是一个功能非常强大的、源代码开放的客户/服务器关系型数据库管理系统(RDBMS)。PostgreSQL最初设想于1986年,当时被叫做Berkley Postgres Project。该项目一直到1994年都处于演进和修改中,直到开发人员Andrew Yu和Jolly Chen在Postgres中添加了一个SQL(Str…

异构数据源数据同步 → 从源码分析 DataX 敏感信息的加解密

开心一刻 出门扔垃圾,看到一大爷摔地上了 过去问大爷:我账户余额 0.8,能扶你起来不 大爷往旁边挪了挪 跟我说到:孩子,快,你也躺下,这个来钱快! 我没理大爷,径直去扔了垃圾 然后飞速的躺在了大爷旁边,说道:感觉大爷带飞!书接上回 通过 异构数据源同步之数据同步 → …

开源工作流设计器(流程设计器)哪个好

本文重点介绍,基于activiti、flowable、camunda开源工作流引擎,如何选择一个开源免费的流程设计器,进行集成和扩展开发,快速交付项目使用。大家在开发OA办公自动化、ERP、CRM、BPM、低代码平台等项目的时候,经常用到流程引擎,目前主流的开源流程引擎有activiti、flowable…

如何设计应用系统的数据权限管理

在开发应用系统时,都离不开权限的设计,权限设计 = 功能权限 + 数据权限。而功能权限,在业界常常是基于RBAC(Role-Based Access Control)的一套方案。而数据权限,则根据不同的业务场景,则权限设计不尽相同,可以有不同的技术解决方案。按照应用系统权限类型划分,可进一步…

【进阶篇】一文搞清楚网页发起 HTTP 请求调用的完整过程

最近笔者在实际项目开发中会频繁涉及到服务之间的远程调用、域名的配置和请求的转发等与计算机网络相关的知识。这些其实在读本科和考研的时候都有学习过理论,但为了更透彻地掌握便于在工作中使用,我还是决定写一篇文章来分享实际开发中是怎么应用的。目录前言一、HTTP协议1.…

C++11标准库 原子变量 atomic 梳理

目录<atomic>原子操作的概念CAS实现原理CAS操作的伪代码:使用CAS完成变量的原子操作:CAS 操作的保证lock和锁的概念atomic模板类构造函数公共成员函数:atomic与互斥锁的效率比对 <atomic> C++11提供了一个原子类型std::atomic,通过这个原子类型管理的内部变量就可…

使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类就这么简单!

前言 今天大姚给大家分享一个.NET开源、免费、跨平台(支持Windows、Linux、macOS多个操作系统)的机器学习框架:ML.NET。并且本文将会带你快速使用ML.NET训练一个属于自己的图像分类模型,对图像进行分类。ML.NET框架介绍 ML.NET 允许开发人员在其 .NET 应用程序中轻松构建、…

网页交互

单击 选择元素 (html)<!DOCTYPE html> <html lang="en"> <head><meta charset="UTF-8"><meta name="viewport" content="width=device-width, initial-scale=1.0"><title>Document</title&g…

读人工智能全传13人工智能导致的问题2

读人工智能全传13人工智能导致的问题21. 机器人sha手 1.1. 自主57的话题总是带有强烈的煽动性,许多人会本能地厌恶它,认为这样的系统是不道德的,永远不该被建立 1.2. 自主57的讨论大多源于战争中使用得越来越频繁的无人机 1.3. 无人机 1.3.1. 人驾驶的飞机,在菌用领域,它可…

万字:清结算体系,全局方案深度解析

本文分享了头部支付机构是如何做清结算的,在做和带领大家打通支付的底层处理原理,内核中的内核,分享给大家。支付机构帮助交易平台代收代付交易款,那么就需要先从消费者发卡行把钱拿过来,然后再结算给交易平台;对于交易平台也是一样的道理,要帮店家卖东西,需要帮忙通过…