介绍
vscode由一个分层的、模块化的core
组成(即src/vs目录),它可以通过extensions
机制进行扩展。extensions
运行在称为extension host
的单独进程中,通过使用extensions API
去实现。
目录结构
根目录结构
1 | ├── build # gulp编译构建脚本 |
src下文件目录结构
1 | ├── bootstrap-amd.js # 子进程实际入口 |
层级
core
分为以下几层:
base
: 提供常规实用程序和用户界面构建块platform
: 为VS Code定义服务注入支持和基本服务editor
: “ Monaco”编辑器可作为单独的可下载组件使用workbench
: 托管“Monaco”编辑器,并提供“视口”的框架,例如资源管理器,状态栏或菜单栏,并利用Electron来实现VS Code桌面应用程序。
目标环境
VS Code的核心完全采用TypeScript实现。在每一层内部,代码都是由目标运行时环境组成的。这样可以确保仅使用运行时特定的API。在代码中,我们对目标环境做以下区分:
common
目录存放的是:仅需要基本的JavaScript API,并且可以运行在其他目标环境中的源代码browser
目录存放的是:需要访问browserAPI如进行DOM操作的源代码。 可以引入common
目录下的源码node
目录存放的是:引入nodejs API的源码。 可以引入common
目录下的源码electron-sandbox
目录存放的是:即需要访问browserAPI如进行DOM操作和要求浏览器API,也需要操作一小部分ElectronAPI用来和Electron主进程进行通信的源代码。 可以使用common
、browser
、electron-sandbox
目录下的源码。electro-browser
目录存放的是:引入了electron 渲染进程API的源码。 可以使用common
、browser
、node
目录文件。electron-main
目录存放的是:引入了electron主进程API的源码。 可以使用common
、node
目录源码。
依赖注入
源码是通过services
组成的,services
更多的被定义在platform
层中。Services
通过construction injection
(构造函数注入)的方式得到对应的客户端(clients)。 service
定义分为两部分: (1)(service
)服务的接口(interface
) (2)服务(service
)标识符(identifier
) 服务标识符是必需的,因为TypeScript
不使用标称类型而是结构性类型。 服务标识符是一种修饰器(针对ES7
提出),并且应与服务接口具有相同的名称。 声明服务依赖关系是通过在构造函数参数中添加相应的修饰来实现的。 在下面的代码段中,@ IModelService
是服务标识符修饰符,而IModelService
是此参数的(可选)类型注释。 如果依赖项是可选的,请使用@optional
装饰,否则实例化服务将引发错误。
1 | class Client { |
使用实例化服务为服务使用者创建实例,例如InstantiationService.createInstance(Client)
。 通常,当您注册为贡献内容(例如Viewle
或Language
)时,会为您完成此操作。
VS Code Editor的源组织
vs/editor
文件夹不应该有任何node
或electron-browser
依赖关系。vs/editor/common
和vs/editor/browser
-代码编辑器核心(若没有这些则编辑器没有任何意义)。vs/editor/contrib
-VS Code和独立编辑器中附带的代码编辑器贡献。依照browser
惯例,编辑器在缺失相关contrib
的情况下,会导致相应功能被删除。vs/editor/standalone
-仅独立编辑器附带的代码。不存在别的依赖。vs/workbench/contrib/codeEditor
-VS Code中附带的代码编辑器贡献。
工作台贡献
VS Code工作台(vs/workbench
)由许多内容组成,可提供丰富的开发经验。示例包括全文搜索,集成的git和debug。从本质上讲,工作台并不直接依赖于所有这些贡献。相反,我们使用内部(而不是真正的扩展API)机制将这些contrib
贡献给工作台。 贡献给工作台的所有贡献都存放在该vs/workbench/contrib
文件夹中。此文件夹中有一些规则:
vs/workbench/contrib
文件夹内部代码与外界没有任何依赖关系- 每个贡献都应从单个文件中公开其内部API(例如
vs/workbench/contrib/search/common/search.ts
) - 一个贡献可以取决于另一个贡献的内部API(例如git贡献可能取决于
vs/workbench/contrib/search/common/search.ts
) - 一个贡献永远都不能进入另一个贡献的内部(内部是贡献文件中不存在于单个公共API文件中的其他内容)
- 在让一个贡献依赖于另一个贡献之前要三思:这是否确实需要,是否有意义?是否可以通过使用工作台的可扩展性来避免这种依赖性呢?
- 本文标题:vscode源码组织
- 本文作者:Joyer Lee
- 创建时间:2020-12-04 14:47:07
- 本文链接:https://lhx.blog.wj2015.com/2020/12/04/工作日志/vscode源码组织/
- 版权声明:本博客所有文章除特别声明外,均采用 BY-NC-SA 许可协议。转载请注明出处!