热门推荐
2024年最全如何阅读源码 —— 以 Vetur 为例,2024年最新字节面试官
2024-10-31 18:46

ES6

2024年最全如何阅读源码 —— 以 Vetur 为例,2024年最新字节面试官

  • 列举常用的ES6特性

  • 箭头函数需要注意哪些地方

  • let、const、var

  • 拓展:var方式定义的变量有什么样的bug

  • Set数据结构

  • 拓展:数组去重的方法

  • 箭头函数this的指向。

  • 手写ES6 class继承。

微信小程序

  • 简单描述一下微信小程序的相关文件类型?

  • 你是怎么封装微信小程序的数据请求

  • 有哪些参数传值的方法

  • 你使用过哪些方法,来提高微信小程序的应用速度

  • 小程序和原生App哪个好

  • 简述微信小程序原理

  • 分析微信小程序的优劣势

  • 怎么解决小程序的异步请求问题

其他知识点面试

  • webpack的原理

  • webpack的loader和plugin的区别

  • 怎么使用webpack对项目进行优化?

  • 防抖、节流

  • 浏览器的缓存机制

  • 描述一下二叉树, 并说明二叉树的几种遍历方式?

  • 项目类问题

  • 笔试编程题

最后

技术栈比较搭,基本用过的东西都是一模一样的。快手终面喜欢问智力题,校招也是终面问智力题,大家要准备一下一些经典智力题。如果排列组合、概率论这些基础忘了,建议回去补一下。

