# YAML

我司基础平台技术组整合了一套 cli 和相关工具，React Native、iOS、Android、Node、前端项目统一进行依赖管理、打包、提测、发布等，项目工程中有 `.yml` 文件，不太了解作用，所以本文对其进行了解和学习。

## 一、 YAML 是什么

> YAML (a recursive acronym for "YAML Ain't Markup Language") is a human-readable data-serialization language. It is commonly used for configuration files and in applications where data is being stored or transmitted. YAML targets many of the same communications applications as Extensible Markup Language (XML) but has a minimal syntax which intentionally differs from SGML .[1] It uses both Python-style indentation to indicate nesting, and a more compact format that uses [] for lists and {} for maps[1] making YAML 1.2 a superset of JSON.[2] ~[维基百科](https://en.wikipedia.org/wiki/YAML)


编程难免需要写配置文件，怎么写配置有很多种方式，XML、JSON、YAML...
YAML 是用来专门写配置文件的语言，非常简洁、强大，比 JSON 格式更简洁。
YAML 是一种人类可读的数据序列化语言，通常用于配置文件和用于存储或传输数据的应用程序中。

基本语法：

- 大小写敏感
- 使用缩进表示层级关系
- 缩进时不允许使用 Tab 键，只允许使用空格键
- 缩进的空格数目不重要，只要相同层级的元素左侧对齐即可

`#` 表示注释，从这个字符串开始到这一行结束，都会被解析器认为是注释而忽略

YAML 支持3种数据结构

- 对象：键值对的集合，又称为映射（mapping）、哈希（hashes）、字典（dictionary）
- 数组：一组按次序排列的值，又称为序列（sequence）/列表（list）
- 纯量：单个的、不可再分的值


## 二、对象

对象：一组键值对，用冒号结构表示

```yaml
hobby: coding
```

转换为 Javascript 

```Javascript
{ hobby: 'coding' }
```

Yaml 也允许另一种写法，将所有键值对写成一个行内对象

```yaml
person: { age: 24, hobby: coding, title: 资深工程师 }
```

转换为 Javascript

```Javascript
{ person: { age: 24, hobby: 'coding', title: '资深工程师' } }
```


## 三、数组

一组连词线开头的行，构成一个数组

```yml
- movie
- coding
- music
- bicycle
```

转换为 Javascript

```Javascript
[ 'movie', 'coding', 'music', 'bicycle' ]
```

数据结构的子成员是一个数组，则可以在该项下面缩进一个空格

```yml
- music
- coding
 - swift
 - Javascript
 - shell
 - php
 - ruby
 - python
- cat
- movie
```

转换为 Javascript

```Javascript
['music', ['swift', 'Javascript', 'shell', 'php', 'ruby', 'python'], 'cat', 'movie']
```

数组也可以用行内表示法

```yml
coding: [swift, Javascript, shell, php, ruby, python]
```

转换为 Javascript

```Javascript
{ coding: ['swift', 'Javascript', 'shell', 'php', 'ruby', 'python']}
```


## 四、复合结构

对象和数组可以结合使用，形成复合结构。


```yml
hobby:
 - coding
 - music
 - movie
 - bicycle
skills:
 swift: iOS
 ruby: cocoapod
 php: server
 python: spider
```

转换为 Javascript

```Javascript
{ 
    hobby: ['coding', 'music', 'movie', 'bicycle'], 
    skills: {
        swift: 'iOS',
        ruby: 'cocoapod',
        php: 'server',
        python: 'spider'
    }
}
```

## 五、纯量

纯量是最基本、不可再分的值。以下数据类型都属于 Javascript 的纯量

- 字符串
- 布尔值
- null
- 整数
- 浮点数
- 日期
- 时间

数值直接以字面量的形式表示：

```yml
number: 12.30
```



转换为 Javascript

```Javascript
{ number: 12.30}
```

布尔值用 true 和 false 表示
```yml
isDeveloper: true
```

转换为 Javascript

```Javascript
{ isDeveloper: true}
```

null 用 ～ 表示

```yml
pet: ~
```

转换为 Javascript

```Javascript
{ pet: null }
```

时间采用 ISO8601 格式

```yml
iso8601: 2019-11-27-14t21:59:43.10-05:00
```

转换为 Javascript

```Javascript
{ iso8601: new Date('2019-11-27-14t21:59:43.10-05:00') }
```

YAML 允许使用2个感叹号，强制数据类型转换。

```yml
age: !!str 24
isDeveloper: !!str true
```

转换为 Javascript

```Javascript
{ age: '24', isDeveloper: 'true' }
```

## 六、字符串

字符串是 YAML 中最常见，也是最复杂的一种数据类型。

字符串默认不使用引号表示。

```yml
str: 这是一行字符串
```

转换为 Javascript

```Javascript
{ str: '这是一行字符串' }
```

如果字符串之中包含空格或特殊字符，需要放在引号之中。

```yml
str: '内容： 字符串'
```

转换为 Javascript

```Javascript
{ str: '内容： 字符串' }
```

单引号和双引号都可以使用，双引号不会对特殊字符转义。

```yml
s1: '姓名\n杭城小刘'
s2: "姓名\n杭城小刘"
```

转换为 Javascript

```Javascript
{ s1: "姓名\\n杭城小刘", s2: "姓名\n杭城小刘" }
```

单引号之中如果还有单引号，必须连续使用2个单引号转义

```yml
str: 'labor''s day'
```

转换为 Javascript

```Javascript
{ s1: "labor's day" }
```


字符串可以写成多行，从第二行开始，必须有一个单空格缩进。换行符会被转为空格。

```yml
str: 这是第一段
 多行
 字符串
```

转换为 Javascript

```Javascript
{ str: "这是第一段 多行 字符串" }
```


多行字符串可以使用 | 保留换行符，也可以使用 > 折叠换行。

```yml
this: |
 Foo
 Bar
that: >
 Foo
 Bar
```

转换为 Javascript

```Javascript
{ this: "Foo\nBar\n", that: "Foo Bar\n" }
```

+ 表示保留文字末尾的换行，- 表示删除字符串末尾的换行

```yml
name: |
 LBP
hobby: |+
 Coding
 Movie


sports: |-
 Bicycle

```

转换为 Javascript

```Javascript
{ name: "LBP\n", hobby: "Coding\nMovie\n\n\n", sports: "Bicycle" }
```

字符串之中还可以插入 HTML 标记

```yml
message: |
 
 <p style="color:red">
  yaml
 </p>
```

转换为 Javascript

```Javascript
{message: "\n <p style="color:red">\n yaml\n</p>\n"}
```


## 七、引用

锚点 `&` 和别名 `*` 用来表示引用

```yml
engineer: &engineer
 name: 杭城小刘
 age: 24
 title: 资深工程师
iOSer:
 kind: iOS
 <<: *engineer
```

等同于下面的 yml 代码

```yml
engineer: 
 name: 杭城小刘
 age: 24
 title: 资深工程师
iOSer:
 kind: iOS
 name: 杭城小刘
 age: 24
 title: 资深工程师
```

其中： `<<` 表示合并到当前数据，`&` 用来建立锚点， `*` 用来表示引用锚点。


## 其他

1. 有个 [NodeJS 库](https://github.com/nodeca/js-yaml)可以将 YAML 函数和正则转换为 JS 对象。反过来也可以
2. [Ruby](https://yaml.org/YAML_for_ruby.html)  可以将 YAML 转换为 Ruby，反过来也可以


参考链接：

- [YAML 语言教程：阮一峰](http://www.ruanyifeng.com/blog/2016/07/yaml.html)