ラベル monaco-editor の投稿を表示しています。 すべての投稿を表示
ラベル monaco-editor の投稿を表示しています。 すべての投稿を表示

2022年3月29日火曜日

monaco-editor で YAML の入力補完を行う

monaco-editor に入門する の続きから、 JSON Schema を読み込ませて YAML の入力補完を実現するところまで。

必要パッケージのインストール

monaco-yaml パッケージをインストールする。

npm install --save-dev monaco-yaml

JSON スキーマの作成

前回 と同じく、「タイトル」「URL」のプロパティを持った要素の配列を定義する。

dist/schema/Bookmarks.json

{
  "type": "array",
  "items": {
    "type": "object",
    "required": [
      "url"
    ],
    "properties": {
      "url": {
        "type": "string"
      },
      "title": {
        "type": "string"
      }
    },
    "$schema": "http://json-schema.org/schema#"
  },
  "$schema": "http://json-schema.org/schema#",
  "additionalProperties": false
}

YAML 補完機能の実装

MonacoWebpackPlugin の言語設定修正

前回のサンプルでは、 typescript, javascript, css が設定されていたが、 今回は YAML を編集したいので、 yaml のみとする。

diff --git a/js/monaco-editor/json/webpack.config.js b/js/monaco-editor/json/webpack.config.js
index 8b5ea53..1094993 100644
--- a/js/monaco-editor/json/webpack.config.js
+++ b/js/monaco-editor/json/webpack.config.js
@@ -28,7 +28,7 @@ module.exports = {
     },
     plugins: [
         new MonacoWebpackPlugin({
-            languages: ['typescript', 'javascript', 'css']
+            languages: ['json']
         })
     ]
 };

monaco-yaml のインポート

+import { setDiagnosticsOptions } from 'monaco-yaml';

スキーマファイルの読み込み

fetch で URL を指定子、ファイルの中身を取得する。

+async function init() {
+
+  const SCHEMA_URL = './schema/Bookmarks.json';
+
+  async function getJsonFromUri(jsonUri) {
+    const response = await fetch(jsonUri);
+    const json = await response.json();
+    return json;
+  }
+
+  const schema = await getJsonFromUri(SCHEMA_URL);
...(snip, 後述の YAML の Diag 設定処理)

fetch で async/await を使用するため、これ以降の処理をすべて init 関数として括る。

YAML の Diag 設定

先ほど取得した JSON スキーマの情報を使い、 Diagnostics Option の設定を行う。

...(snip, 前述のスキーマファイルの読み込み処理)
+  setDiagnosticsOptions({
+    enableSchemaRequest: true,
+    hover: true,
+    completion: true,
+    format: true,
+    validate: true,
+    schemas: [
+      {
+        uri: SCHEMA_URL,
+        fileMatch: ['*'],
+        schema: schema
+      }
+    ]
+  });
...(snip, 後述の monaco-editor の生成処理)
  • schemas.uri: JSON スキーマファイルの URI を指定
  • schemas.fileMatch: このスキーマを適用するファイル名のパターンを指定、今回は全ファイルにマッチさせたいので '*' とする
  • schemas.schema: JSON スキーマファイルの中身を指定

これで、このスキーマに則った候補の出力をしてくれるようになる。

monaco-editor の生成

   monaco.editor.create(document.getElementById('root'), {
-    value: `const foo = () => 0;`,
-    language: 'javascript',
-    theme: 'vs-dark'
+    value: "",
+    language: 'yaml',
   });
+}
  • language: エディタで開くファイルの言語、今回は YAML なので yaml を設定
  • value: エディタのテキスト初期値、今回は空にしたいので空文字を設定

init 関数を呼び出す処理追加

async/await の関係上 init 関数を作ったので、 DOMContentLoaded のタイミングでその関数を呼び出すように修正。

+document.addEventListener('DOMContentLoaded', () => {
+  init();
 });
■ index.js 全体
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';
import { setDiagnosticsOptions } from 'monaco-yaml';

(function () {
    // create div to avoid needing a HtmlWebpackPlugin template
    const div = document.createElement('div');
    div.id = 'root';
    div.style = 'width:800px; height:600px; border:1px solid #ccc;';

    document.body.appendChild(div);
})();

async function init() {

  const SCHEMA_URL = './schema/Bookmarks.json';

  async function getJsonFromUri(jsonUri) {
    const response = await fetch(jsonUri);
    const json = await response.json();
    return json;
  }

  const schema = await getJsonFromUri(SCHEMA_URL);

  setDiagnosticsOptions({
    enableSchemaRequest: true,
    hover: true,
    completion: true,
    format: true,
    validate: true,
    schemas: [
      {
        uri: SCHEMA_URL,
        fileMatch: ['*'],
        schema: schema
      }
    ]
  });

  monaco.editor.create(document.getElementById('root'), {
    value: "",
    language: 'yaml',
  });
}

