20

背景

之前部门想要统一代码编辑器, 最后决定统一用 VS Code。

我之前也有写这篇文章的想法,于是就主动报了名。

所以就有了今天这篇,一篇详细介绍 VS Code 的文章。

中间参考了不少资料,如有错误,欢迎留言指出 :)

文章主要内容:

  • VS Code 概览

    • VS Code 介绍
    • VS Code 技术路线
    • VS Code 技术组成
    • VS Code 为优化性能做的努力
    • VS Code 启动速度优化
    • VS Code 代码编辑器滚动虚拟化
    • VS Code 着色速度优化
    • VS Code 多进程架构
    • 后台进程
    • 编辑器窗口
    • IO
    • 插件进程
    • Debug 进程
    • 搜索进程
  • `VSCode 技术架构与核心

    • VS Code 技术架构
    • VSCode 核心

      • 核心层
      • 核心组件
      • 核心环境
  • VS Code 语言支持
  • VS Code 插件系统

    • 语言支持
    • Debugger
    • 主题/配色方案
    • 编辑器辅助
    • 扩展命令
    • 扩展菜单
    • 快捷键
  • VS Code 插件开发

    • VSC 插件在实际项目中的运用
    • 社区里一些有趣的 VSC 插件
  • VS Code 与 Git 集成

    • Git 集成功能介绍
    • Git 提交历史记录
  • VS Code 远程开发

    • 支持的功能
    • 需要安装的插件
    • 打开远程目录与端口转发
  • VS Code 服务器端部署

    • Code Server 下载与运行
  • VS Code 开发实践

    • 我推荐的10个实用插件
  • 总结

废话不多说,我们直接开始吧。

正文

VS Code 概览

VS Code 介绍

Visual Studio Code (下面简称VSC) 是由微软公司开发的开源、免费、跨平台的代码编辑器。

微软希望它在保持核心轻量化文本编辑器的基础上,为编辑器添加项目支持智能感知编译调试

Visual Studio Code

VSC 的前身是微软基于云端的编辑器项目:Monaco 编辑器,它作为微软云服务的一部分,提供在线编辑源代码的能力。

VSC Team 由著名工程师 Erich Gamma 领导,Erich 是《设计模式》作者之一,Eclipse 之父,拥有多年的 IDE 开发经验。

Erich Gamma

由于云端编辑器的种种限制,和微软近年来对Windows外平台的态度转变,微软决定由它扩展开发为一个全平台通用的代码编辑器。

VS Code 技术路线

VSCode 采用了 Electron,使用的代码编辑器名为 Monaco

在语言上,VSCode 使用了 HTML,CSS,TypeScript 进行开发,使用 Electron 作为构建工具。

从实现上来看:

Electron = Node + Chromium + Native API

也就是说 Electron 拥有 Node 运行环境,赋予了用户与系统底层进行交互的能力。

依靠 Chromium 提供基于 Web 技术(HTML、CSS、JS)的界面交互支持,另外还具有一些平台特性,比如桌面通知等。

VS Code 技术组成

Electron

为了保护本地文件的安全性,浏览器都没有提供直接的本地文件访问权限。

为了实现本地文件系统的访问,VSC 采用了 Github 的开源项目 Electron。

Electron 原名 Atom-Shell,是 Github 为 Atom 编辑器编写的一个开源框架。

它将 Chromium 和 Node.js 完美融合,让开发者能用使用 HTML 来实现 App UI,用 Node.js API 来访问文件系统。

TypeScript

VSC 的主要代码都是用 TypeScript 编写,目前 VSC 的核心有 1100 多个 TS 文件,TypeScript 的语言优势为多次重构提供了保障。

纯 DOM 操作

为了保证 UI 响应速度,VSC 没有采用现有的 UI 库,大部分 UI 采用绝对尺寸,简单粗暴的避免大面积 UI 的联动刷新。

VS Code 为优化性能做的努力

VS Code team 做了很多工作来提高 VSC 的性能。

VS Code 启动速度优化

基于 HTML 技术的编辑器,受限于 Chrome 一般都会有启动速度慢的问题。

除了基本的 JS / CSS 合并压缩外,VSC 还将特别常用的 ActivityBar icon 直接内嵌在了 css 中。

但是即便如此,启动速度跟 Sublime Text 等编辑器还是有比较大的差距。

这里说一个技巧,当我们用 VSC 打开一个文件的时候,VSC 会默认启动一个新的 VSC 窗口,这样启动的时间比较长,我们可以通过设置全局设置项里的 window.openFilesInNewWindow: false 来使用已经打开的 VSC 实例打开新文件,这样就几乎没有了等待的时间。

VS Code 代码编辑器滚动虚拟化

让编辑器只渲染可见的部分,减小大文件编辑对浏览器的压力。

同时配合 css translate3d, 避免重复渲染没有改变的代码行。

VS Code 着色速度优化

为了不重复发明轮子,VSC 采用了跟 TextMate 一样的代码着色分析语法。

它是基于正则表达式的一套分析方案,虽然 JS 原生支持正则表达式,但为了更高的效率,VSC 使用了 C++ 编写的一套正则表达式引擎来提高效率。

VS Code 多进程架构

前面讲的这些都只是一些小的优化,真正保证响应速度的还是多进程架构带来的优势。

VS Code 多进程架构

VSC 采用多进程架构,VSC 启动后主要有下面的几个进程:

  • 后台进程
  • 编辑器窗口 - 由后台进程启动,也是多进程架构

    • HTML 编写的 UI

      • Activitybar
      • Viewlets
      • Panels
      • Editors
      • Statusbar
  • Nodejs 异步 IO

    • FileService
    • ConfigurationService
  • 插件宿主进程

    • 插件实例

      • 插件子进程 - 如 TS 语言服务
      • 插件实例
    • Debug 进程
    • Search 进程
  • 编辑器窗口

后台进程

后台进程是 VSC 的入口,主要负责管理编辑器生命周期,进程间通信,自动更新,菜单管理等。

我们启动 VSC 的时候,后台进程会首先启动,读取各种配置信息和历史记录,然后将这些信息和主窗口 UI 的 HTML 主文件路径整合成一个 URL,启动一个浏览器窗口来显示编辑器的 UI。

后台进程会一直关注 UI 进程的状态,当所有 UI 进程被关闭的时候,整个编辑器退出。

此外后台进程还会开启一个本地的 Socket,当有新的 VSC 进程启动的时候,会尝试连接这个 Socket,并将启动的参数信息传递给它,由已经存在的 VSC 来执行相关的动作,这样能够保证 VSC 的唯一性,避免出现多开文件夹带来的问题。

编辑器窗口

编辑器窗口进程负责整个 UI 的展示。

也就是我们所见的部分, UI 全部用 HTML 编写没有太多需要介绍的部分。

IO

项目文件的读取和保存由主进程的 NodeJS API 完成,因为全部是异步操作,即便有比较大的文件,也不会对 UI 造成阻塞。

IO 跟 UI 在一个进程,并采用异步操作,在保证 IO 性能的基础上也保证了 UI 的响应速度。

插件进程

每一个 UI 窗口会启动一个 NodeJS 子进程作为插件的宿主进程。所有的插件会共同运行在这个进程中。

这样设计最主要的目的就是: 避免复杂的插件系统阻塞 UI 的响应。这要从JS和浏览器说起。

在大部分的操作系统中,显示器的刷新频率是 60 帧每秒,也就是说应用需要在 16.7 毫秒内完成所有的计算和 UI 刷新。

HTML DOM 的速度向来为人诟病,留给JS的时间就更少了。所以要在这么短的时间内完成所有指令才能保证 UI 的响应速度。

但是事实上我们很难在这么短的时间内完成诸如对一万行代码进行着色这种任务。这就需要我们将这种耗时比较长的任务转移到其他的线程或进程来做,等耗时任务结束,再将结果返回给 UI 进程即可。

VSC 最近的版本中, 将所有的语言支持都改成了插件。包括之前在 UI 进程用 Web Worker 实现的 Markdown 语言支持。后面我会介绍一个典型的语言服务的工作方式。

但是将插件放在一个单独进程也有很明显的缺点,因为是一个单独的进程,而不是 UI 进程,所以没有办法直接访问 DOM 树,想要实时高效的改变 UI 变得很难,在 VSC 的扩展体系中几乎没有对 UI 进行扩展的 API。

Debug 进程

Debugger 插件跟普通的插件有一点区别,它不运行在插件进程中,而是在每次 debug 的时候由UI单独新开一个进程

搜索进程

搜索是一个十分耗时的任务,VSC 也使用的单独的进程来实现这个功能,保证主窗口的效率。

将耗时的任务分到多个进程中,有效的保证了主进程的响应速度

VSCode 技术架构与核心

VS Code 技术架构

分层架构值得我们好好学习。

源码目录结构

VSCode 核心

核心层
  • base: 提供通用服务和构建用户界面
  • platform: 注入服务和基础服务代码
  • editor: 微软 Monaco 编辑器,也可独立运行使用
  • wrokbench: 配合 Monaco 并且给 viewlets 提供框架:如:浏览器状态栏,菜单栏利用 electron 实现桌面程序
核心组件
  • Electron: 原名 Atom Shell, 是由Github 开发的开源框架。
  • Momaco Edictor: VSC 最核心的组件。
  • Typescript: Javascript 的严格超集。
  • Language Server Protocol: 语言服务器, 提供了诸如自动补全, 定义跳转,代码格式化等与编程语言相关的功能。
  • Degug Adaptor Protocol: DAP 是一个基于JSON 的协议, 他抽象了开发工具与调试工具之间的通信。
  • Xterm.js: 是一个使用TS 开发的前端组件, 它把完整的终端功能带入了浏览器,可可以与bash这样的进程相连接。

这里简单展示一下 LSP 和 DAP :

https://code.visualstudio.com/api/language-extensions/language-server-extension-guide

没有 DAP 的结构:

具备 DAP 的结构:

https://code.visualstudio.com/blogs/2018/08/07/debug-adapter-protocol-website

又一次体现了分层的思想。

核心环境

整个项目完全使用 typescript 实现,electron 中运行主进程和渲染进程,使用的 api 有所不同,所以在 core 中每个目录组织也是按照使用的 api 来安排。

运行的环境分为几类:

  • common: 只使用 javascritp api 的代码,能在任何环境下运行
  • browser: 浏览器 api, 如操作 dom; 可以调用 common
  • node: 需要使用 node 的 api,比如文件 io 操作
  • electron-brower: 渲染进程 api, 可以调用 common, brower, node, 依赖electron renderer-process API
  • electron-main: 主进程 api, 可以调用: common, node 依赖于electron main-process API

VS Code 语言支持

VS code 几乎支持所有主流的编程语言。

对于JS, TS, CSS, HTML, VS code 提供了开箱即用的支持, 但对于其他语言来说, 则需要安装相应的插件。

目前下载量最高的语言插件排行:

VS Code 插件系统

插件系统对 VSC 至关重要。

为什么 ?

在早期的版本中 VSC 并没有插件系统,只支持 TypeScript、JavaScript和C#的智能感知, 还有其余40中语言的代码着色。

所以 VSC 只是出现在微软技术的社区中。15 年 12 月份,VSC 发布了第一个支持扩展的版本。

不久之后就出现了许多其他语言的支持,比如 Go 语言、C++、Java、Python、Ruby。

所以说有了核心编辑器的极速体验,加上良好的扩展能力才成就了 VSC。

语言支持

VSC 制订了一套完善的语言支持体系,方便支持新的编程语言。

一个代码编辑器需要哪些功能来支持一种新语言?

  • 代码显示

    • 代码着色
  • 智能感知

    • 代码提示
    • 代码跳转
    • 鼠标触碰提示
    • 查找引用
    • 错误提示
  • 代码修改

    • 自动补全
    • 重构功能

兼容 TextMate 的代码着色分析

可以简单的将 TextMate 的语言着色配置文件拷贝到插件中,并在 package.json 中指定即可。

语言支持通用协议

VSC 约定了一种通用的通信协议来支持多种语言

由于 VSC 采用多进程的架构,语言的开发者可以使用自己熟悉的语言编写这门语言的语言服务,VSC 将采用 JSON-RPC 通信的方式跟语言服务沟通,执行用户命令,获取结果。

Debugger

同语言服务类似,VSC 开放了一组通用协议来满足不同语言不通平台的调试需求。

主题/配色方案

VSC 采用了跟 TextMate 相同的配色方案文件格式。

编辑器辅助

VSC 提供了编辑器操作 API,你能够实时获取用户输入点、当前文件代码。从而可以根据用户当前文档确定可以提供的快捷操作。比如自动添加不存在的方法等。

扩展命令

开发者可以在插件中定义自己的命令,这些命令会出现在“命令面板” 中,开发者可以通过 ctrl/cmd + shift + pF1 来调用这些命令,完成复杂的操作。

插件可以使用所有的 NodeJS API,配合各种 NodeJS 库,能够完成非常有想象力的功能。

扩展菜单

VSC 提供了文件管理器菜单,编辑器菜单,文件标题菜单扩展点。方便开发者针对不同的上下文进行操作。

快捷键

开发者可以为各种自定义操作指定快捷键。

VS Code 插件开发

VSC 插件开发文档: https://code.visualstudio.com...

Wing 插件开发文档: http://developer.egret.com/cn...

VSC 插件在实际项目中的运用

利用 VSC 插件,我们可以为项目定制一些效率工具, 比如:

  1. MyStock 一键下载翻译插件

这个是我写的快捷下载翻译资源的插件。

  1. WMS 翻译自动生成插件

隔壁项目的, 快捷生成翻译key的插件:

社区里一些有趣的 VSC 插件

  1. 小霸王

  1. 韭菜盒子

还有很多,就不一一列出来了。

VS Code 与 Git 集成

Git 集成功能介绍

Visual Studio Code 自带对 Git 的支持。

需要已经安装好 2.0.0(及以上)版本的 Git。

主要功能如下:

  • 在行号槽显示正在编辑的文件的改动情况
  • Git状态栏(位于左下角)会显示当前所在分支,编辑指示符以及未提交或者未拉取的提交的数量
  • 能够在编辑器内完成常用的 Git 操作:

    • 初始化一个仓库
    • 克隆一个仓库
    • 新建分支和标签
    • 暂存和提交修改
    • 对一个远程分支进行推送/拉取/同步
    • 解决合并冲突
    • 查看比较

点击克隆存储库,在弹出框输入Git远程库地址:

提交修改并推送到远程仓库(更多支持的Git命令见下图):

Git 提交历史记录

在使用git的时候,经常需要查看修改记录,或者需要查看谁提交了什么文件等,当然可以到存放git代码的目录查看,但这样很不方便,如果使用vscode编辑工具写的话,可以安装一个 git history 的工具包,如图:

然后重启 vscode,选择任何一个文件或者文件夹,右键就可以看到git:history 标签了。

点击弹出Git History页面,如下图:

VS Code 远程开发

支持的功能

VS Code 用来做远程开发,可以支持在物理机、容器以及Windows Subsystem for Linux(WSL)上实现无缝远程开发,可以做到:

  • 在部署相同的操作系统上进行开发,或者使用更大或更专业的硬件
  • 把开发环境作为沙箱,以免影响本地计算机配置
  • 让新手轻松上手,让每个人都保持一致的开发环境
  • 使用原本在本地环境不可用的工具或运行时,或者管理它们的多个版本
  • 在WSL里开发Linux应用
  • 从多台不同的计算机访问现有的开发环境
  • 调试在其它位置(比如客户网站或云端)运行的应用程序

下面是通过SSH来连接本地虚拟机,模拟远程开发的操作流程。

使用VS Code 远程连接服务器的原理如下,VS Code 会在远程主机上运行一个Server,本地通过SSH连接到远程服务器。

需要安装的插件

在VS Code 扩展页面搜索: Remote - SSH

安装了 Remote - SSH 扩展后,你会在最左边看到一个新的状态栏图标:

远程状态栏图标可以快速显示 VS Code 在哪个上下文中运行(本地或远程),点击该图标或者点击 F1 按键然后输入Remote-SSH 便会弹出 Remote-SSH 的相关命令。

选择 Remote-SSH: Connect to Host 命令,然后按以下格式输入远程主机的连接信息,连接到主机:user@hostname,然后根据提示输入登录的密码。

VSCode 将打开一个新窗口,然后你会看到 “VSCode 服务器 “正在 SSH 主机上初始化的通知,一旦 VSCode 服务器安装在远程主机上,它就可以运行扩展并与你的本地 VSCode 实例通信了。

通过查看状态栏中的指示器,可以知道已连接到虚拟机了,它显示的是虚拟机的主机名

一旦连接到远程的 SSH 主机,就可以与远程机器上的文件进行交互 ,如果打开集成终端,会发现现在是在远程的 Linux 下面了。

打开远程目录与端口转发

现在可以使用 bash shell 浏览远程主机上的文件系统,还可以使用 "文件">"打开文件夹" 浏览和打开远程目录上的文件夹。

此外,如果开发的是 WEB 应用,为了能够浏览到远程主机上的应用,我们可以利用另一个端口转发的功能来实现。

VS Code 服务器端部署

Code Server 下载与运行

Coder-server项目部署在远程服务器上,可以实现随时随地打开浏览器写代码,操作步骤如下:

  • ssh连接到服务器上
  • 下载code-server二进制版本 wget https://github.com/cdr/code-s...
  • 解压 tar -xvzf code-server-3.9.0-linux-amd64.tar.gz
  • 重命名 mv code-server-3.9.0-linux-amd64.tar.gz code-server

运行:

  • cd code-server
  • export PASSWORD="password" && ./bin/code-server --port 8080 --host 0.0.0.0

说明:

  1. 不指定密码,会默认生成一个,可以在运行后看到
  2. --port 指定端口运行
  3. --host 0.0.0.0 默认是127.0.0.1,只能本地访问,得改成0.0.0.0以外网访问

访问后效果如下(基本和本地的VS Code界面一样,只是扩展不能在线安装):

code-server的优点:

  • 高便携性:无论你在哪里,只要手边有电脑,能联网,就可以进行代码的调试。
  • 高安全性:可能有些时候你用的并不是你的电脑,但是你又不得不去完成一些分配的任务,你可以把代码从git仓库拉取到当前电脑完成,但是可能会留下一些你不想要留下的记录,云编码则是能保证你不留下痕迹。
  • 方便调试:因为是在服务器环境上运行代码,所以如果这台服务器正好是你使用的服务器的话,则你所见即所得,无需解决在后续代码部署上的环境兼容问题。
  • 高统一性:有些时候你可能需要多个团队开发同一区域的编码,但是可能你的队友们环境完全不一样甚至会因为环境配置拖慢工程,这个时候创建多个账户分发给你的队友们在服务器上进行云编程,那么可以完美解决这个问题。

code-server的缺点:

  • 对云服务器有非常高的要求:这不仅仅是对内存和cpu的要求,对网络带宽也有很大的需求。而且运行代码的加载时间相比本地vscode也是有一定的延时。
  • 没有网络就不能写代码:因为是基于浏览器和服务器之间的交互,没有网络就打不开网页。
  • 无法编写太大工程:vscode本生就是一个轻量级ide,如果你要进行一个特别大的网站开发的话,肯定是要用其他ide的,原生支持的开发插件更全面。
  • 无法调试图形化页面:也不是完全不能调试,可以通过浏览器进行访问,但是这需要你的服务器进行更大的带宽,而且代价是更高的延时,可能你只是要写一个html页面,但是每写几行就想预览效果,而code-server需要你等半天将页面从服务器发送过来,这肯定是不能和本地访问相媲美的。

VS Code 开发实践

前端实用插件推荐

  1. AutoCloseTag

  1. Bracket Pair Colorizer

  1. ESLint

...

  1. GitLens

  1. Import Cost

  1. Prettier

  1. Peacock

  1. Svg viewer

  1. Indent-rainbow

  1. Reload

总结

VS Code 是我们离不开的工具,它还有很多值得我们探索的地方, 期待你去发现。

本篇内容就这么多, 希望对你有所帮助。

才疏学浅, 如有错误, 还请指正, 谢谢。

如果觉得内容有帮助, 可以关注下我的公众号,掌握最新动态,一起学习!

image.png

参考资料


皮小蛋
8k 声望12.8k 粉丝

积跬步,至千里。