如何借助 JSON Schema 在 VS Code 中为 JSON 和 YAML 文件创建自定义自动完成功能
Visual Studio Code能够开箱即用地显示常用 JSON 和 YAML 格式配置文件的自动完成建议。
例如,如果您package.json在 VS Code 中打开了一个文件,您可以点击CTRL + Space,然后会出现一个弹出窗口,显示该文件类型所有可用字段的建议。
这非常实用,无需查阅文档即可快速了解所有可用选项。
为了实现这一点,VS Code在底层使用了JSON Schema 。
注意:其他编辑器,例如 JetBrains 系列的编辑器,也使用相同的策略来实现相同的功能,因此,虽然本文以 VS Code 为例,但其中的概念也适用于其他任何 IDE。请务必查阅它们各自的文档。
什么是JSON Schema?
JSON Schema 是一种规范,它允许您描述 JSON 文档的结构并根据该模式验证文档。
例如,可以使用以下模式来描述“人”实体:
{
"$id": "https://example.com/person.schema.json",
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "Person",
"type": "object",
"properties": {
"firstName": {
"type": "string",
"description": "The person's first name."
},
"lastName": {
"type": "string",
"description": "The person's last name."
},
"age": {
"description": "Age in years which must be equal to or greater than zero.",
"type": "integer",
"minimum": 0
}
}
}
如您所见,JSON Schema 就是一个 JSON 文档,其中包含一组特定的标签,用于描述文档结构。
这是一个非常基础的例子。您可以访问JSON Schema网站查看完整的规范。
虽然 JSON Schema 的设计初衷是用于 JSON 文件,但它也可以用于任何其他可以转换为 JSON 的文件,例如 YAML。
VS Code 使用 JSON Schema 来推断特定文件类型的文档结构,并显示相应的建议和验证。
为了向各种流行的文件类型提供自动完成功能,VS Code 利用了JSON Schema Store项目,该项目托管了 200 多种文件类型的 JSON Schema 规范。
JSON Schema Store 提供了一套非常优秀的模式集。但是,由于文件类型繁多,它当然不可能为所有类型都提供模式。
好消息是,您可以轻松创建自己的模板,并使其可供您的编辑使用。
顺便一提,JSON Schema Store 是开源的,为什么不向他们的代码库做贡献,让大家都能从中受益呢?
为了演示这一点,我们将为Hadolint(一个流行的 Dockerfile 代码检查器)创建一个模式。
Hadolint支持使用.hadolint.yaml文件进行配置。
它只允许定义两种配置:
- 忽略 - 定义要忽略的 lint 规则列表
- trustedRegistries——顾名思义,它是一个允许使用的有效 Docker 镜像仓库列表。
示例文件:
ignored:
- DL3008
trustedRegistries:
- docker.io
这是一个非常简单的结构,所以是一个很好的入门例子。
创建我们的模式
因此,我们需要为这种文件类型创建 JSON Schema 规范。
首先,我们需要了解文件结构,并找出该特定文件类型的所有可能选项。这项任务的难易程度取决于现有文档的多少。
最好的入手方式可能是查看项目文档或示例文件。有些项目会提供包含所有可能值的示例文件,您可以从中推断出模式。
对于 Hadolint,我们可以从项目 Readme中获取所需的一切。
接下来,我们将创建一个hadolint.json包含模式规范的文件。
方案将与此非常相似:
{
"$schema": "http://json-schema.org/draft-07/schema#",
"title": "JSON Schema for Hadolint, a Dockerfile linter tool",
"description": "Dockerfile linter, validate inline bash, written in Haskell",
"type": "object",
"additionalProperties": false,
"properties": {
"ignored": {
"type": "array",
"description": "A list of rules to be ignored",
"items": {
"type": "string",
"oneOf": [
{
"const": "DL3000",
"description": "Use absolute WORKDIR.",
},
{
"const": "DL3001",
"description": "For some bash commands it makes no sense running them in a Docker container like ssh, vim, shutdown, service, ps, free, top, kill, mount, ifconfig.",
},
{
"const": "DL3002",
"description": "Last user should not be root."
},
{
"const": "DL3003",
"description": "Use WORKDIR to switch to a directory.",
},
{
"const": "DL3004",
"description": "Do not use sudo as it leads to unpredictable behavior. Use a tool like gosu to enforce root.",
},
{
"const": "DL3005",
"description": "Do not use apt-get upgrade or dist-upgrade.",
}
],
"title": "Rule",
}
},
"trustedRegistries": {
"type": "array",
"description": "A list of trusted registries. Ex: docker.io",
"items": {
"type": "string"
}
}
}
}
为了便于阅读,我省略了“忽略”字段中的一些选项。
让我们来分析一下我们的架构:
"$schema": "http://json-schema.org/draft-07/schema#"
第一行描述了我们使用的模式版本。我们使用的是“Draft-07”,这是撰写本文时的最新版本。
然后我们为该模式定义“标题”和“描述”。
"title": "JSON Schema for Hadolint, a Dockerfile linter tool",
"description": "Dockerfile linter, validate inline bash, written in Haskell",
根“type”属性的值大多数时候为“object”,我们还定义了“additionalProperties”属性,其值为“false”,表示该文件不能有架构中未列出的额外属性。
“属性”字段是我们开始定义对象所有属性的地方。
正如我们所见,hadolint.yaml它有两个属性:“ignored”和“trustedRegistries”,它们都是字符串列表。
对于“trustedRegistries”,这是一个开放列表;而对于“ignored”,每个选项都必须是 Hadolint 中可用的规则之一。
“trustedRegistries”可以定义如下:
"trustedRegistries": {
"type": "array",
"description": "A list of trusted registries. Ex: docker.io",
"items": {
"type": "string"
}
}
我们将“类型”定义为“数组”,其元素类型为“字符串”。
对于“忽略”属性,情况类似,但它有一个固定的选项列表。
它可以这样定义:
"ignored": {
"type": "array",
"description": "A list of rules to be ignored",
"items": {
"type": "string",
"oneOf": [
{
"const": "DL3000",
"description": "Use absolute WORKDIR.",
},
{
"const": "DL3001",
"description": "For some bash commands it makes no sense running them in a Docker container like ssh, vim, shutdown, service, ps, free, top, kill, mount, ifconfig.",
}]
}
}
JSON Schema 也包含“enum”类型。我们原本可以使用“enum”类型代替“string”类型,并配合“oneOf”字段,但由于我们希望为每个值添加描述,而“enum”类型不支持此功能。
至此,我们的模式基本结构就完成了。
这个例子只是展示了 JSON Schema 的一些功能。你可以在 Schema Store 中看到更复杂的模式,例如gitlab-ci。
根据你要创建的架构文件的复杂程度,指定每个可用选项可能会有点枯燥,但如果你经常使用该文件,这将在将来为你节省宝贵的时间。
现在我们已经创建了架构,让我们看看如何使其在 VS Code 中可用。
在 VS Code 中启用架构
由于新架构不在架构存储中,您必须在 VS Code 中注册它。这可以在 VS Code 设置页面中完成。
由于我们要为 YAML 文件创建架构,请确保在继续之前已安装YAML扩展。
然后,转到“文件”->“首选项”->“设置”(或使用命令面板)打开设置页面并搜索yaml。
打开 YAML 扩展的设置,搜索“Yaml: Schemas”,然后点击“在 settings.json 中编辑”。
“settings.json”文件将会打开。您需要再次查找“yaml.schemas”对象。如果该对象尚不存在,则需要创建它。
此属性表示一个键值对,其中键是系统中模式文件的绝对路径,值是一个 glob 表达式,用于指定要应用该模式的文件。在我的示例中,它看起来像这样:
"yaml.schemas": {
"/home/bruno/Code/Personal/other/schemastore/src/schemas/json/hadolint.json": ".hadolint.yaml",
},
保存文件并重新加载 VS Code 以完成该过程。
如果一切按预期运行,当我们创建一个新.hadolint.yaml文件并按下 键时CTRL + Space,VS Code 应该会根据我们为该文件类型创建的架构显示建议。
请注意,VS Code 首次建立架构索引可能需要几秒钟时间。
就这样,我们刚刚为hadolint.yaml文件添加了自动补全功能。
结论
JSON Schema 为 JSON 和 YAML 文件提供了一种简单的自动完成方式,并且许多流行的编辑器(如 Visual Studio、Visual Studio Code 和 Jetbrains 系列 IDE)都开箱即用地支持它。
JSON Schema Store 托管了许多流行文件格式的模式,但您也可以创建自己的模式,如本文所示。
只需按照 JSON 模式规范创建一个描述文件的模式,然后将其导入到编辑器中即可。
为复杂文件创建模式的过程可能有点痛苦和枯燥,但最终,如果你经常处理这种文件类型,我认为生产力的提升是值得的。
我希望这周就能完成 Hadolint schema 并向 Schema Store 提交一个 PR。
感谢阅读,如有任何疑问,欢迎在评论区留言。
另外,如果你喜欢我的内容,可以请我喝杯咖啡哦;)
文章来源:https://dev.to/brpaz/how-to-create-your-own-auto-completion-for-json-and-yaml-files-on-vs-code-with-the-help-of-json-schema-k1i


