博客:

掘金:

前言

配置文件,不言而喻,主要是我们进行项目和工程配置的文件。

如果是站在前端角度说的话,我们最常接触的就是 json以及 js类型的文件,这种形式的配置写法对前端非常友好,因为都是我们熟悉的 JS 对象结构,如:

不过,随着技术的更新迭代,也涌现出一些新的配置文件格式,相比较而言,原有的文件格式好像也变得不是那么好用了。虽然在此之前,json+js用着也不错,不过,当新的工具出现后,尤其是在你深度体验与使用之后,可能会发现事情似乎有点那么不一样了,感觉新的玩意就是好啊,也便开始嫌弃之前的家伙了~

不过,我们要站在不同角度思考问题,从新工具诞生的角度看,其诞生必然有着一定的历史背景存在,如:

旧工具在某些场景表现吃力,需要更优的替代方案

旧的写法和模式在某些场景下有着明显的短板和缺陷,需要更进一步的完善方案

背景

最近在做开源项目的时候,在开发功能时,考虑到不同场景、不同用户的不同需求,在开始设计功能时就考虑到预留一定的可定制窗口方便用户进行定制化配置。当然,在功能不断开发进行时,以及后期的迭代拓展时,都会源源不断的诞生出各种小功能和定制需求,因此,对于拥有一个足够简单、易用、拓展的配置文件是相当有必要的。

它应该具备以下基本能力:

支持注释:对于配置文件来说,注释的重要性不必多说,它需要描述每个配置字段的作用

足够简单:语法足够简单,用法足够简单,上手足够简单;至少保证新人能很快上手使用

方便读写:对于用户来说,应该是可读性非常高的,符合人类语言习惯的,概览之后可以快速上手配置

在此之前的版本,我已经针对该想法做了初步的实施落地,从个人经验来说,我之前在搞 CI/CD 自动化部署相关的东西时,写过一些 github action(配置文件为yaml格式),因此,对于yaml语法算是有些了解。

从使用感受上来说,它语法更简洁、支持注释,所以,我果断选择了yaml作为我对于项目的配置文件格式。

不过,在这段时间的使用过程中,我也发现了yaml存在的一些问题,因此,最近我又重新思考了一下下这个问题:

是继续按照传统的js文件的对象写法呢?

还是继续使用yaml作为配置文件使用呢?

还是进一步研究一些其他类型的配置文件呢?

这些配置文件类型又有啥本质区别呢?

抱着学习的心理,咱不能在遇到问题的时候就选择逃避呀,那么本篇文章也算是对不同类型配置文件的一种研究和学习了。

简单介绍JSON

JSON的定义一般是作为数据格式,它通常用于序列化、结构化数据并通过网络进行交换,通常发生在服务器与 Web 应用之间。不过也有很多工具将其作为配置文件使用。

JSON 其实完全可以当成是 JS 对象的形式进行理解、使用。

其实使用JSON作为配置文件也有其一定的优势:

语法非常简单,纯粹的键值对结构

很多编程语言的标准库都支持 JSON,比如:在JS当中你可以直接引入读取

现在几乎所有的工具都提供 JSON 支持,包括语法突出显示、自动格式化、验证工具等。

采用人类可读的轻量级文本,只需更少的编码,处理速度更快

但是,也因为其独特的定位,它天生就注定了并不适合作为配置文件使用,原因也很明显:

不支持注释:对于配置文件来说,注释的重要性不言而喻,但是JSON不支持添加注释(JSON 作为一种数据交换格式,也不需要注释)

语法过于严格:键和字符串必须使用””双引号(其实对于键来说,并不需要使用引号),结尾不允许有逗号(除了结尾都必须有逗号,哈哈~)

多余的最外层大括号:作为配置文件来说,最外层的大括号也显得有些多余(这也是其作为交换数据格式的特点,为了界定不同的对象)

虽然大家都很熟悉了,我们还是按流程看下基本用法,方便接下来做对比,如下:

{
  "name""cat",
  "desc": {
    "color""orange",
    "age"1
  }
}

可以看出JSON作为数据格式,还是比较合适且优秀的,但是作为配置文件来说,总觉得是力气使错了方向

