一直以来,前端工程中的配置大多都是 .js
文件或者 .json
文件,最常见的比如:
这些配置对前端非常友好,因为都是我们熟悉的 JS 对象结构。一般静态化的配置会选择 json 文件,而动态化的配置,涉及到引入其他模块,因此会选择 js 文件。
还有现在许多新工具同时支持多种配置,比如 Eslint
,两种格式的配置任你选择:
后来不知道什么时候,突然出现了一种以 .yaml
或 .yml
为后缀的配置文件。一开始以为是某个程序的专有配置,后来发现这个后缀的文件出现的频率越来越高,甚至 Eslint 也支持了第三种格式的配置 .eslintrc.yml
。
既然遇到了,那就探索它!
下面我们从 YAML 的出现背景,使用场景,具体用法,高级操作四个方面,看一下这个流行的现代化配置的神秘之处。
一个新工具的出现避免不了有两个原因:
YAML 这种新工具就属于后者。其实在 yaml 出现之前 js+json
用的也不错,也没什么特别难以处理的问题;但是 yaml 出现以后,开始觉得它好乱呀什么东西,后来了解它后,越用越喜欢,一个字就是优雅。
很多文章说选择 yaml 是因为 json 的各种问题,json 不适合做配置文件,这我觉得有些言过其实了。我更愿意将 yaml 看做是 json 的升级,因为 yaml 在格式简化和体验上表现确实不错,这个得承认。
下面我们对比 YAML 和 JSON,从两方面分析:
JSON 比较繁琐的地方是它严格的格式要求。比如这个对象:
{
name: 'ruims'
}
在 JSON 中以下写法通通都是错的:
// key 没引号不行
{
name: 'ruims'
}
// key 不是 "" 号不行
{
'name': 'ruims'
}
// value 不是 "" 号不行
{
"name": 'ruims'
}
字符串的值必须 k->v 都是 ""
才行:
// 只能这样
{
"name": "ruims"
}
虽然是统一格式,但是使用上确实有不便利的地方。比如我在浏览器上测出了接口错误。然后把参数拷贝到 Postman 里调试,这时就我要手动给每个属性和值加 "" 号,非常繁琐。
YAML 则是另辟蹊径,直接把字符串符号干掉了。上面对象的同等 yaml 配置如下:
name: ruims
没错,就这么简单!
除了 ""
号,yaml 觉得 {}
和 []
这种符号也是多余的,不如一起干掉。
于是呢,以这个对象数组为例:
{
"names": [
{ "name": "ruims" },
{ "name": "ruidoc" }
]
}
转换成 yaml 是这样的:
names:
- name: ruims
- name: ruidoc
对比一下这个精简程度,有什么理由不爱它?
说起增加的部分,最值得一提的,是 YAML 支持了 注释
。
用 JSON 写配置是不能有注释的,这就意味着我们的配置不会有备注,配置多了会非常凌乱,这是最不人性化的地方。
现在 yaml 支持了备注,以后配置可以是这样的:
# 应用名称
name: my_app
# 应用端口
port: 8080
把这种配置丢给新同事,还怕他看不懂配了啥吗?
除注释外,还支持配置复用的相关功能,这个后面说。
我接触的第一个 yaml 配置是 Flutter 项目的包管理文件 pubspec.yaml
,这个文件的作用和前端项目中的 package.json
一样,用于存放一些全局配置和应用依赖的包和版本。
看一下它的基本结构:
name: flutter_demo
description: A new Flutter project.
publish_to: 'none'
version: 1.0.0
dependencies:
cupertino_icons: ^1.0.2
dev_dependencies:
flutter_lints: ^1.0.0
你看这个结构和 package.json
是不是基本一致?dependencies
下列出应用依赖和版本,dev_dependencies
下的则是开发依赖。
后来在做 CI/CD 自动化部署的时候,我们用到了 GitHub Action。它需要多个 yaml 文件来定义不同的工作流,这个配置可比 flutter 复杂的多。
其实不光 GitHub Action,其他流行的类似的构建工具如 GitLab CI/CD,circleci,全部都是齐刷刷的 yaml 配置,因此如果你的项目要做 CI/CD 持续集成,不懂 yaml 语法肯定是不行的。
还有,接触过 Docker 的同学肯定知道 Docker Compose,它是 Docker 官方的单机编排工具,其配置文件 docker-compose.yml
也是妥妥的 yaml 格式。现在 Docker 正是如日中天的时候,使用 Docker 必然免不了编排,因此 yaml 语法早晚也要攻克。
上面说的这 3 个案例,几乎都是现代最新最流行的框架/工具。从它们身上可以看出来,yaml 必然是下一代配置文件的标准,并且是前端-后端-运维的通用标准。
说了这么多,你跃跃欲试了吗?下面我们详细介绍 yaml 语法。
介绍 yaml 语法会对比 json 解释,以便我们快速理解。
先看一下 yaml 的几个特点:
#
表示注释相比于 JSON 来说,最大的区别是用 缩进
来表示层级,这个和 Python 非常接近。还有强化的一点是支持了注释,JSON 默认是不支持的(虽然 TS 支持),这也对配置文件非常重要。
YAML 支持以下几种数据结构:
对象
:json 中的对象数组
:json 中的数组纯量
:json 中的简单类型(字符串,数值,布尔等)先看对象,上一个 json 例子:
{
"id": 1,
"name": "杨成功",
"isman": true
}
转换成 yaml:
id: 1
name: 杨成功
isman: true
对象是最核心的结构,key 值的表示方法是 [key]:
,注意这里冒号后面有个空格,一定不能少。value 的值就是一个纯量
,且默认不需要引号。
数组和对象的结构差不多,区别是在 key 前用一个 -
符号标识这个是数组项。注意这里也有一个空格,同样也不能少。
- hello
- world
转换成 JSON 格式如下:
["hello", "world"]
了解了基本的对象和数组,我们再来看一个复杂的结构。
众所周知,在实际项目配置中很少有简单的对象或数组,大多都是对象和数组相互嵌套而成。在 js 中我们称之为对象数组,而在 yaml 中我们叫 复合结构
。
比如这样一个稍复杂的 JSON:
{
"name": "杨成功",
"isman": true,
"age": 25,
"tag": ["阳光", "帅气"],
"address": [
{ "c": "北京", "a": "海淀区" },
{ "c": "天津", "a": "滨海新区" }
]
}
转换成复合结构的 YAML:
name: 杨成功
isman: true
age: 25
tag:
- 阳光
- 帅气
address:
- c: 北京
a: 海淀区
- c: 天津
a: 滨海新区
若你想尝试更复杂结构的转换,可以在 这个 网页中在线实践。
纯量比较简单,对应的就是 js 的基本数据类型,支持如下:
比较特殊的两个,null 用 ~
符号表示,时间大多用 2021-12-21
这种格式表示,如:
who: ~
date: 2019-09-10
转换成 JS 后:
{
who: null,
date: new Date('2019-09-10')
}
在 yaml 实战过程中,遇到过一些特殊场景,可能需要一些特殊的处理。
在 shell 中我们常见到一些参数很多,然后特别长的命令,如果命令都写在一行的话可读性会非常差。
假设下面的是一条长命令:
$ docker run --name my-nginx -d nginx
在 linux 中可以这样处理:
$ docker run \
--name my-nginx \
-d nginx
就是在每行后加 \
符号标识换行。然而在 YAML 中更简单,不需要加任何符号,直接换行即可:
cmd: docker run
--name my-nginx
-d nginx
YAML 默认会把换行符转换成空格
,因此转换后 JSON 如下,正是我们需要的:
{ "cmd": "docker run --name my-nginx -d nginx" }
然而有时候,我们的需求是保留换行符,并不是把它转换成空格,又该怎么办呢?
这个也简单,只需要在首行加一个 |
符号:
cmd: |
docker run
--name my-nginx
-d nginx
转换成 JSON 变成了这样:
{ "cmd": "docker run\n--name my-nginx\n-d nginx" }
获取配置是指,在 YAML 文件中定义的某个配置,如何在代码(JS)里获取?
比如前端在 package.json
里有一个 version
的配置项表示应用版本,我们要在代码中获取版本,可以这么写:
import pack from './package.json'
console.log(pack.version)
JSON 是可以直接导入的,YAML 可就不行了,那怎么办呢?我们分环境解析:
在浏览器中
浏览器中代码用 webapck 打包,因此加一个 loader 即可:
$ yarn add -D yaml-loader
然后配置 loader:
// webpack.config.js
module.exports = {
module: {
rules: [
{
test: /\.ya?ml$/,
type: 'json', // Required by Webpack v4
use: 'yaml-loader'
}
]
}
}
在组件中使用:
import pack from './package.yaml'
console.log(pack.version)
在 Node.js 中
Node.js 环境下没有 Webpack,因此读取 yaml 配置的方法也不一样。
首先安装一个 js-yaml
模块:
$ yarn add js-yaml
然后通过模块提供的方法获取:
const yaml = require('js-yaml')
const fs = require('fs')
const doc = yaml.load(fs.readFileSync('./package.yaml', 'utf8'))
console.log(doc.version)
配置项复用的意思是,对于定义过的配置,在后面的配置直接引用,而不是再写一遍,从而达到复用的目的。
YAML 中将定义的复用项称为锚点,用&
标识;引用锚点则用 *
标识。
name: &name my_config
env: &env
version: 1.0
compose:
key1: *name
key2: *env
对应的 JSON 如下:
{
"name": "my_config",
"env": { "version": 1 },
"compose": { "key1": "my_config", "key2": { "version": 1 } }
}
但是锚点有个弊端,就是不能作为 变量
在字符串中使用。比如:
name: &name my_config
compose:
key1: *name
key2: my name is *name
此时 key2 的值就是普通字符串 my name is *name,引用变得无效了。
其实在实际开发中,字符串中使用变量还是很常见的。比如在复杂的命令中多次使用某个路径,这个时候这个路径就应该是一个变量,在多个命令中复用。
GitHub Action 中有这样的支持,定义一个环境变量,然后在其他的地方复用:
env:
NAME: test
describe: This app is called ${NAME}
这种实现方式与 webpack 中使用环境变量类似,在构建的时候将变量替换成对应的字符串。
本文由哈喽比特于2年以前收录,如有侵权请联系我们。
文章来源:https://mp.weixin.qq.com/s/BtPwgKkugFmYgWOxphPNaA
京东创始人刘强东和其妻子章泽天最近成为了互联网舆论关注的焦点。有关他们“移民美国”和在美国购买豪宅的传言在互联网上广泛传播。然而,京东官方通过微博发言人发布的消息澄清了这些传言,称这些言论纯属虚假信息和蓄意捏造。
日前,据博主“@超能数码君老周”爆料,国内三大运营商中国移动、中国电信和中国联通预计将集体采购百万台规模的华为Mate60系列手机。
据报道,荷兰半导体设备公司ASML正看到美国对华遏制政策的负面影响。阿斯麦(ASML)CEO彼得·温宁克在一档电视节目中分享了他对中国大陆问题以及该公司面临的出口管制和保护主义的看法。彼得曾在多个场合表达了他对出口管制以及中荷经济关系的担忧。
今年早些时候,抖音悄然上线了一款名为“青桃”的 App,Slogan 为“看见你的热爱”,根据应用介绍可知,“青桃”是一个属于年轻人的兴趣知识视频平台,由抖音官方出品的中长视频关联版本,整体风格有些类似B站。
日前,威马汽车首席数据官梅松林转发了一份“世界各国地区拥车率排行榜”,同时,他发文表示:中国汽车普及率低于非洲国家尼日利亚,每百户家庭仅17户有车。意大利世界排名第一,每十户中九户有车。
近日,一项新的研究发现,维生素 C 和 E 等抗氧化剂会激活一种机制,刺激癌症肿瘤中新血管的生长,帮助它们生长和扩散。
据媒体援引消息人士报道,苹果公司正在测试使用3D打印技术来生产其智能手表的钢质底盘。消息传出后,3D系统一度大涨超10%,不过截至周三收盘,该股涨幅回落至2%以内。
9月2日,坐拥千万粉丝的网红主播“秀才”账号被封禁,在社交媒体平台上引发热议。平台相关负责人表示,“秀才”账号违反平台相关规定,已封禁。据知情人士透露,秀才近期被举报存在违法行为,这可能是他被封禁的部分原因。据悉,“秀才”年龄39岁,是安徽省亳州市蒙城县人,抖音网红,粉丝数量超1200万。他曾被称为“中老年...
9月3日消息,亚马逊的一些股东,包括持有该公司股票的一家养老基金,日前对亚马逊、其创始人贝索斯和其董事会提起诉讼,指控他们在为 Project Kuiper 卫星星座项目购买发射服务时“违反了信义义务”。
据消息,为推广自家应用,苹果现推出了一个名为“Apps by Apple”的网站,展示了苹果为旗下产品(如 iPhone、iPad、Apple Watch、Mac 和 Apple TV)开发的各种应用程序。
特斯拉本周在美国大幅下调Model S和X售价,引发了该公司一些最坚定支持者的不满。知名特斯拉多头、未来基金(Future Fund)管理合伙人加里·布莱克发帖称,降价是一种“短期麻醉剂”,会让潜在客户等待进一步降价。
据外媒9月2日报道,荷兰半导体设备制造商阿斯麦称,尽管荷兰政府颁布的半导体设备出口管制新规9月正式生效,但该公司已获得在2023年底以前向中国运送受限制芯片制造机器的许可。
近日,根据美国证券交易委员会的文件显示,苹果卫星服务提供商 Globalstar 近期向马斯克旗下的 SpaceX 支付 6400 万美元(约 4.65 亿元人民币)。用于在 2023-2025 年期间,发射卫星,进一步扩展苹果 iPhone 系列的 SOS 卫星服务。
据报道,马斯克旗下社交平台𝕏(推特)日前调整了隐私政策,允许 𝕏 使用用户发布的信息来训练其人工智能(AI)模型。新的隐私政策将于 9 月 29 日生效。新政策规定,𝕏可能会使用所收集到的平台信息和公开可用的信息,来帮助训练 𝕏 的机器学习或人工智能模型。
9月2日,荣耀CEO赵明在采访中谈及华为手机回归时表示,替老同事们高兴,觉得手机行业,由于华为的回归,让竞争充满了更多的可能性和更多的魅力,对行业来说也是件好事。
《自然》30日发表的一篇论文报道了一个名为Swift的人工智能(AI)系统,该系统驾驶无人机的能力可在真实世界中一对一冠军赛里战胜人类对手。
近日,非营利组织纽约真菌学会(NYMS)发出警告,表示亚马逊为代表的电商平台上,充斥着各种AI生成的蘑菇觅食科普书籍,其中存在诸多错误。
社交媒体平台𝕏(原推特)新隐私政策提到:“在您同意的情况下,我们可能出于安全、安保和身份识别目的收集和使用您的生物识别信息。”
2023年德国柏林消费电子展上,各大企业都带来了最新的理念和产品,而高端化、本土化的中国产品正在不断吸引欧洲等国际市场的目光。
罗永浩日前在直播中吐槽苹果即将推出的 iPhone 新品,具体内容为:“以我对我‘子公司’的了解,我认为 iPhone 15 跟 iPhone 14 不会有什么区别的,除了序(列)号变了,这个‘不要脸’的东西,这个‘臭厨子’。