【JavaScript】AtCoderとかでも利用したい、ブラウザで動くエディタ + デバッグ環境を作る

【AtCoder】自分用のブラウザで動くテストコード環境を作る【JavaScript】 JavaScript




概要

AtCoder用の自分用のJSデバッグ環境を作りました。
JSのみです。

デモ

こちらから、

デモ ※外部ウィンドウが開きます。

ソース

これがソース。

(() => {
    var src = document.getElementById("src")
    var dst = document.getElementById("dst")
    var run = document.getElementById("run")

    const editor = ace.edit("editor")
    editor.setTheme("ace/theme/monokai")
    editor.getSession().setMode("ace/mode/javascript")

    console.log = (v) => {
        dst.value += String(v) + "\n"
    }

    function getStdio() {
        return `
        let require = (arg)  => {
            return {
                readFileSync : (type, string_type) => {
                    return \`` + src.value + `\`
                }
            }
        }`
    }

    run.addEventListener("click", () => {
        dst.value = ""

        let f = getStdio() + "\n"
        f += editor.getValue();
        try {
            let tmp = new Function(f)
            tmp()
        } catch (e) {
            dst.value = String(e)
        }
    })
})()

解説

簡単に解説すると、実行イベントが呼ばれるたびに、

require.readFileSync

の返り値を
テキストエリアの文字列を固定にした上で、入力したJSコードに埋め込んでいます。

さらに、

let tmp = new Function(f)

の箇所でJS文字列を式として評価して実行しています。
Functionを使ってるコードってあんまりみたことがありませんが、
これを利用して、クロージャのようなもを作ったりすることができるそうです。

【JavaScript】即時関数, 無名関数, クロージャについて - Qiita
# 技術をアウトプットするところに技術は集まる (が、 非常に心に残るものだった...

また、このソースに関してはFunctionではなくeval()でも問題ないと思います。

console.log()

は強引に書き換えています。
引数が複数渡るとマズイ感じです。そのうち修正します。

エラーハンドリングに関してはかなり適切ではない気がしますが問題ないでしょう。

AceEditor

また他の特徴として、AceEditorを使っています。

Ace - The High Performance Code Editor for the Web

Semantic UI

CSSフレームワークとしてSemantic UIを使ってます。最近ハマってます。

Semantic UI
Semantic empowers designers and developers by creating a shared vocabulary for UI.

背景

コードテストで毎回アップロードして数秒待たされるのも嫌だけど、ローカルサーバ立ててまで…
JSコードならブラウザで十分実行環境として成り立つのでは??と思い作りました。
そもそもJSで参加してる人ってあんまりいない。