使用JSON作配置文件已经成了一种趋势。
不要这样做,一次也不要。因为这是一个非常糟糕的做法。
JSON的设计初衷不是用来干这个的。JSON是一种“轻量级的数据交换格式”,它“易于人类读写”和“便于机器解析和生成”。
作为一种数据交换格式,JSON相当不错。人们可以轻易阅读和编写它,机器也很容易解析(尽管存在问题)。在机器可读和人类可读性之间取得很好的平衡,相对于XML有了巨大改进,我认为XML对机器或人类可读性都很差。
将它用于其它目的有点类似于说:“嘿,这个锤子钉钉子真好用!我喜欢它!为什么不用它钉螺丝呢?”当然,这也是一种方法,但对于这项工作来说是使用了错误的工具。
缺点详述
1、没有注释
这是迄今为止最大的问题:您无法在JSON中添加注释。少数JSON解析器支持注释,但大多数不支持,而且不符合标准,事实上,出于种种原因,JSON已经明确不支持注释。
这会产生许多问题。
--没有办法记录设置原因。
--没有办法添加助记符或警告。
--没有办法在配置文件中保存一个基本的变更日志,记录做了哪些更改(记录这些更改可能是非常有用的)。
--更难调试,因为快速注释掉一部分代码是不可能的。
一种解决方法是使用新的键值对,例如:
但这真是太丑了。
有人说你可以使用操作日志啊,但这是一个更糟糕的想法。看看下面使用bower文件包管理器的例子:
那么,为了查找一些重要的信息,你是否会查阅全部操作记录?
当然不是。
2、可读性
这不是一般意义上的可读性。对于数据交换格式是可读的,但对配置文件不可读。
可读性很重要。
3、标准严格
JSON标准相当严格,这是它的优点,用简洁和快速的解析器,不必处理不同的格式,但这也意味着编写起来更加困难。
例如,对象或数组中的逗号是一个错误,并且已经多次困扰我。如果你的字符串中包含很多双引号,那么转义所有的实例或者引号会非常麻烦。
4、缺乏可编程性
不总是这样,但有时候就是这样,特别是当使用JSON配置某段代码时。
例如:
例如在MediaWiki的skin.json文件中,这是一个问题。如果我加载了某个插件而不想包括其中的CSS, 我们可以在PHP文件中解决它,但“解决”事情永远不是最好的方法(记住,我们不能在JSON文件中添加注释,告知人们我们正在解决问题!)
MediaWiki中的老办法(声明类变量)要好得多,而且功能更多。
替代方案
——JSON的创造者Douglas Crockford的“推荐方式”是“在将文件交给JSON解析器之前,通过JSMin管理它”。一些JSON解析器也明确支持注释(但大多数不支持)。但预先处理配置文件是一件痛苦的事情。
——使用import, require, include或其它任何语言的代码导入工具(甚至是eval())。这意味着配置文件必须是可信来源,而通常都是可信来源。
——ini文件;不是标准化的,但这通常不是问题,因为配置文件通常只能被一个程序读取。
——TOML与ini文件非常相似,但这是标准化的。
——YAML有点不错...我猜...但我不是很喜欢它,我专门写过一篇文章:YAML可能并不是那么好用(链接:http://arp242.net/weblog/yaml_probably_not_so_great_after_all.html)。
——虽然我不想推荐这个方法,但“自己制作”配置文件解析器非常简单。在Python中:
真实例子
点名批评:-)
——MediaWiki的新扩展注册系统(链接:https://www.mediawiki.org/wiki/Manual:Extension_registration)促使我写这篇文章。
——npm的package.json(使用一个有点愚蠢的系统来添加注释)。(链接:http://stackoverflow.com/a/14221781/660921)
——bower不支持注释,这很白痴。(链接:https://github.com/bower/bower/issues/1059)
...还有很多很多例子......
建议:
JSON配置文件格式,参考链接http://octodecillion.com/blog/json-data-file-format/
反馈
您可以给我发邮件martin@arp242.net,或者创建一个GitHub issue 以获得反馈。
英文原文:https://arp242.net/weblog/json_as_configuration_files-_please_dont
译者:钱利鹏