メインコンテンツへ移動

JSON Schemaに基づくJSONインテリセンス_VSCodeプラグイン開発ノート6

無料2020-05-17#Tool#JSON to JSON Schema#json2schema#VSCode JSON字段提示#VSCode JSON字段校验#VSCode jsonValidation

JSONフィールドの補完やバリデーションはどのように実現されているのでしょうか?拡張はサポートされていますか?

一. JSON インテリセンス

VS CodeはJSONに対して補完とバリデーションを行うことができます:

長大な設定ファイルを編集する際に特に便利です。 デフォルトで package.jsontsconfig.json などの一般的なJSON設定をサポートしています。

独自の特殊なJSONプロトコルについては、JSON Schemaを使用してサポートを拡張する必要があります。

二. JSON Schema

JSONのインテリセンス(またはバリデーション)を行うには、まずメタデータが必要です。JSONの構造、フィールドの値、意味などのメタ情報を明確に定義します。

VS Codeでは、このメタデータはJSON Schemaを使用して記述されます:

JSONファイルの構造を理解するために、私たちはJSONスキーマを使用します。JSONスキーマは、値のセット、デフォルト値、説明だけでなく、JSONファイルの形状についても記述します。

P.S. VS Codeは現在(2020/5/16)最新の JSON Schema Draft 7 仕様 をサポートしています。

JSON Schemaは、JSONデータの構造を定義するための、JSONベースのデータ形式です:

JSON Schemaは、バリデーション、ドキュメント化、およびインタラクション制御のために、JSONデータの構造を定義するJSONベースの形式を指定します。

JSON Schema より引用)

例えば person.json

{
  "first_name": "George",
  "last_name": "Washington",
  "birthday": "1732-02-22",
  "address": {
    "street_address": "3200 Mount Vernon Memorial Highway",
    "city": "Mount Vernon",
    "state": "Virginia",
    "country": "United States"
  }
}

対応するJSON Schemaは以下のようになります(person.schema.json):

{
  "type": "object",
  "properties": {
    "first_name": { "type": "string" },
    "last_name": { "type": "string" },
    "birthday": { "type": "string", "format": "date" },
    "address": {
      "type": "object",
      "properties": {
        "street_address": { "type": "string" },
        "city": { "type": "string" },
        "state": { "type": "string" },
        "country": { "type" : "string" }
      }
    }
  }
}

上の例はJSONの型宣言のように見えますが、実際には型以外にもフィールドの値や意味の記述などの情報を含めることができます:

{
  "type": "string",
  "pattern": "^(\\([0-9]{3}\\))?[0-9]{3}-[0-9]{4}$",
  "title": "telephone number",
  "description": "a simple North American telephone number with an optional area code"
}

P.S. JSON Schemaの詳細については、 Understanding JSON Schema を参照してください。

三. カスタムJSON補完の拡張

VS Codeが提供するJSON補完機能はJSON Schemaに基づいているため、カスタムJSON形式のサポートは非常に簡単です:

  1. まず、JSON Schemaを作成(手動作成または変換生成)し、補完/バリデーションに必要なメタデータを準備します。

  2. 次に、ターゲットとなるJSONファイルと関連付けを行い、VS Codeが特定のJSONファイルを開いたときに対応する補完情報(JSON Schema)を見つけられるようにします。

JSON Schemaの生成

シンプルで更新頻度の低いJSONデータの場合は、手動でJSON Schemaを記述すれば十分です。一方で、複雑で冗長、かつ頻繁にフィールドが拡張されるようなJSONデータの場合は、ツールを使用して変換生成するのが一般的により良い選択です:

  • JSONからJSON Schemaへの変換: JSON Schema Tool (非公開ソースですが、変換と編集が一体となっており、機能が比較的充実しており、Draft-07仕様をサポートしています)や to-json-schema (オープンソース、変換のみサポート、他のJSON Schemaエディタと併用します)がおすすめです。

  • JSON Schemaの編集: JSON-Schema-Editor ビジュアルエディタがおすすめです。

  • JSON Schemaの構文チェック: JSON Schema Validator

JSON Schemaを正しく生成したら、VS Code内でJSONファイルと関連付けを行います。

JSONファイルとの関連付け

