跳转到主要内容

扩展钩子

在 Comfy 执行的不同阶段,应用会调用 #invokeExtensionsAsync#invokeExtensions,并传入钩子的名称。 这些方法会在所有已注册的扩展上调用同名方法(如果存在),比如上面例子中的 setup Comfy 提供了多种钩子,供自定义扩展代码使用,以修改客户端行为。
这些钩子会在 Comfy 客户端元素的创建和修改过程中被调用。
工作流执行过程中的事件由 apiUpdateHandlers 处理。
下面介绍了一些最重要的钩子。由于 Comfy 仍在积极开发中,新的钩子会不时加入,因此可以在 app.js 中搜索 #invokeExtensions 以查找所有可用钩子。 另请参阅钩子的调用顺序

常用钩子

beforeRegisterNodeDef 开始,大多数扩展都会用到它,通常也是唯一需要的钩子。

beforeRegisterNodeDef()

对每种节点类型(即 AddNode 菜单中可用的节点列表)调用一次,用于修改节点的行为。
传入的 nodeType 参数本质上是该类型所有节点的模板,因此对 nodeType.prototype 的修改会应用到所有该类型节点上。nodeData 封装了 Python 代码中定义的节点相关信息,如类别、输入和输出。app 是主 Comfy app 对象的引用(你应该已经导入了它!)
该方法会对每个已注册扩展、每种节点类型都调用一次,而不仅仅是扩展自己添加的节点。
常见做法是检查 nodeType.ComfyClass,它保存了该节点对应的 Python 类名,以判断是否需要修改该节点。通常这意味着只修改你自己添加的自定义节点,但有时也可能需要修改其他节点(或其他自定义节点也可能修改你的节点!),此时要注意兼容性。
由于其他扩展也可能会修改节点,建议尽量减少假设,并尽量隔离你的更改,友好共存。
beforeRegisterNodeDef 中非常常见的做法是”劫持”已有方法:
已弃用: 下面展示的原型劫持模式已被弃用,可能在不久的将来随时更改。对于右键菜单,请改用官方的 右键菜单 API。对于其他用例,请尽可能使用官方的 扩展钩子
这种做法是先保存原型上的原方法,然后替换为新方法。新方法会调用原方法(?.apply 保证即使没有原方法也不会出错),然后执行额外操作。根据你的代码逻辑,可能需要在新方法的其他位置调用 apply,甚至有条件地调用。 以这种方式劫持方法时,建议查看核心 comfy 代码(断点调试很有用),以确保方法签名一致。
这种方法比较脆弱,可能会在未来的 ComfyUI 更新中失效。请尽可能使用官方 API。

nodeCreated()

当某个节点实例被创建时调用(就在 nodeType 上的 ComfyNode() 构造函数结束时)。在这个钩子里你可以修改节点的具体实例。
如果是对所有实例都生效的更改,建议在上文的 beforeRegisterNodeDef 里加到 prototype 上。

init()

当 Comfy 网页被加载(或重新加载)时调用。调用时机是在图对象已创建,但还未注册或创建任何节点之前。可以用来劫持 app 或 graph(LiteGraph 对象)的方法,从而修改核心 Comfy 行为。详见Comfy 对象与劫持
能力越大,责任越大。劫持核心行为可能导致你的节点与其他自定义节点或未来 Comfy 更新不兼容。

setup()

在启动流程结束时调用。适合添加事件监听器(无论是 Comfy 事件还是 DOM 事件),或添加全局菜单,相关内容在其他地方有详细介绍。
如果要在工作流加载后做事,请用 afterConfigureGraph,不要用 setup

调用顺序

以下顺序是通过在 Comfy app.js 文件中插入日志代码获得的。你也可以用类似方法帮助理解执行流程。

网页加载时

加载工作流

添加新节点