當前位置:
首頁 > 最新 > JSON不是合格的配置語言!

JSON不是合格的配置語言!

作者|Thayne McCombs

譯者|無明

編輯|覃雲

很多項目使用 JSON 作為配置文件,最明顯的例子就是 npm 和 yarn 使用的 package.json 文件。當然,還有很多其他文件,例如 CloudFormation(最初只有 JSON,但現在也支持 YAML)和 composer(PHP)。

但是,JSON 實際上是一種非常糟糕的配置語言。別誤會我的意思,我其實是喜歡 JSON 的。它是一種相對靈活的文本格式,對於機器和人類來說都很容易閱讀,而且是一種非常好的數據交換和存儲格式。但作為一種配置語言,它有它的不足。

為什麼流行使用 JSON 作為配置語言?

將 JSON 用作配置文件有幾個方面的原因,其中最大的原因可能是它很容易實現。很多編程語言的標準庫都支持 JSON,開發人員或用戶可能已經很熟悉 JSON,所以不需要學習新的配置格式就可以使用那些產品。現在幾乎所有的工具都提供 JSON 支持,包括語法突出顯示、自動格式化、驗證工具等。

這些都是很好的理由,但這種無處不在的格式其實不適合用作配置。

JSON 的問題

缺乏注釋

注釋對於配置語言而言絕對是一個重要的功能。注釋可用於標註不同的配置選項、解釋為什麼要配置成特定的值,更重要的是,在使用不同的配置進行測試和調試時需要臨時注釋掉部分配置。當然,如果只是把 JSON 當作是一種數據交換格式,那麼就不需要用到注釋。

我們可以通過一些方法給 JSON 添加註釋。一種常見的方法是在對象中使用特殊的鍵作為注釋,例如「//」或「__comment」。但是,這種語法的可讀性不高,並且為了在單個對象中包含多個注釋,需要為每個注釋使用唯一的鍵。David Crockford(JSON 的發明者)建議使用預處理器來刪除注釋。如果你的應用程序需要使用 JSON 作為配置,那麼完全沒問題,不過這確實帶來了一些額外的工作量。

一些 JSON 庫允許將注釋作為輸入。例如,Ruby 的 JSON 模塊和啟用了 JsonParser.Feature.ALLOW_COMMENTS 功能的 Java Jackson 庫可以處理 JavaScript 風格的注釋。但是,這不是標準的方式,而且很多編輯器無法正確處理 JSON 文件中的注釋,這讓編輯它們變得更加困難。

過於嚴格

JSON 規範非常嚴格,這也是為什麼實現 JSON 解析器會這麼簡單,但在我看來,它還會影響可讀性,並且在較小程度上會影響可寫性。

低信噪比

與其他配置語言相比,JSON 顯得非常嘈雜。JSON 的很多標點符號對可讀性毫無幫助,況且,對象中的鍵幾乎都是標識符,所以鍵的引號其實是多餘的。

此外,JSON 需要使用花括弧將整個文檔包圍起來,所以 JSON 是 JavaScript 的子集,並在流中發送多個對象時用於界定不同的對象。但是,對於配置文件來說,最外面的大括弧其實沒有任何用處。在配置文件中,鍵值對之間的逗號也是沒有必要的。通常情況下,每行只有一個鍵值對,所以使用換行作為分隔符更有意義。

說到逗號,JSON 居然不允許在結尾出現逗號。如果你需要在每個鍵值對之後使用逗號,那麼至少應該接受結尾的逗號,因為有了結尾的逗號,在添加新條目時會更容易,而且在進行 commit diff 時也更清晰。

長字元串

JSON 作為配置格式的另一個問題是,它不支持多行字元串。如果你想在字元串中換行,必須使用「
」進行轉義,更糟糕的是,如果你想要一個字元串在文件中另起一行顯示,那就徹底沒辦法了。如果你的配置項里沒有很長的字元串,那就不是問題。但是,如果你的配置項里包括了長字元串,例如項目描述或 GPG 密鑰,你可能不希望只是使用「
」來轉義而不是使用真實的換行符。