YAML

YAML 是一种数据序列化语言,通常用于编写配置文件(它的流行和 k8s 脱不了关系~)。

语法规则:

支持的数据格式:

以下数据类型都属于 JavaScript 的纯量:

字符串、布尔值、整数、浮点数、Null、时间、日期

其特点如下:

有更好的可读性,对用户更友好

简洁和强大,写法简洁,也有复杂的语法支持不同功能

是JSON的超集,JSON 文件在 YAML 中有效

使用 Python 风格的缩进来表示嵌套

如果说到缺点的话,那和它的特点也是密不可分的

因为不是原生支持的格式,不同平台需要专门的解析工具(如:在JS中使用需要使用js-yaml解析,在线转换)

简单使用,基本语法够简单;但是进阶使用,语法就比较复杂了,对于多行字符串的处理也有待优化,尤其是结合缩进语法一起

缩进语法,如果搞错了缩进或者没看清,够你定位问题的了

按惯例,看下基本用法:

# 我是注释
name: cat
desc:
  color: orange
  age: 1
  date: 2022-09-01 16:10:01

同时上面的内容也可以这样写:

name: cat
desc: { color: orange, age: 1, date: 2022-09-01 16:10:01 } # JSON的超集

转为JS如下:


  name'cat'
  desc: { 
    color'orange'
    age1,
    date'Fri Sep 02 2022 00:10:01 GMT+0800 (中国标准时间)' // new Date
  } 
}

TOML

全称 Tom’s Obvious, Minimal Language,意为语义明显的、配置最小化的的语言。

官方描述:

为人而生的配置文件格式(好屌的感觉~)。

TOML 旨在成为一个语义明显且易于阅读的最小化配置文件格式。TOML 被设计成可以无歧义地映射为哈希表。TOML 应该能很容易地被解析成各种语言中的数据结构。

TOML 以人为先

TOML 具备实用的原生类型

TOML 受到广泛支持

语法规则:

其特点如下:

写法符合直觉、简单清晰

键名写法强大,键名可以是裸露的,引号引起来的,或点分隔的。

对字符串支持完善,基本字符串、多行基本字符串、字面量和多行字面量

表写法功能强大,键值对、数组、嵌套写法等

缺点:

不是原生支持的格式,不同平台需要专门的解析工具(如:在JS中使用需要使用@ltd/j-toml解析,在线转换)

属于比较新型的格式,社区认知度不高

新人对核心语法“表”需要适应

基本用法如下:

# 我是注释
name = "cat"

[desc]
color = "orange"
age = 1
date = 2022-09-01 16:10:01

你也可以这样写:

name = "cat"

desc.color = "orange"
desc.age = 1
desc.date = 2022-09-01 16:10:01

转为JS如下:


  name'cat'
  desc: { 
    color'orange'
    age1
    date'2022-09-01T16:10:01'
  } 
}

用法对比

其实站在配置文件的角度思考,我们最关心的就是键值对写法(一个属性控制一个功能点),谁能做到在使用时读写更方便,谁也就更具有优势。

基本上就是一个对象结构,数据类型符合字符串、对象、数组、布尔值、日期、数值也就差不多了


  "key" : value // 这里的 value 应可以是以上的任何类型
}

字符串1️⃣ 简单字符串用法2️⃣ 多行字符串

有些场景我们可能会定义很长的一段字符串,默认展示肯定是在一行显示的,这样既不好读也不好维护,尤其针对一些 shell 命令,我们在前端工程中应该见过不少这样的。

我举个列子:

