🛠️

ComfyUI Custom Nodes用のTypeScriptテンプレートを公開しました

2025/02/16に公開

TL;DR

ComfyUIのCustom NodesをTypeScriptで開発するためのテンプレートを公開しました。

https://github.com/xhiroga/ComfyUI-TypeScript-CustomNode

Star⭐️お待ちしております!

ComfyUI Custom Nodeとは?

ComfyUI は、拡散モデルや LLM などを実行するためのワークフローを GUI 上で実装・管理できるアプリケーションです。ノードベースのインターフェースを採用しており、各ノードが特定の処理を実行し、それらを繋ぎ合わせることで複雑なワークフローを構築できます。

Custom Nodesを用いることで、公式には用意されていない処理(例えばCV系の処理)を組み込むことができます。また、ノードのUIをカスタマイズすることができます。

詳細は公式ドキュメントをご覧ください。

Custom NodesのUI開発の課題

ComfyUIのCustom NodesのUIの開発とは、ざっくり言えば「本体からimportしたappのインスタンスのイベントリスナーにフックを登録する」プログラムを書くことです。

具体的には、次のようなコードになります。

import { app } from "../../../scripts/app.js";

const custom_function = () => {
  // ここにカスタムコード
}

app.registerExtension({
  name: "SomeCustomNode",
  async beforeRegisterNodeDef(nodeType, nodeData, app) {
    if (nodeData.name === "SomeCustomNode") {
      const onExecuted = nodeType.prototype.onExecuted;
      nodeType.prototype.onExecuted = function(message) {
        onExecuted?.apply(this, arguments);
        custom_function.call(this. message)
      }
    }
  }
})

ツラいポイント

ComfyUIのCustom NodesのUI開発を行う場合の辛い点は次のとおりです。

  1. 公式ドキュメントが不足しています。利用可能なイベントリスナーや引数の型についての情報が少なく、実際に動かしながらの開発が必須です。
  2. TypeScriptで開発されたCustom Nodesのサンプルがありません。ComfyUIのFrontendは型情報を@comfyorg/comfyui-frontend-typesとしてnpmに公開しているのですが、2025年2月24日時点でGitHub上にそれをimportしているソースコードは存在しませんでした。

ComfyUI-TypeScript-CustomNodeの紹介

前述の理由からComfyUIのCustom NodesのUIをTypeScriptで開発したいところですが、サンプルが少ないため雛形を作るまでに数時間程度を要しました。

非常に徒労を感じたので、テンプレートを作って公開した、という流れです。

ComfyUI-TypeScript-CustomNodeを用いた開発手順

テンプレートを利用した ComfyUI カスタムノード開発の基本的な手順は以下の通りです。

  1. テンプレートリポジトリのページを開く
  2. use this templateを押下
  3. make install コマンドを実行し、必要な依存ライブラリをインストール。
  4. カスタムノードを開発: web/src ディレクトリに TypeScript コードを作成します。
  5. 開発サーバーを起動: make dev コマンドを実行し、ComfyUI を起動します。

ComfyUI-TypeScript-CustomNodeの実装上のポイント

本テンプレートを実装する上で工夫した点です。テンプレートを用いずにTypeScriptで開発される方にも参考になると思います。

1. @comfyorg/comfyui-frontend-typesのバグ解消

ComfyUIのフロントエンドはlitegraphを用いて開発されていますが、独自の拡張が入っています。

それらはアンビエント宣言(declare)でmoduleを拡張することで定義されていたのですが、@comfyorg/comfyui-frontend-typesv1.10.0まではその情報が含まれていませんでした。

PRを送ったところすぐにmergeしていただいたので、現在は修正済みです。

2. 本体からの相対importをコンパイル時に差し込む

ComfyUIのCustom NodesのUIのソースコードは、サーバー起動時には次の位置にデプロイされます。

localhost:8188
- assets
- extensions
  - ComfyUI-TypeScript-CustomNode
    - index.js <- HERE!!!
- scripts
  - app.js

したがって、appインスタンスはimport { app } from "../../scripts/app.js";のようにimportします。

しかし、Custom Nodes開発時点では../../scripts/app.jsは存在しないので、コンパイル時に挿入することになります。viteでは次のような指定になります。

// vite.config.mts
import { defineConfig } from 'vite'

export default defineConfig({
  build: {
    ...,
    rollupOptions: {
      plugins: [
        inject({
          app: ['../../scripts/app.js', 'app']
        })
      ],
      external: (id) => id.startsWith('../../scripts/'),
    }
  },
  ...,
})

まとめ

ComfyUI のCustom Nodeを TypeScript で開発する手順についてお伝えしました。特に公式ドキュメントが十分でない場合、型情報による開発のサポートは非常に強力です。

ぜひ ComfyUI-TypeScript-CustomNode テンプレートを利用して、TypeScript での ComfyUI カスタムノード開発を試してみてください。

GitHubで編集を提案

Discussion