推しアイデア
「だっしゅ」つをテーマにしたとこ
「だっしゅ」つをテーマにしたとこ
WebContainer を使ってアレコレしたかったから
WebContainer を使用したオンライン実行環境の構築、問題・異変を管理する基盤技術の構築
コーディング支援に加えて、チーム全体でGitHub Copilotを導入しプルリクのレビューをしてもらった🤖
情報共有やメモをDiscordで行っていたため、そこから情報を引っ張ってきてCopilotに答えてもらえるようにMCPサーバーを構築!
などもCopilotから可能に!
作りたいコンポーネント画像をGeminiに投げて、画像と似ているコンポーネントを作ってもらった
今回の実装の肝となる部分です。 WebContainer は、ブラウザ上でコード実行環境を整えるために使用する技術です。身近なサービスでは mosya React 等に使われています(参照)。
要件を満たすための最小の実装は eval()
を使用することでしたが、任意コードの実行は高いリスクを伴います。これを回避するため、WebContainer 上のサンドボックス環境で eval()
を実行しています。
// WebContainer 起動部分 useEffect(() => { (async () => { try { const container = await WebContainer.boot(); await container.mount(files); console.log("WebContainerが起動しました"); } catch (error) { if (error instanceof Error) { setError(`WebContainerの起動に失敗: ${error.message}`); } } })();
コードのテストは
1.静的テスト 2.コードを実行、出力を受け取る 3.出力に対し動的テスト
の順で行っています。サービス内では出力として console.log
によるログ出力を指定しているため、WebContainer 内では console.log
を「logOutput
にログを書き足す関数」としてオーバライドすることで解決しています。本当はグローバルオブジェクトを更新せず、Console インスタンスを作成してオーバライドしたかったけど、Vite 環境上では厳しいのでこうしました。
ちなみに出力の終端は __EOF__
で検知しました。うろ覚えのヒアドキュメント知識が役に立った瞬間です。
export const runCode = (code: string): string => { let logOutput = ""; // console.log を一時的にオーバーライド const originalConsoleLog = console.log; console.log = (...args: unknown[]) => { logOutput += args.map((arg) => String(arg)).join(" ") + "\n"; }; let evalOut = ""; try { evalOut = eval(code) ?? ""; } catch (e) { evalOut = `Error: ${e}`; } // console.log を元に戻す console.log = originalConsoleLog; return logOutput + evalOut + "\n__EOF__"; };
🔗 https://exit-prog8-vercel.vercel.app
____Team hanami より愛を込めて 🌸