"scripts": {
  "dev""webpack-dev-server --base test/ --port 8081 --config build/webpack.dev.config.js",
  "lint:fix:utils""eslint --fix "./packages/utils/**" --ext .js,.ts,.json"
}

3️⃣ 字面量字符串

为了方便理解,你把它当成JS的模板字符串即可,没有转义行为,所见即所得。

这里以保留换行为例说明:

toml写法:

字面量字符串由单引号包裹,不能换行(不会进行任何转义)

path = 'C:Usersnodejstemplates'
path2 = '\Useradmin$system32'
quoted = 'Tom "Dubs" Preston-Werner'
regex = ''

多行字面量字符串两侧各有三个单引号来包裹,允许换行。

# 三个单引号包裹
hi = '''
echo
hello
world 我是小明
'''

解析为JS如下:

{ hi: ‘echo nhello nworld 我是小明n’ }

解析规则TOML.parse(data, { joiner: ‘n’ })

字符串用法小结

总的来说,JSON对于字符串的支持还是比较弱的,对于多行字符串等写法使用比较吃力;yaml总体来说简单方便,对字符串的支持还是不错的,相关解析库也很易用,唯一需要注意的就是缩进需要把控好;如果要说对字符串的支持能力,toml是最强的毋庸置疑,也没有缩进语法的担忧,几乎支持你所能相到的任何场景,不过,目前确实存在使用量不高,第三方解析库不太稳定的问题。

npm周下载量(Weekly Downloads)大致如下:

千万级别和万级别的对比~

@ltd/j-toml解析库对于存在多行字符串的toml文件进行解析时,必须要手动指定拼接规则({ joiner: ” }),有点奇怪,不过,这样也使得我们在处理多行字符串时,可以自定义拼接规则,以此实现不同的效果(要是说对于一个文件内多个多行字符串选择不同的处理方式,有待商榷)

对象

对象写法还是非常普遍的,对于该核心语法的掌握还是很有必要的,其实也是键值对的范畴,举例如下:

1️⃣ 简单用法2️⃣ 复杂一些的用法

在使用对象时也会遇到多个对象结构与嵌套的情况,如下:

对象用法小结

总的来说,JSON对于对象的写法支持还是蛮OK的,但是需要指出的是,JSON不支持注释,这是硬伤,而且和另外两个格式相比较而言,写法也是略显繁琐;yaml总体来说挺不错的,写法简洁、清爽,我还是蛮喜欢的,需要指出的是对于缩进的处理一定要注意,yaml语法规范严格,一个缩进不对就会解析错误;就目前而言,toml在对象语法和使用上优势明显,写法也是十分简单,而且其对键名的写法支持异常强大,极大的丰富了不同场景下的需求,不过,需要指出的是,从易读和已维护性考虑,还是推荐按照官方规范的写法使用。

数组与嵌套组合

数组以及JSON数组等常见用法的对比举例,如下:

1️⃣ 数组的基本用法2️⃣ JSON数组多级嵌套的的基本用法数组与嵌套数组小结

其实作为配置文件来说,数组一般还是有不少使用场景的,对于掌握数组的基本用法还是蛮有必要的,但是,对于类JSON数组来说,使用场景比较有限(gtHub action配置文件中这种用法多一些)。

竟然觉得JOSN看着属于比较清晰、易读的;yaml写法我在配置github action的时候使用过,当时就是语法缩进和数组对象结构一起使用时犯了错,耽误了不少时间定位问题,还是那句话,yaml对于缩进的处理需要特别注意;toml我用着还是不太习惯,但是总体结构划分、读写性上绝对值得点赞,看着还是比较清晰地,就是对于表的使用需要适应,用习惯了觉得是值得推荐的。

总结

好了,就写这么多吧。对于相关内容感兴趣的可以去官方文档进一步查看,本文也只是通用功能的概括,篇幅有限,很多高级用法这里不再赘述。

其实,这整个一轮学习、分析对比下来,就这三种配置文件格式来说,如果没有特殊使用场景,到了一定需要考虑选择配置文件的地方,我觉得吧,就JS对象用着就挺好的,毕竟人家webpack这么多配置,用着不也是完全ok;但是这样说是属于比较局限于前端角度的看法,毕竟我们对于JS语言整体是熟悉的,上手起来自然容易些。

但是,作为配置文件来说,它一定不能像开发语言一样那么的重,其实也不需要那么多功能,我们对配置文件的定位就是,它只要能覆盖我们基本的使用场景也就足够了。

资料

限 时 特 惠: 本站每日持续更新海量各大内部创业教程,一年会员只需98元,全站资源免费下载 点击查看详情
站 长 微 信: lzxmw777

发表回复

您的电子邮箱地址不会被公开。 必填项已用*标注