document.addEventListener('DOMContentLoaded', () => {
  init();
});

動作確認

npm start コマンドで実行し、 monaco-editor が開かれ、 <C-Space>title, url が補完されることを確認。 OK.

ここまでの修正内容を以下 Pull Request で実施しているので、必要に応じて参照してみてください。

参考資料

2022年3月28日月曜日

monaco-editor で JSON Schema の入力補完を行う

前回 の続きから、 JSON Schema を読み込ませて入力補完を実現するところまで。

JSON スキーマの作成

今回は、「タイトル」「URL」のプロパティを持った要素の配列を定義する。

dist/schema/Bookmarks.json

{
  "type": "array",
  "items": {
    "type": "object",
    "required": [
      "url"
    ],
    "properties": {
      "url": {
        "type": "string"
      },
      "title": {
        "type": "string"
      }
    },
    "$schema": "http://json-schema.org/schema#"
  },
  "$schema": "http://json-schema.org/schema#",
  "additionalProperties": false
}

JSON Schema 補完機能の実装

MonacoWebpackPlugin の言語設定修正

前回のサンプルでは、 typescript, javascript, css が設定されていたが、 今回は JSON を編集したいので、 json のみとする。

diff --git a/js/monaco-editor/json/webpack.config.js b/js/monaco-editor/json/webpack.config.js
index 8b5ea53..1094993 100644
--- a/js/monaco-editor/json/webpack.config.js
+++ b/js/monaco-editor/json/webpack.config.js
@@ -28,7 +28,7 @@ module.exports = {
     },
     plugins: [
         new MonacoWebpackPlugin({
-            languages: ['typescript', 'javascript', 'css']
+            languages: ['json']
         })
     ]
 };

スキーマファイルの読み込み

fetch で URL を指定子、ファイルの中身を取得する。

+async function init() {
+
+  const SCHEMA_URL = './schema/Bookmarks.json';
+
+  async function getJsonFromUri(jsonUri) {
+    const response = await fetch(jsonUri);
+    const json = await response.json();
+    return json;
+  }
+
+  const schemaUri = monaco.Uri.parse(SCHEMA_URL);
+  const schema = await getJsonFromUri(SCHEMA_URL);
...(snip, 後述の JSON の Diag 設定処理)

fetch で async/await を使用するため、これ以降の処理をすべて init 関数として括る。

JSON の Diag 設定

先ほど取得した JSON スキーマの情報を使い、 Diagnostics Option の設定を行う。

...(snip, 前述のスキーマファイルの読み込み処理)
+  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
+    validate: true,
+    schemas: [
+      {
+        uri: schemaUri,
+        fileMatch: ['*'],
+        schema: schema
+      }
+    ]
+  });
...(snip, 後述の monaco-editor の生成処理)
  • uri: JSON スキーマファイルの URI を指定
  • fileMatch: このスキーマを適用するファイル名のパターンを指定、今回は全ファイルにマッチさせたいので '*' とする
  • schema: JSON スキーマファイルの中身を指定

これで、このスキーマに則った候補の出力をしてくれるようになる。

monaco-editor の生成

   monaco.editor.create(document.getElementById('root'), {
-    value: `const foo = () => 0;`,
-    language: 'javascript',
-    theme: 'vs-dark'
-    theme: 'vs-dark'
+    value: "",
+    language: 'json',
+  });
+}
  • language: エディタで開くファイルの言語、今回は JSON なので json を設定
  • value: エディタのテキスト初期値、今回は空にしたいので空文字を設定

init 関数を呼び出す処理追加

async/await の関係上 init 関数を作ったので、 DOMContentLoaded のタイミングでその関数を呼び出すように修正。

+document.addEventListener('DOMContentLoaded', () => {
+  init();
 });
■ index.js 全体
import * as monaco from 'monaco-editor/esm/vs/editor/editor.api';

(function () {
    // create div to avoid needing a HtmlWebpackPlugin template
    const div = document.createElement('div');
    div.id = 'root';
    div.style = 'width:800px; height:600px; border:1px solid #ccc;';

    document.body.appendChild(div);
})();