“contributes”: {

“grammars”: [

“language”: “vue”,

“scopeName”: “source.vue”,

“path”: “./syntaxes/vue-generated.json”,

“embeddedLanguages”: {

“text.html.basic”: “html”,

“language”: “vue-postcss”,

“scopeName”: “source.css.postcss”,

“path”: “./syntaxes/vue-postcss.json”

]

同样的,我们先查一下官网对 配置项的解释

Contribute a TextMate grammar to a language. You must provide the this grammar applies to, the TextMate for the grammar and the file path.

这段描述略微复杂,大意是开发者可以通过 属性提供关于语言的 TextMate 形式的语法描述, 配置项包含三个属性

  • :语言的名称

  • :语言的分类,与 TextMate 同义,可用于嵌套语法定义

  • :语言的词法规则文件

这里面 属性指向一个内容更复杂的配置文件 ,我们可以接着打开其中任意一个文件,关键内容结构如下

“name”: “Vue HTML”,

“scopeName”: “text.html.vue-html”,

“fileTypes”: [],

“uuid”: “ca2e4260-5d62-45bf-8cf1-d8b5cc19c8f8”,

“patterns”: [

“name”: “meta.tag.any.html”,

“begin”: “(<)([A-Z][a-zA-Z0-9:-])(?=[^>]></2>)”,

“beginCaptures”: {

“1”: {

“name”: “punctuation.definition.tag.begin.html”

“2”: {

“name”: “support.class.component.html”

],

“repository”: {

按照 Syntax Highlight Guide(https://zjsms.com/e7E5Jdq/) 一节的说法这里面最重要的是 属性,而 属性最关键的功能就是以正则语句表达语言的词法分析规则,并分配词法对应的 命名,详细的配置规则还可以继续参考 TextMate 官网,这里大致理解作用即可,先不展开深究。

探索 配置

接着往下看,第三个值得关注的是 属性,在 vetur 中对应的值为

“main”: “./dist/vueMain.js”

VS Code 官网对 属性的解释非常精简「The entry point to your extension」,也就是插件的入口,通常需要指向到可执行的 JS 文件,插件启动时 VS Code 会执行这个入口文件导出的 方法,内容框架大致为

import vscode from ‘vscode’;

export async function activate(context: vscode.ExtensionContext) {

// … 启动逻辑

在 Vetur 中, 函数定义在 文件,分析源码可知该函数主要完成如下事项

  • 调用 方法注册一系列命令

  • 调用 方法初始化 LSP Client 对象

这两个操作具体的作用,我们先按下不表,后面再展开。

小结

对入口的分析就到这里了,我们先总结、记录下关键信息

  • Vetur 本质上是一个 VS Code 插件,所有配置 —— 包括入口都记录在 文件中

  • Vetur 包含三种启动入口

    • :定义一些简单的语言基本配置,包括怎么折叠,怎么注释
  • :定义了一套基于 TextMate 引擎的词法规则,用于实现代码高亮

  • :定义了插件的启动入口,入口中注册了一系列命令,同时创建了基于 LSP 协议的 Language Client 对象,而 LSP 协议用于实现如代码补全、错误诊断、跳转定义等高级特性

到这里,虽然我们还是不了解 Vetur 的实现细节,但是对 Vetur 的背景知识与项目结构应该已经有了一个比较基础的认知,已经能大致识别哪些功能由哪些模块实现。

OK,这里先保持好这个模模糊糊的认知就行了,不要花太多时间。

基础依赖分析

接下来,需要梳理一下 Vetur 的基础依赖,这一步的作用是帮助我们理解 Vetur 可能用到哪些基础技术,比如用到哪些工程化工具、怎么编译、怎么检查代码等。

Vetur 的 文件主要包含三类信息

  • VS Code 插件配置信息,大体上在上一节都有描述,这里不展开

  • 工程化命令,核心有

    • :对应命令为 ,由此可以推断 Vetur 基于 Rollup 实现构建
  • :功能与 相似

  • :对应命令为 ,由此可以推断 Vetur 基于 实现代码检查

  • 项目的 依赖,主要包含 typescript、tslint、rollup、vscode-languageclient、husky、mocha、vscode-test、prettier

那么,从这些信息我们基本可以推断出如下信息

  • Vetur 使用 Rollup + typescript 等工具执行构建工作,按常理执行 命令应该就能启动一个持续的构建工作进程

  • Vetur 使用 tslint 实现代码检查,配合 huscky + prettier 完成格式化工作

  • Vetur 使用 mocha + vscode-test 实现自动化测试

文件结构

接着,还需要稍微展开看看 Vetur 的文件结构,这一步能够一定程度上帮助我们理解 Vetur 的代码架构及要素,推测各种特性是在什么位置实现的。Vetur 的文件结构大致上如下

vetur

├─ .vscode

├─ build

├─ client

│  ├─ client.ts

│  ├─ commands

│  ├─ grammar.ts

├─ languages

│  ├─ vue-html-language-configuration.json

├─ scripts

│  ├─ build_grammar.ts

│  └─ tsconfig.json

├─ server

│  ├─ .gitignore

│  ├─ .mocharc.yml

│  ├─ .npmrc

│  │  └─ vls

├─ syntaxes

│  ├─ markdown-vue.json

│  ├─ pug

│  └─ vue.yaml

├─ test

├─ vti

│  ├─ README.md

│  │  └─ vti

│  ├─ tsconfig.json

│  └─ yarn.lock

├─ tsconfig.options.json

├─ package.json

├─ …

└─ yarn.lock

其中,比较关键的有

  • :VS Code 插件的入口代码, 文件中 字段会指向这个目录的产物

  • :LSP 架构中的 Server 端,上述 会通过 LSP 协议与这个 目录通信

  • :Vetur 的词法规则文件夹,内部包含许多 JSON 格式,符合 TextMate 规则的词法声明

  • :Vetur 提供的语言配置信息,规则比较简单,了解作用即可,不必深入

  • :按 文件可以推断,这里是 Vetur 的命令行工具,不在主流程内可以先忽略

  • :按内容可以推断这是 Vetur 的介绍文档,此处可忽略

  • :构建命令, 文件的 命令有一些会指向这个目录,可以忽略

  • 一系列基础配置文件,包括 、 等,可先忽略

我们还可以继续往下探索各个子目录的内容,但是注意浅尝辄止即可,后面随着源码阅读的深入,读者对各个目录的理解应该会不断迭代增长,现在没必要花太多时间。

小结

回顾一下,我们首先学习了一些背景知识,之后花了一些时间分析项目的入口、基础依赖、文件结构,到这里我们基本上可以推断出

  • Vetur 是一个语言插件,所以必然是使用 「词法高亮、Language API、Language Server Protocol」 三类技术实现核心逻辑的,而 文件中的 配置项的内容也恰好验证了这一点

  • 「词法高亮」 相关的代码集中在 文件夹

  • 「Language Server Protocol」 相关的代码集中在 与 文件夹

  • 可以用 命令持续构建,配合 F5 快捷键启动调试

这些信息是后续分析源码的必要条件,而这个过程跟学习一门新语言很类似,读者可以回想一下最开始学习 Javascript 的时候,有经验的学习者不会一上来马上深入诸如原型、变量提升、事件循环等语言细节,而是先以更高层、更抽象的视角学习 Javascript 语言的基本骨架,包括函数、循环语句、分支判断语句、对象等,从而构建起一个抽象的结构化认知,后续再慢慢填充细节,有点自顶向下的味道。

设定切入点

在对项目背景与结构有基本了解之后,我们可以正式开始分析源码了。首先,读者要找到一个匹配自身状态和需求的切入点,本质上就是将大目标拆解成一系列小目标,将大问题拆解成一系列更具体的小问题,然后带着具体问题更聚焦地去看代码。

所谓切入点可以直接对标到框架的具体功能,或者某些底层机制的实现上,以 Vetur 为例,它实现了诸多辅助开发 Vue SFC 组件的特性,包括代码补全、错误诊断、代码高亮、跳转到定义、hover 提示等等,这里面任意一个展开来都有大量可以挖掘的空间,如果从一开始就漫无目的瞎逛乱看那铁定是看不出个所以然的,鉴于我的目标就是想通过 Vetur 学习 VS Code 插件的开发套路,所以选择了一个看起来比较简单的特性「代码补全」 作为第一个切入点,后续的学习经历证明这是一个非常合适的点,不复杂但是已经能帮我窥见 Vetur 的核心工作机制,以此类推后面分析其它高级特性如代码高亮、代码补全等,基本上就是很轻车熟路的状态了。

如果你有一些更明确的目的,比如解决某个具体的 bug,那你应该会更容易 get 到当下最需要做的事情;如果始终抓不到要点,那么建议先回到前面“了解背景知识”或“理解项目结构”的步骤,继续探索一些上下文信息,再试试问自己:我接下来到底应该先了解哪些具体功能的实现逻辑

记住,这并不是一锤子买卖,如果你在后续的分析过程中发现这个切入点变得越来越复杂,超出最开始的预期,不要有心理负担,这再正常不过了,而且反而侧面表现出你对问题域有越来越少的理解了,可以回过头来重新调整目标,找一个更小的切入点。

善用搜索引擎

定下切入点后,首先要做的不是打开代码咔咔就干,而应该首先试试在社区搜索相关的资料,毕竟自媒体时代了,很多开源框架的知识已经被无数人吃透、捏碎、重组成各种维度的文章,顺着这些文章的思路去理解源码会比完全靠自己摸索效率高很多。

列举几种我常用的搜索渠道

  • 谷歌 and 百度一类的搜索引擎,体感上谷歌的搜索质量会好很多,不过有一定的英语门槛

  • 开源项目的官网、社区、wiki、github 等官方渠道,通常都会有比较不错的资料

  • Segmentfault、知乎、掘金、公众号等垂直社区

  • 国外的 Medium/StackOverflow 社区,质量极高,很多大佬在上面活跃

假如搜了一通找不到答案,可以试试不同的关键词组合,我经常用的关键词有

  • Xxx 源码解析

  • Xxx 原理

  • 如何实现 xxx

假如还是找不到,还可以试试换一个意思接近的关键词,绕点弯路。总之就是想尽办法找到有用的,适合当下问题的信息,帮助读者更快更平滑地深入研究源码,这一步对新手尤为重要。

顺便推销一下我的公 众号: 【Tecvan】,长期聚焦各类前端框架源码的研读解析,欢迎订阅。

分析关键流程

前面说了一大通,到这里终于要开始正儿八经地深入研究代码了。

其实源码分析的过程特别像侦探电影,最开始你需要面对一堆凌乱,看起来相关又不太相关的线索,侦探需要从这千头万绪中找出唯一事实答案,这个过程通常有两种行之有效的做法,一是自顶向下,从时间线、流程的角度出发归纳出大致的事件框架,之后再深入研究细节,由抽象到具体;一是自底向上,找到疑点再往上逐层推敲,梳理出事件的全貌,由具体到抽象。

两种方式各有适用场景,如果出于学习目的,就是想了解某些功能特性的实现原理的话,就应该自定向下,从应用入口出发逐步向下跟踪梳理出执行流程,理解大框架之后深挖具体细节;而如果是追查单一 bug 的时候就应该找到出问题的地方,自底向上追溯出全貌再加以更改。

我个人会更倾向于自顶向下的方式,例如我在学习 Vetur 的时候,首先是选定了 「代码补全」 这一类功能作为切入点,之后从 开始一路沿着主流程向下逐级探索,最终到达实际执行代码补全的位置,虽然实际学习过程没有现在说的这么顺利,但最终还是慢慢推导出了这样一个流程图

这个流程图非常重要,它基本上让我理透 Vetur 的两个重要阶段

  • 启动阶段, 类型会初始化化 对象,之后再监听各类 LSP 事件

  • 执行阶段,LSP 事件触发时, 会将事件直接委托给 对象处理,而 会做两件事情

    • 针对 SFC 文件做 region 切割,解析出 、、 等区块
  • 针对不同区块,调用 对象的 函数处理

基于这个流程图,逻辑上可以推断出「所有 LSP 请求最终都会按照代码的类型流转到相应的」 「文件夹上」,例如

  • 对于 的格式化请求,最终会流转到 文件的 函数做处理

  • 对于 的格式化请求,则流转到 文件的 函数

  • 同理可以推导出包括代码补全、hover 提示、跳转到定义、错误诊断等等高级特性上

这个发现让整个 Vetur 的代码架构变得很扁平,后续研究具体特性的时候可以跳过前面这一对 LSP 请求的处理、分割步骤,直接找到对应的 代码。

那么,如何分析代码的执行流程呢?我个人总结的方法有两个「静态猜想」 + 「动态验证」,放在下一节细讲。

局部深入

经历前面一系列步骤,储备了足够的背景知识与框架认知后,我们可以开始逐行分析源码,了解每一行、每一个变量、每一个函数、每一个模块的具体作用与实现了。接下来我会介绍两种行之有效的方法论

  • 「静态猜想」:“读”源码,从面上理解代码逻辑并作出猜想

  • 「动态验证」:“运行”源码,借用 debug 工具逐行跟踪代码执行过程,必要时可以改动原有代码,验证猜想

这两种方法并不泾渭分明,通常是一边看代码,一边做推测,有疑点马上运行起来验证猜想是否正确,灵活配合使用效果更佳。

静态分析 —— 做猜想

所谓的静态分析,说白了就是逐行逐句分析代码,研究每一个变量、每一个过程的作用,是一个特别吃基础知识和信息检索能力的苦力活。虽然每个框架的实现细节不一样,但还是有一些普适的技巧可以讨论一下

  • 函数层面,关注输入输出及副作用

    • 函数接受什么结构的参数,这些参数经过函数内部的每一条语句之后会发生什么变化,或者如何影响语句的执行
  • 函数执行完毕之后,会返回什么结构的结果,这些结果下一步会被谁消费,影响谁的执行逻辑

  • 特别的,有不少库的函数实现有明显的“副作用”,不是那么“纯”,包括 Webpack、Vetur、Eslint 等 —— 这会急剧提升理解成本,所以阅读的时候多留个心眼

  • 分支语句中,优先关注主流程,分支流程很容易增加心智负担,到后面就不认得谁是谁了

  • 对于循环语句,通常可以关注循环之前的状态与之后的状态,通过这些变化推断循环的作用

  • 对于变量与子函数,根据命名推断作用,通常不必过度细究

  • 跳过参数校验、错误处理等分支逻辑,抓主流程!抓重点

  • 谨记你要研究的切入点,遇到特别复杂的子模块,先大致理解功能,点到为止,记下这个硬骨头回头再作为一个新的切入点继续研究

  • 学点常用的设计模式,工厂、装饰器、代理等等,这些模式的使用率非常高

结合这些技巧,在分析过程中读者应该还是会遇到很多推测和问题:这个函数是干什么的;这个语句太复杂了,看不懂;这个循环太多 side effect 了,捋不出重点。有问题是好事,证明你开始能看出端倪了,这个时候就需要将框架运行起来,并且逐步、动态地观察代码的流转,验证你的猜想或者问题。

动态分析 —— 验证猜想

经历前面静态阅读代码后,相信读者已经有一些对代码逻辑的基本推断与问题,接下来就需要运行框架,在任何有疑问的地方添加断点,观察执行栈、参数变化、环境变化、逻辑分支语句,确定输入参数是如何确定的,输出结果又会被谁消费。

不过,要修改、运行起一个开源框架可能并不容易,通常需要关注三个点

  • 如果框架已经接入了一些工程化工具,需要弄清楚如何将源码编译为运行产物,例如 Vetur 项目接入了 tsc + rollup,对应的命令为

  • 如何启动调试模式,例如 Vetur 场景下需要借用 VS Code 的 配置文件 + F5 命令启动调试;而对于前端框架如 Vue、React,通常打开浏览器的 DevTool 面板即可

  • 如何插入调试语句,前端或 Node 场景下通常添加 语句即可

如果一段代码你运行不起来,那么你大概率是无法掌握它的,所以我才会在前面“「了解背景知识」”一节特意强调需要了解项目的入口、启动、调试方法,而一旦掌握了调试技能,那这份代码在你面前就相当于脱掉了所有外装,可以逐行、逐句观察代码逻辑的动态流转。

常用算法面试题

前端基础面试题
内容主要包括HTML,CSS,Javascript,浏览器,性能优化

概率是无法掌握它的,所以我才会在前面“「了解背景知识」”一节特意强调需要了解项目的入口、启动、调试方法,而一旦掌握了调试技能,那这份代码在你面前就相当于脱掉了所有外装,可以逐行、逐句观察代码逻辑的动态流转。

  • [外链图片转存中…(img-GGPU1hYc-1715680232149)]
    以上就是本篇文章【2024年最全如何阅读源码 —— 以 Vetur 为例,2024年最新字节面试官】的全部内容了,欢迎阅览 ! 文章地址:http://lianchengexpo.xrbh.cn/quote/12348.html 
     行业      资讯      企业新闻      行情      企业黄页      同类资讯      网站地图      返回首页 迅博思语资讯移动站 http://lianchengexpo.xrbh.cn/mobile/ , 查看更多