TECH BOX

Technology developer's blog

JSONの代わりにYAMLを使う

JSONはいいですね。扱いやすくて。
でもコメントが書けないとか、ネストが深くなると可読性が悪くなるとか色々問題があります。

そういった問題を解決するためにJSON5やらCSONやらいろんなaltJSONが存在します。
使ったことはないけどコメントが書けるっていうだけでも全然違いますね。

ただ、自分はコメントはもちろん配列やらオブジェクトの記号([]とか{})も極力書きたくないし、なんならダブルクォーテーションやカンマも書きたくない。

そんなワガママを実現するためにYAMLをよく使います。
PHPのSymfonyとかを触ったことがある人には馴染みがあると思います。

YAMLとは「人間が読みやすいように最適化された、すべてのプログラミング言語のための標準的なデータシリアライゼーション」と公式サイトがおっしゃっております。

YAMLの書き方

記述方法はいくつかありますが、下記はよく使う書き方です。
ちょっと試してみたい方はOnline YAML Parserがあるので試してみてください。

拡張子は.ymlもしくは.yamlになります。

# コメント
data:
  # 配列は-(ハイフン)で表す
  # オブジェクトは xxx: zzz で表示
  - shop: foobar
    isShow: true
    tel: 000-0000-0000
    open: 
      - 平日 12:00-19:00
      - 土日祝 10:00-22:00
    url: https://foobar.com
    brands:
      - id: aaaa
        products:
          - name: foobar original
            category: T-Shirt
            price: 5000
            target: [mens, womens, kids] # JSONのような書き方もOK

          - 
            # 一行下げてもOK
            name: foobar fighter
            category: T-Shirt
            price: 15000
            target: [mens, womens, kids]


これをJSONで表すと下記のようになります。

{
  "data": [
    {
      "shop": "foobar",
      "isShow": true,
      "tel": "000-0000-0000",
      "open": [
        "平日 12:00-19:00",
        "土日祝 10:00-22:00"
      ],
      "url": "https://foobar.com",
      "brands": [
        {
          "id": "aaaa",
          "products": [
            {
              "name": "foobar original",
              "category": "T-Shirt",
              "price": 5000,
              "target": ["mens", "womens", "kids"]
            },
            {
              "name": "foobar fighter",
              "category": "T-Shirt",
              "price": 5000,
              "target": ["mens", "womens", "kids"]
            }
          ]
        }
      ]
    }
  ]
}

YAMLの場合、配列の時のみ-(ハイフン)を使うのでグルーピングデータを追いやすいです。

YAMLをJavaScriptのオブジェクトや配列に変換する

JavaScriptやNode.jsではYAMLファイルをそのまま使うことは出来ないのでパーサーを通す必要があります。
JavaScriptやNode.jsの場合はjs-yamlが有名です。

フロントエンドでも使うことは出来ますが、どちらかと言うとYAMLで書いたファイルをjs-yamlでパースしJSONファイルとして書き出したり、バンドラーの設定ファイルとしてそのまま使ったりする方が多いです。

JSONファイルとして出力せずにバンドラーのオプションなどで使う場合はjs-yaml 公式APIにもあるようにfspathと組み合わせて使えばいいです。

const yaml = require('js-yaml')
const fs = require('fs')

const options = yaml.safeLoad(fs.readFileSync('/path/to/foo.yml'), 'utf-8'))

bundler.options = options

yamlのパースはたった1行だけなのでわかりやすいですね。

YAMLをJSONファイルに変換して出力する

YAMLをJSONファイルとして出力する場合もfspathを使います。

//yaml2json.js
const yaml = require('js-yaml')
const fs = require('fs')

const body =  yaml.safeLoad(fs.readFileSync('/path/to/foo.yml'), 'utf-8'))
body = JSON.stringify(body, null, 0) // JSONに変換

fs.writeFile('/output/foo.json', body, 'utf8', (err)=>{
  if(err !== null){
    // エラー処理
    return false
  }
})

コマンドラインで実行。

$ node yaml2json.js

もし、babelで書いたならbabelで書いたファイルをシェルやnpm scriptsで実行するを参考に実行できます。

本来はpathやディレクトリがない場合はディレクトリ作成するmkdirpなどを使ってOS依存やディレクトリを手作業で作成する手間を省いたりも出来ますが、この辺はまた違う機会に、動的に行う方法をアップしたいと思います。


もし、変数やJSONで設定を書いていたりしていて、もっと楽にできないかなと思った人はYAMLを試してみてはいかがでしょうか?

Write a commets