仓库源文站点原文


title: VSCode 是怎么运行起来的? description: 小胡子哥的个人网站 warning: true author: 小胡子哥 tags:


之前有基于 VSCode 做二次开发的经验,约摸全投入持续了 5 个多月,开发了一个 Editor,算是超级魔改吧,虽然保留了 VSCode 的样子,但是整个板块都有比较大的调整,新增了 Webview 预览面板、Devtool 调试工具、顶部控制区、插件市场等等。

当时由于需求的实现不需要了解全部的 VSCode 源码,但是也把大部分的源码啃得差不多了,包括:

但是也有很多内容没有掌握,应该说没有太多兴趣和时间了解,包括:

这两天突然来了兴致,把之前没了解的部分源码通读了一遍,当然,仍然有一些疑惑,也仍然有一些不感兴趣的部分,后续空了会有更多的梳理,下面先贴上这两天的阅读笔记。其实我应该画图来帮助读者理解,不过以下主要是个人笔记,就懒得整理了,感兴趣的读者将就着看。

阅读的版本是 v1.37.0,是目前 VSCode 源码仓库 master 分支最新的代码。

InstantiationService

基本就是 IoC 的实现原理,以及 Service 的全局管理机制。

服务注册为可被使用的 Decorator

提供了一个泛型装饰器 createDecorator,入参是 ServiceName 和 IService,后者是泛型入参:

function createDecorator<IService>('service'): ServiceIdentifier<IService> {}

内部对 service 的实际处理是:

返回的 ServiceIdentifier,格式为:

export interface ServiceIdentifier<T> {
    (...args: any[]): void;
    type: T;
}

全局服务管理

服务的调用

入口分析

看看 VSCode 在启动前和启动时都做了哪些事情。

Code Application 启动之前

VSCode 的入口启动文件是 ./out/main.js,对应源文件目录是 ./src/vs/main.ts

Code Application 启动

入口文件是 ./src/vs/code/electron-main/app.ts,对应的类为 CodeApplication,实例化的时候做了两件事情

MainIpcServer

IPCServer 的大致原理,细节非常多,下面只是列了提纲,主要是实现了一套序列化和反序列化的协议,以及 call 调用和 listen 监听的两大逻辑。

创建 Server

/-------------------------------|------\
|             HEADER            |      |
|-------------------------------| DATA |
| TYPE | ID | ACK | DATA_LENGTH |      |
\-------------------------------|------/

连接 Server

小结

以上的分析过程,对读者的作用可能并不大,主要是逻辑过于冗长,防止自己读着读着开始迷失,把觉得比较核心的逻辑记录了下来。

如果读者想了解 VSCode 的全盘代码,有几处是必须全部理解的:

  1. InstantiationService 设计
  2. IPC Protocol 设计
  3. ExtensionHost 设计
  4. Workbench Layout 设计
  5. VSCode 的打包机制
  6. Electron 的几乎所有 API

后续空闲,我还会结合单测和自动化测试,熟悉 VSCode 整体架构,等有了内容再来分享。