1. この記事について
この記事は、私が開発したExecNoteというアプリケーションの技術的要素を説明したものです。
ExecNoteは、Markdownに記述したコードを、ワンクリックで実行できるアプリケーションです。現在は、NodeJS、Python、Powershellのコード実行に対応しています。
現在はWindowsのみですが、今後、Mac OSX、Linux、AWS Lambda等でコード実行できるSaaSアプリ化へ対応予定です。
2. 作者について
私は、SIerのSEとして5年、その後、自動車部品製造業社内SEとして6年ほどシステムエンジニアとして働いています。実務では主にERPや製造業務システムの要件定義・設計開発・保守を担当しています。VB6とCOBOLで開発されたERPのメンテナンスもしています。
ブログは主に技術的な内容を書いています。
- Blog: https://usefuledge.com/
Twitterでは、ExecNoteの宣伝や、感じたことを徒然と書いています。
- Twitter: https://twitter.com/Harus0313
3. ExecNoteの機能概要
ExecNoteは、2020年8月22日時点で、主に以下の機能を実装しています。
- Markdownドキュメントのツリー表示
- Markdown編集機能
- プレビュー機能
- オートセーブ機能
- コード実行機能
- コード実行時の作業ディレクトリ変更機能
画像のコピペに対応していなかったり、今一つ機能としては足りていないところもありますが、必要最低限の機能を実装しています。
機能概要は、以下のYouTube動画にまとめています。
4. 使用したプログラム言語とフレームワーク
このアプリケーションは、ローカルPC上に .NET Core Blazor サーバーを起動して、ブラウザで表示しています。よって、バックグラウンドは、Blazor Server と C#, フロント側は、HTML, JavaScript, CSSを使用しています。
Markdownを編集するエディタは、Visual Studio Codeと同じく、Monaco Editor を採用しました。補完機能が充実していますし、個人的に好きなので。
https://microsoft.github.io/monaco-editor/
MarkdownをHTMLに変換するエンジンは、marked.js を採用しました。シンプルでものすごく使いやすいです。
https://github.com/markedjs/marked
Markdownドキュメントや設定情報は、内部にポータブルNoSQLデータベースを作成して保存しています。ポータブルNoSQLデータベースは、LiteDBを採用しました。
LiteDBは、.NET Framework で書かれています。動作も高速で、ファイルサイズも32KB程度とかなり軽量です。
5. コマンドと言語の取得方法
ExecNoteは、Markdownに記述されたコードと言語を判断して、実行することが最重要機能要件です。
コード記入のMarkdown文法では、以下のようにプログラム言語を記述できます。
これをmarked.jsでHTMLに変換すると、<pre class="language-js"><code>...</code></pre>のように、classに言語名が付与されます。
これをもとにプログラム言語を判定します。そのため、Markdownの記述が誤っていると、誤ったインタプリタで実行されてしまいます。
コードは、<code>...</code>の中に書かれた内容をinnerTextで取得します。
これらの情報をBlazorServer側に渡して、コードを実行します。
6. フロントエンド(JavaScript)からBlazor Serverの関数を呼び出す方法
フロントエンド(JavaScript)からBlazor Server関数を呼び出すには、DotNet.invokeMethodAsync
を使用します。
以下のコードは、ExecNoteプロジェクトのJSInvokableExecCode
というBlazorServer側の関数を呼び出します。引数は、codeInfoJson
です。
DotNet.invokeMethodAsync('ExecNote', 'JSInvokableExecCode', codeInfoJson)
JSInvokableExecCode
から返り値がある場合、.then
を用いて取得します。
DotNet.invokeMethodAsync('ExecNote', 'JSInvokableExecCode', codeInfoJson)
.then(data => {
})
詳しくは以下を参照ください。
https://usefuledge.com/js-call-blazor-function.html
7. Monaco Editor の使い方
まず、https://microsoft.github.io/monaco-editor/を参照し、npm installなどを使用してダウンロードします。
_Host.cshtml
にloader.js
を記述します。
<script src="~/monaco-editor/min/vs/loader.js"></script>
razorコンポーネント等に、Monaco Editor を表示するDIVタグを記述します。
<div id="EditorContainer"></div>
以下のような、初期化用のJavaScript関数を定義します。オプションは、PlaygroundもしくはAPI DOCSをみると分かるかもしれません。
https://microsoft.github.io/monaco-editor/playground.html
https://microsoft.github.io/monaco-editor/api/index.html
Monaco Editor の OnChangeなイベントはwindow.editor.onDidChangeModelContent
で実行できます。
function initializeMonaco()
{
require(['vs/editor/editor.main'], function () {
window.editor = monaco.editor.create(document.getElementById('EditorContainer'), {
value: GetReadMe(),
language: 'html',
theme: "vs-dark"
});
window.editor.onDidChangeModelContent(() => {
PreviewMarkdown();
AutoSaveDB();
});
}
8. 終わりに
機能を実装するにはいろいろな手法があると思いますが、1つの例として読んで頂ければと思います。
また、ExecNoteは、定常的に実行するコードをMarkdownと一緒に管理することで、作業効率が見込まれるアプリケーションです。
よければダウンロードをお願いします!