數字

此外,在某些情況下,JSON 對數字的定義可能會有問題。JSON 規範中將數字定義成使用十進位表示的任意精度有限浮點數。對於大多數應用程序來說,這沒有問題。但是,如果你需要使用十六進位表示法或表示無窮大或 NaN 等值時,那麼 TOML 或 YAML 將能夠更好地處理它們。

JSON 的替代方案

TOML

TOML 是一種越來越流行的配置語言。Cargo(Rust 的構建工具)、pip(Python 包管理器)和 dep(Go 語言依賴管理器)都在使用 TOML。TOML 有點類似於 INI 格式,但與 INI 不同的是,它有一個標準規範,並且嵌套結構有明確定義的語法。它比 YAML 簡單得多,如果你的配置很簡單,那麼 TOML 就非常合適。但是,如果你的配置具有大量的嵌套結構,那麼使用 TOML 可能就有點冗長,而另一種格式(如 YAML 或 HOCON)可能是更好的選擇。

HJSON

HJSON 是一種基於 JSON 的格式,但具有更大的靈活性,可讀性也更強。它支持注釋、多行字元串、不帶引號的鍵和字元串,以及可選的逗號。如果你想要 JSON 結構的簡單性,同時對配置文件更友好,那麼可以考慮 HJSON。有一些可以將 HJSON 轉換為 JSON 的命令行工具,如果你使用的工具是基於 JSON 的,可以先用 HJSON 編寫配置,然後再轉換成 JSON。JSON5 是另一個與 HJSON 非常相似的配置語言。

HOCON

HOCON 是為 Play 框架設計的配置格式,在 Scala 項目中非常流行。它是 JSON 的超集,因此可以使用現有的 JSON 文件。除了注釋、可選逗號和多行字元串這些標準特性外,HOCON 還支持從其他文件導入和引用其他值的鍵,避免重複代碼,並使用以點作為分隔符的鍵來指定值的路徑,因此用戶可以不必將所有值直接放在花括弧對象中。

YAML

YAML(YAML 不是標記語言)是一種非常靈活的格式,幾乎是 JSON 的超集,已經被用在一些著名的項目中,如 Travis CI、Circle CI 和 AWS CloudFormation。YAML 的庫幾乎和 JSON 一樣無處不在。除了支持注釋、換行符分隔、多行字元串、裸字元串和更靈活的類型系統之外,YAML 也支持引用文件,以避免重複代碼。

YAML 的主要缺點是規範非常複雜,不同的實現之間可能存在不一致的情況。它將縮進視為嚴格語法的一部分(類似於 Python),有些人喜歡,有些人不喜歡。這會讓複製和粘貼變得很麻煩。

腳本語言

如果你的應用程序是使用 Python 或 Ruby 等腳本語言開發的,並且你知道配置的來源是可靠的,那麼最好的選擇可能就是使用這些語言進行配置。如果你需要一個真正靈活的配置選項,也可以在編譯語言中嵌入諸如 Lua 之類的腳本語言。這樣可以獲得腳本語言的靈活性,而且比使用不同的配置語言更容易實現。使用腳本語言的缺點是它可能過於強大,當然,如果配置來源是不受信任的,可能會引入嚴重的安全問題。

自定義配置格式

如果由於某種原因,鍵值配置格式不能滿足你的要求,並且由於性能或大小限制而無法使用腳本語言,那麼可以考慮自定義配置格式。如果是這種情況,那麼在做出選擇之前要想清楚,因為你不僅要編寫和維護一個解析器,還要讓你的用戶熟悉另一種配置格式。

結 論

有了這麼多更好的配置語言,沒有理由還要使用 JSON。如果要創建需要用到配置的新應用程序、框架或庫,請選擇 JSON 以外的其他選項。

英文原文

https://www.lucidchart.com/techblog/2018/07/16/why-json-isnt-a-good-configuration-language/

課程推薦

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 前端之巔 的精彩文章:

SpriteJS:重新定義Canvas API

TAG:前端之巔 |