Vetur 插件 是一个 VS Code 上的 Vue 插件,提供了代码补全、高亮等功能。今天看了一下代码,记录一下 Vetur 插件是如何做到 Script 部分自动补全的。

<!—- more —->

不同区域的处理

首先说一下 Vetur 是如何对 Vue 的每一部分进行高亮的。在 Vetur 的 Language Server 中,实现了一个 LanguageModes (server/src/embeddedSupport/languageModes.ts)类:

Untitled.png

这个 LanguageModes 类中实现了 getModeAtPosition 方法,也就是根据文档当前所处的位置,返回不同的 mode。

mode 是用于处理不同语言的一系列工具方法:

Untitled.png

他们是在 init 中进行初始化的。比如 vue-html 处理 template 部分,javascript、typescript 处理 script 部分。

这些 mode 的主要作用其实就是识别出语言,然后调用这些语言的方法来进行高亮、补全等操作。

可以看到 javascript、typescript、tsx 都使用的同一个 jsMode,他们的内部都是使用的 TypeScript 库来实现的。

jsMode定义在 server/src/modes/script/javascript.ts 中,它有这些方法:

Untitled.png

从名字就可以看出大部分方法的功能,其中 doComplete 方法就是用于代码补全的。

Untitled.png

这个方法的代码是这样的,其中 service.getCompletionsAtPosition 方法就是用于获取所有补全选项的,这个 service 其实就是 TypeScript 自身,getCompletionsAtPosition 是 TypeScript 的一个 API:https://github.com/Microsoft/TypeScript/wiki/Using-the-Language-Service-API

所以我们可以看到,Vetur 中对于 script 部分的代码补全,是依赖 TypeScript 来实现的,依赖两个工作:

  • 识别这部分是 js、ts
  • 有 Vue 的类型信息

extend Vue 时

我们知道 .vue 文件中的 script 其实不只有一种写法,可以这么写:

Untitled.png

也可以这么写:

Untitled.png

第一种写法使用了 Vue.extend 方法,那么只需要标记出 script 使用 jsMode 来处理,TypeScript 就可以根据 Vue.extend 方法来获取到类型信息,进而给出代码补全。

但是在第二种写法中,单单凭借 script 中的代码,是不能推断出类型信息的,Vetur 是如何实现的呢?

直接 export default 时的实现

在这种情况下,Vetur 会讲 script 部分的代码进行预处理,预处理代码在:server/src/services/typescriptService/preprocess.ts

Untitled.png

这里注释写的听清楚的,经过处理后,代码实际变成了这样:

Untitled.png

vue-editor-bridge 是 Vetur 中实现的一个工具库,目的就是给 export default 出的对象增加类型信息。

这样通过 __vueEditorBridge 增加类型信息后,TypeScript 就可以正确返回代码补全内容了。

TypeScript 本身提供了一些 Compiler API,可以生成 TypeScript 代码对应的 AST 等操作。作为官方提供的编译工具,也可以说是目前唯一可用的工具了。TypeScript 官方有一个介绍 Compiler API 的 Wiki,但这个文档内容较少,还很晦涩,这里补充一些基本概念和使用例子。

阅读全文 »

最近在看《七周七语言》这本书,其中有讲到 Prolog,感觉它跟平时自己用到的语言完全不同,是声明式的编程语言,因此安装尝试了一下。

阅读全文 »

WSL 全称为 Windows Subsystem for Linux,是一个为在 Windows 10 上能够原生运行 Linux 二进制可执行文件(ELF格式)的兼容层。微软早在 16 年就推出了 WSL,前一阵更是发布了 WSL 2.0,现在想必已经相对完善了。最近我在自己的 Windows 笔记本上安装了 WSL 并进行了体验,总体来说体验很棒,下面是具体的内容。

阅读全文 »

PWA(Progressive Web App) 可以使得 Web 站点拥有类似 Native App 的使用体验,虽然已经推出一段时间,但目前来看,PWA 离真正的 Native App 还有一个重要的差别,那就是进入应用商店。Trusted Web Activity 的发布,使得将 PWA 站点打包为 Native App 放入应用商店有了更好的体验。为什么要把一个 Web 站点放入应用商店呢?如何做呢?

阅读全文 »
0%