async function init() {

  const SCHEMA_URL = './schema/Bookmarks.json';

  async function getJsonFromUri(jsonUri) {
    const response = await fetch(jsonUri);
    const json = await response.json();
    return json;
  }

  const schemaUri = monaco.Uri.parse(SCHEMA_URL);
  const schema = await getJsonFromUri(SCHEMA_URL);

  monaco.languages.json.jsonDefaults.setDiagnosticsOptions({
    validate: true,
    schemas: [
      {
        uri: schemaUri,
        fileMatch: ['*'],
        schema: schema
      }
    ]
  });

  monaco.editor.create(document.getElementById('root'), {
    value: "",
    language: 'json',
  });
}

document.addEventListener('DOMContentLoaded', () => {
  init();
});

動作確認

npm start コマンドで実行し、 monaco-editor が開かれ、 <C-Space>{}title, url が補完されることを確認。 OK.

ここまでの修正内容を以下 commit で実施しているので、必要に応じて参照してみてください。

JSON 補完機能実装 in js/monaco-editor/json. · mikoto2000/MiscellaneousStudy@c8b5a5e

2022年3月26日土曜日

monaco-editor に入門する

monaco-editor リポジトリのサンプル「browser-esm-webpack-monaco-plugin」を実行するところまで。

monaco-edito サンプルの作成

npm プロジェクトの初期化

いつもの。

npm init

サンプルコードのコピー

monaco-editor の sample から、 browser-esm-webpack-monaco-plugin のソースコードをコピー。

monaco-editor/samples at e77825074dc019aebc7b28368428d16226d9ab8b · microsoft/monaco-editor

必要パッケージのインストール

npm install --save monaco-editor
npm install --save-dev webpack webpack-cli monaco-editor-webpack-plugin style-loader css-loader file-loader

ビルド

以下コマンドでビルドが成功することを確認。

npx webpack --mode=development

動作確認

webpack-dev-server で、ローカルサーバーを立ち上げ、動作確認する。

必要パッケージのインストール

npm install --save-dev webpack-dev-server

package.json の更新

scripts に、ビルドで使いそうなコマンドを追加。

webpack-dev-server を使うのは "start": "webpack serve" の定義部分。

また、webpack-dev-server をインストールしたので、 devDependencieswebpack-dev-server が追加されている。

diff --git a/js/monaco-editor/firststep/package.json b/js/monaco-editor/firststep/package.json
index 44eacaa..bd4660e 100644
--- a/js/monaco-editor/firststep/package.json
+++ b/js/monaco-editor/firststep/package.json
@@ -4,7 +4,11 @@
   "description": "",
   "main": "index.js",
   "scripts": {
-    "test": "echo \"Error: no test specified\" && exit 1"
+    "start": "webpack serve",
+    "test": "echo \"Error: no test specified\" && exit 1",
+    "build": "webpack",
+    "build:dev": "webpack --mode=development",
+    "build:pro": "webpack --mode=production"
   },
   "author": "mikoto2000",
   "license": "MIT",
@@ -17,6 +21,7 @@
     "monaco-editor-webpack-plugin": "^7.0.1",
     "style-loader": "^3.3.1",
     "webpack": "^5.70.0",
-    "webpack-cli": "^4.9.2"
+    "webpack-cli": "^4.9.2",
+    "webpack-dev-server": "^4.7.4"
   }
 }

webpack.config.json を更新

  • デフォルトのモードを development に変更
  • ./dist のパスを変数化して共有
  • devServer セクションに webpack-dev-server の設定を追加
diff --git a/js/monaco-editor/firststep/webpack.config.js b/js/monaco-editor/firststep/webpack.config.js
index 823fa44..8b5ea53 100644
--- a/js/monaco-editor/firststep/webpack.config.js
+++ b/js/monaco-editor/firststep/webpack.config.js
@@ -1,13 +1,19 @@
 const path = require('path');
 const MonacoWebpackPlugin = require('monaco-editor-webpack-plugin');

+const distPath = path.resolve(__dirname, 'dist');
+
 module.exports = {
-    mode: process.env.NODE_ENV,
+    mode: 'development',
     entry: './index.js',
     output: {
-        path: path.resolve(__dirname, 'dist'),
+        path: distPath,
         filename: '[name].bundle.js'
     },
+    devServer: {
+        static: distPath,
+        open: true
+    },
     module: {
         rules: [
             {

webpack-dev-server の設定は以下の通り。

  • devServe.static: サーバーのドキュメントルート
  • devServe.open: 起動時にブラウザを開く

動作確認

webpack-dev-server を立ち上げて動作確認。

npx webpack serve

この作業を以下 PR にまとめたので、必要があれば参照してください。

Monaco firststep by mikoto2000 · Pull Request #45 · mikoto2000/MiscellaneousStudy

参考資料