面向 Web 开发人员的 Yaml
我们这些 Web 开发人员越来越需要学习不同的领域,以便成为更优秀的专业人士,减少对他人的依赖,完成一些简单的事情。
如果您开始从事 FE 职业,您可能会看到很多.yml
文件,例如.travis.yml
(用于 Travis Build)、.gitlab-ci.yml
(用于 git lab CI)等。但是,说实话,这到底是什么?
人们为什么要使用这种文件?它有什么好处?它是如何工作的?
因此,本文的目标是向您介绍该YAML
结构,并让您在需要时更有信心理解、阅读和更改这样的文件。
毕竟,我们往往会感到非常不舒服和沮丧,我们需要做某事,但我们甚至不明白那是什么。
但首先,什么是 YAML?
根据官方网站的介绍,Yaml是:
“YAML(“YAML 不是标记语言”的递归缩写)是适用于所有编程语言的人性化数据序列化标准。”
大量用于编写配置文件,这解释了很多,对吧?
人们厌倦了一堆没人能理解的配置,直到有人说:
如果我们能以某种方式像“蛋糕食谱”那样编写我们的配置会怎么样?我的意思是,用最少的文字,非常直接?
轰隆隆,2001 年 5 月 Yaml 诞生了。
YAML 与 JSON
令人惊讶的是(或者并非如此),Yaml 是我们熟知的 JSON 的超集。
“超集是一种编程语言,它包含特定语言的所有特性,并且还进行了扩展或增强,以包含其他特性。” - Font
如果我能给你一个角度来解释它的含义,我会说:
在 FE 世界中,Yaml 适合 TypeScript,而 JSON 适合 JavaScript
为了更好地理解这是如何实现的,让我们看这个例子:
{
"compilerOptions": {
"module": "system",
"noImplicitAny": true,
"removeComments": true,
"preserveConstEnums": true,
"outFile": "../../built/local/tsc.js",
"sourceMap": false,
"types": ["node", "lodash", "express"]
},
"include": ["src/**/*"],
"exclude": ["node_modules", "**/*.spec.ts"]
}
这是一个tsconfig.json
例子。非常容易阅读,我们可以轻松识别什么是什么,但是......它有一些局限性,例如:
- 无法创建变量;
- 不能使用外部变量(例如环境变量)
- 覆盖值;
在 JS 世界中,如果我们可以创建一个.json
配置文件,我们几乎总是可以创建一个.js
(如.eslintrc
或.eslint.js
),这使我们能够减轻前面提到的缺点。
但是,如果你使用其他编程语言,JS 文件就不是一个选择。这时 Yaml 就开始发挥作用了。
如果我们必须重写tsconfig.json
语法YAML
并得到精确的结果,它将是这样的:
compilerOptions:
module: system
noImplicitAny: true
removeComments: true
preserveConstEnums: true
outFile: '../../built/local/tsc.js'
sourceMap: false
types:
- node
- lodash
- express
include:
- src/**/*
exclude:
- node_modules
- '**/*.spec.ts'
注意,这只是一个例子。你不能
tsconfig
用 YAML 来写!😜
我希望您能从这些文件中了解到一些想法。
概念、类型和语法
现在,让我们深入了解一下该语言的概念。
缩进
在 Yaml 中,缩进很重要。它使用空格缩进来嵌套信息。注意,空格tab
是不允许的。
如果你像我一样,什么都用 Tab 键,那就在 IDE 中安装一些插件,把 Tab 键替换成空格(比如editorconfig)。这样,当你按下 Tab 键时,它会自动用空格替换 Tab 键,你甚至不需要使用空格键!;)
根
由于缩进在这里很重要,如果第一个声明之前没有空格,YAML 就会理解这是文件的根(级别 0):
person:
age: 20
{
就像我们在 JSON 中第一个花括号一样:
{
"person": {
"age": 20
}
}
键/值
与 JSON/JS 类似,YAML
也使用key/value
语法,并且可以通过多种方式使用:
key: value
key_one: value one
key one: value # This works but it's weird
'my key': somekey
评论
要写评论,您只需使用#
后跟您的消息即可。
# I'm a comment
person: # I'm also a comment
age: 20
用它来记录一些决策或做笔记很酷。可惜的是,我们无法用 JSON 来实现这一点。
列表
有两种编写列表的方法:
JSON 方式:字符串数组
还记得 Yaml 是 JSON 的超集吗?我们可以使用它的语法:
people: ['Anne', 'John', 'Max']
连字符语法
最常见(也可能是推荐的)
people:
- Anne
- John
- Max
字符串
有几种方法可以在 Yaml 中声明字符串:
company: Google # Single words, no quotes
full_name: John Foo Bar Doe # Full sentence, no quotes
name: 'John' # Using single quotes
surname: "Christian Meyer" # Using double quotes
而在 JSON 中我们只有一种方法可以使用双引号:
{
"company": "Google",
"full_name": "John Foo Bar Doe",
"name": "John",
"surname": "Christian Meyer"
}
建议当您想要使用任何特殊字符(如_
、@
等)时最好使用引号。
数字
与任何编程语言一样,我们有两种类型的数字:整数和浮点数:
year: 2019 # Integer
nodeVersion: 10.8 # Float
节点锚点(变量式)
锚点是一种创建一组数据(对象)的机制,该数据组可以从其他对象注入或扩展。
假设您需要为 CI 创建一个配置。它将包含production
和staging
环境。正如您所想象的,它们共享几乎相同的基本设置。
在 JSON 世界中,我们必须重复这些配置:
{
"production": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": {
"ENVIRONMENT": "production"
}
},
"staging": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": {
"ENVIRONMENT": "staging"
}
}
}
复制和粘贴也很烦人,特别是当你必须在所有使用过这些信息的地方进行更改时。
锚点的出现解决了这个问题。我们可以:
- 首先,创建我们的锚点
# I name it as "base-config" but it can be whatever
# &base will be the "variable name" you'll use in the injection
base-config: &base
node_version: 13.0.0
os: ubuntu
package_manager: yarn
run:
- yarn install
- NODE_ENV=${ENVIRONMENT} yarn build
- 然后,注入在级别中创建的锚点,我们希望看到注入这些值:
base-config: &base
node_version: 13.0.0
os: ubuntu
package_manager: yarn
run:
- yarn install
- NODE_ENV=${ENVIRONMENT} yarn build
production:
# I'm injecting all "base" attributes and values inside production
<<: *base
env:
- ENVIRONMENT: production
staging:
# I'm injecting all "base" attributes and values inside staging
<<: *base
env:
- ENVIRONMENT: staging
看起来更简单,对吧?而且也更容易维护。
如果您复制此代码并粘贴到“Yaml 到 JSON 转换器”在线工具中,您将看到与我之前在 JSON 示例中提到的相同的代码,但在基本配置中添加了以下内容:
{
"base-config": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"]
},
"production": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": [
{
"ENVIRONMENT": "production"
}
]
},
"staging": {
"node_version": "13.0.0",
"os": "ubuntu",
"package_manager": "yarn",
"run": ["yarn install", "NODE_ENV=${ENVIRONMENT} yarn build"],
"env": [
{
"ENVIRONMENT": "staging"
}
]
}
}
JSON 语法(是的,JSON)
正如之前解释的那样,语言的超集是基础语言加上一些额外的功能,这意味着我们可以Yaml
用 JSON 方式编写文件
{
"details": {
"company": {
"name": "Google",
"year": 2019,
"active": true
},
"employees": [
"Anne",
"John",
"Max"
]
}
}
有疑问?复制此代码并粘贴到这里
如果将此 YAML 转换为 JSON,您将具有相同的结构:
{
"details": {
"company": {
"name": "Google",
"year": 2019,
"active": true
},
"employees": ["Anne", "John", "Max"]
}
}
Shell/Bash 环境
正如我在本文开头所说,非常常见的.yml
文件被用作许多事物的配置文件,尤其是对于 CI/CD 环境。
对于这些,您必须描述机器/docker 应该如何工作,应该安装、运行什么等等。
通常,所有这些环境都是 Linux,这意味着您也可以访问环境本身。
例如,在 GitLab CI 上,您可以在全局级别指定希望在整个过程中可用的环境变量:
variables:
NODE_IMAGE: node:10
stages:
- build
test:
image: $NODE_IMAGE
stage: build
请注意,使用变量的语法$
不是来自 YAML,而是shell/bash
。
GitLab CI 所做的是获取您定义的所有内容variables
并创建shell
变量。
一些其他平台还注入其他值,如提交引用、分支名称、构建时间、作者以及在配置之外定义的密钥:
variables:
NODE_IMAGE: node:10
stages:
- build
test:
image: $NODE_IMAGE
stage: build
artifacts:
name: $CI_COMMIT_REF_NAME
在上面的例子中,我们使用了$CI_COMMIT_REF_NAME
GitLab CI 平台提供的描述外部环境变量The branch or tag name for which the project is built
。
结论
我希望您现在对 YAML 有了更多的了解,并且至少可以轻松地读取和写入文件。
请记住,您能否访问哪些内容,其限制取决于您使用的平台。例如,Travis 定义的配置与 GitLab CI 或 CircleCI 不同。
请务必检查您正在使用的平台的文档,以了解哪些可以做或不可以做!:)
参考
- YAML 网站。(您可以在那里找到所有语言的解析)
- 在 Y 分钟内学习 X:YAML:这里有关于 YAML 可以为您做的一切的完整指南/介绍;
- JSON ←→ YAML 在线转换器:有助于直观地了解生成的内容并更好地理解;
- 维基百科的 YAML