JSON SchemaとJSONファイルを関連付けるには、以下の3つの方法があります:

  • ユーザー側:ユーザー設定(Settings)の json.schemas オプションを通じてマッピング関係を設定します。

  • データ側:JSONデータ内に $schema フィールドを追加し、JSON Schemaを指し示します。

  • サードパーティ側: jsonValidation 拡張ポイントを通じてマッピング関係を設定します。

json.schemas

"json.schemas": [
  {
    "fileMatch": [
      "/.babelrc"
    ],
    "url": "http://json.schemastore.org/babelrc"
  }
]

P.S. JSON Schema Store では、200以上の一般的な設定ファイルに対応するJSON Schemaが提供されています。

これは、 .babelrc という名前のすべてのJSONファイルに対して、 url が指すJSON Schemaを適用することを意味します。ここで、 url はローカルファイルの相対パスにすることもできます。例えば、 "url": "./myschema.json" は現在のワークスペースのルートディレクトリにある myschema.json を表します。

または、JSON Schemaを直接記述することもできます:

"json.schemas": [
  {
    "fileMatch": [
      "/.myconfig"
    ],
    "schema": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "description": "The name of the entry"
        }
      }
    }
  }
]

ユーザー設定は操作が簡単でJSONデータに影響を与えませんが、ローカル設定が共有されない(全員が設定する必要がある)ため、複数人での共同作業には適していません。また、 fileMatch ルールではマッピング関係を記述できない特殊なケースもあります。そのような場合は、 $schema を検討してください。

P.S. JSONデータファイルの拡張子が .json ではない場合、そのファイルの内容をJSONとして処理するように files.associations を設定する必要があります(JSON Schemaの設定はJSONに対してのみ有効なため):

"files.associations": {
  ".babelrc": "json"
}

詳細は Adding a file extension to a language を参照してください。

$schema

{
  "$schema": "http://json.schemastore.org/coffeelint",
  "line_endings": "unix"
}

JSONデータ側に(特殊な $schema フィールドを通じて)対応するJSON Schemaを付帯させる方法です。欠点はJSONデータが汚れること、すべてのコンシューマーが $schema を特殊処理する必要があること、そしてサードパーティから提供されるJSONデータのようにデータ側を制御できない場合にはフィールドを追加できないため適用できないことです。

利点は、1対1の正確なマッピングを構築できることであり、マッピングルールでは記述しにくいシナリオ(独自のJSONデータも package.json という名前である場合や、JSONファイル名が固定されていない場合など)に対応できます(詳細は support setting schema associations at runtime を参照してください。将来的に、より柔軟で元のデータを侵害しないJSON Schemaの関連付け方法が提供される可能性があります)。

jsonValidation

{
  "contributes": {
    "jsonValidation": [
      {
        "fileMatch": ".jshintrc",
        "url": "http://json.schemastore.org/jshintrc"
      }
    ]
  }
}

ユーザー設定の json.schemas と似ていますが、マッピング関係をプラグインの package.json に集約して提供することで、設定共有の問題を解決します。マッピング関係の記述能力の制限は依然として存在します。

P.S. jsonValidationurl 形式でのJSON Schemaの導入のみをサポートしており、 schema で直接記述することはサポートしていません。

四. 自動補完

JSON Schema仕様の default フィールドはJSONの自動補完に使用できます(VS Codeはデフォルトでサポートしています)。より複雑な補完ヒントについては、拡張フィールド defaultSnippets を使用して実現できます:

{
  "type": "array",
  "title": "Keybindings configuration",
  "items": {
    "type": "object",
    "required": ["key"],
    "defaultSnippets": [
      {
        "label": "New keybinding",
        "description": "Binds a key to a command for a given state",
        "body": { "key": "$1", "command": "$2", "when": "$3" }
      }
    ],
    "properties": {
      "key": {
        "type": "string"
      }
    }
  }
}

defaultSnippets 内の body 構文は Snippets と同じで、カーソル位置の制御、プレースホルダーの使用、定義済みの定数(現在のファイル名、年月日など)の使用などが可能です。

P.S. defaultSnippets はJSON Schema仕様の一部ではなく、VS CodeがJSONの補完能力を強化するために拡張した独自フィールドです(JSON Schema仕様では拡張が許可されており、未知のフィールドは無視されます)。

参考文献

コメント

コメントはまだありません

コメントを書く