Superjson‐ステロイドに関するJSON


SuperJSON 高忠実度の代替品ですJSON.stringify . データ型をサポートしますDate , RegExp , Map , Set などは参照等価性を保持し、循環参照をサポートします.このブログ記事は、それを代替案と比較し、それがどのように機能するかを説明することを目的としています.

何が問題ですか.
JSONは、Webアプリケーションのための事実上の標準のデータ交換形式です.これは人間の読み取り可能な、広いツールをサポートしており、データ型の選択はほとんどのプラットフォームと互換性があります.
バックエンドとフロントエンドの向こう側のJavaScriptの使用がより人気になったので、その価値命題の1つはJSONによってダウンされましたDate , RegExp , Map or Set , 開発者に、これらの制限を回避するために厄介なアダプター・ロジックを書くよう促します.
この問題は、特にBlitz.js . ブリッツ.JSは、コンパイル時にアプリケーションのAPI層を生成します.このように、開発者はフロントエンドから直接バックエンド機能をインポートすることができます.そして、完全にネットワークコールを離れて抽象化します.ここで問題がある:私たちが使用する場合JSON.stringify , それが彼らの良いデータ型を破壊したので、我々の開発者は驚きます!それはSuperJSONが遊びに来るところです:それはどんなJavascript価値も直列化することができて、したがって、我々の開発者をかなりの頭痛から救うことができます.

その他の解決方法
Superjsonは最初の競争相手ではなく、この問題を解決する他のアプローチが存在している.
devalue リッチHarrisによって、それを作成するJavaScriptコードに値をコード化するアルゴリズムは{ foo: "bar", self: this } into (function(a){a.foo="bar";a.self=a;return a}({})) , 次に、元の値を返すように評価できます.それは信じられないほど効率的ですが1 , ツールのサポートはありません.また、サーバーにデータを送信するために使用することはできませんwhile (true) { /* do nothing */ } ?
同様のアプローチはヤフーのSerialize JavaScript , しかし、それは同じ問題に苦しみます.

スーパーJのゴール
上記のアプローチに反して、Superjsonは、.
  • … サポートJavaScriptの値
  • … リモートコード実行から安全です
  • … JSON互換性があるので、既存のツーリングは
  • … サポート循環参照
  • … 参照平等を保つ
  • … 読みやすいので、デバッグが簡単です
  • … あなたがそれを知っていないとしても

  • どのように、Superjsonはそれを解決しますか?
    我々が達成しようとしているものに2つの部分があります.…する必要がある.
  • … JavaScriptの値をJSON互換のものに変換する
  • … それを逆にすることができます!

  • JSON互換値への変換
    変換は非常に簡単ですが、実際には:すでに互換性のあるものについては、それは些細なことです.42 なる42 , "lol" なる"lol" , true なるtrue and false なるfalse .
    JSON対応のない値は少し難しくなります.Set { "foo", "bar" } なる["foo", "bar"] , Map { 1 => 11, 2 => 22 } なる[[1, 11], [2, 22] ] and NaN なる"NaN" .
    したがって、この値を与えられます.
    {
        a: new Set([/a-Z/g]),
        b: new Map([
            [1, NaN],
            [2, NaN]
        ])
    }
    
    
    ...このJSONを作成します.
    {
        "a": ["/a-Z/g"],
        "b": [
            [1, "NaN"],
            [2, "NaN"]
        ]
    }
    
    
    簡単、右?これは、再帰的に行うことができますし、コードの行のカップルに収まります.
    しかし、我々はこれを右に戻すことができないでしょう?…を除いて
    {
        "a": "set",
        "a.0": "RegExp",
        "b": "map",
        "b.0.1": "number",
        "b.1.1": "number"
    }
    
    
    これはどんな些細な変換にも注意を含んでいます.2
    その後、安全にネットワーク上で我々のJSONの値とノートの両方を送信することができます.逆シリアル化の間、オリジナルの値を再現するためにメモを適用します.
    value["b"][1][1] = Number(value["b"][1][1])
    value["b"][0][1] = Number(value["b"][0][1])
    value["b"] = new Map(value["b"])
    ...
    
    
    それほど難しくはないか.タイプを保存できるようになりました.

    参照等価性の保存
    次のコードによって作成されたオブジェクトを想像します.
    const a = { id: "a" }
    const b = { id: "b" }
    
    { options: [a, b], selected: a }
    
    
    としてGoals , 我々はその事実を守りたいoptions[0] === selected . これは、再現するタイプのノートを取るだけでなく、参照平等によっても行うことができます.上記の値については、SuperJSONは次の注意を取ります.
    {
        "selected": ["options.0"]
    }
    
    
    以下のようにしてこれらのノートを使用することができます.
    value["options"]["0"] = value["selected"]
    
    
    この機能は、循環参照を保持するためにも使用できます.

    それを使用してください!
    SuperJSONは現在ベータ版で、独自のプロジェクトで使用する準備ができているはずです.
    npm install --save superjson
    yarn add superjson
    
    
    import SuperJSON from "superjson"
    
    const string = SuperJSON.stringify(yourValue)
    const profit = SuperJSON.parse(string)
    
    
    現在保存中のサポートをテスト中ですclass and Symbol インスタンスは、スーパーJSONをより速くより小さくすることにも取り組みます.
    私はあなたがそれをどう思うかを聞きたい!私のつぶやき:または下にコメントを書く.

  • 参照this benchmark 比較のために

  • 実際には、これらをツリー構造でエンコードしてスペースを節約します.しかし、それは別のポストのトピックです😄