zhin-plugin-lifecycle

Compare original and translation side by side

🇺🇸

Original

English
🇨🇳

Translation

Chinese

Zhin Plugin Lifecycle Guide

Zhin 插件生命周期指南

Use this skill to help developers scaffold and reason about Zhin plugins, including lifecycle hooks, auto-loading behavior, and hot-reload interactions.
使用本技能帮助开发者搭建和理解Zhin插件,包括生命周期钩子、自动加载行为以及热重载交互逻辑。

Plugin Scaffold

插件脚手架

Start with the minimal plugin entry file that uses
usePlugin()
so Zhin can create a plugin instance for the file:
ts
import { usePlugin } from '@zhin.js/core'

const plugin = usePlugin()

plugin.onMounted(() => {
  plugin.logger.info(`Plugin ${plugin.name} mounted`)
})

plugin.onDispose(() => {
  plugin.logger.info(`Plugin ${plugin.name} disposed`)
})
从使用
usePlugin()
的最小化插件入口文件开始,这样Zhin就能为该文件创建一个插件实例:
ts
import { usePlugin } from '@zhin.js/core'

const plugin = usePlugin()

plugin.onMounted(() => {
  plugin.logger.info(`Plugin ${plugin.name} mounted`)
})

plugin.onDispose(() => {
  plugin.logger.info(`Plugin ${plugin.name} disposed`)
})

Key Concepts

核心概念

  • usePlugin()
    creates (and registers) the plugin instance based on the current file path.
  • Plugin names are derived from the file path (package name or folder name).
  • plugin.onMounted
    runs after contexts are mounted and child plugins start.
  • plugin.onDispose
    runs when the plugin is stopped or reloaded.
  • usePlugin()
    会根据当前文件路径创建(并注册)插件实例。
  • 插件名称由文件路径(包名或文件夹名)派生而来。
  • plugin.onMounted
    会在上下文挂载完成且子插件启动后执行。
  • plugin.onDispose
    会在插件停止或重载时执行。

Hot Reload Behavior

热重载行为

In development mode (
NODE_ENV=development
), the core will watch plugin files and trigger reloads when they change.
ts
plugin.onMounted(() => {
  plugin.logger.debug('Plugin ready for HMR')
})
在开发模式下(
NODE_ENV=development
),核心模块会监听插件文件,当文件发生变化时触发重载。
ts
plugin.onMounted(() => {
  plugin.logger.debug('Plugin ready for HMR')
})

Reload Flow

重载流程

  1. File changes trigger
    plugin.reload()
    .
  2. The plugin is stopped via
    plugin.stop()
    .
  3. Parent re-imports the plugin entry file.
  4. mounted
    lifecycle events fire again.
If the plugin is the root plugin, reload exits the process (
exit code 51
) so the CLI can restart it.
  1. 文件变化触发
    plugin.reload()
  2. 通过
    plugin.stop()
    停止插件。
  3. 父插件重新导入插件入口文件。
  4. 再次触发
    mounted
    生命周期事件。
如果该插件是根插件,重载会终止进程(退出码51),以便CLI重新启动它。

Adding Child Plugins

添加子插件

Use
plugin.import()
to load child plugins relative to the current file:
ts
await plugin.import('./sub-plugin/index.ts')
Notes:
  • The core prevents double-loading the same resolved path.
  • Child plugins are stopped automatically when the parent stops.
使用
plugin.import()
加载相对于当前文件的子插件:
ts
await plugin.import('./sub-plugin/index.ts')
注意:
  • 核心模块会防止重复加载相同的解析路径。
  • 当父插件停止时,子插件会自动停止。

Common Diagnostics

常见诊断方法

  • plugin.features
    returns registered commands, components, crons, and middleware names.
  • plugin.info()
    returns a nested tree of features for the plugin and its children.
Use this to build "health" commands for debugging plugin loads.
  • plugin.features
    会返回已注册的命令、组件、定时任务和中间件名称。
  • plugin.info()
    会返回插件及其子插件的嵌套特性树。
可使用这些方法构建用于调试插件加载情况的“健康检查”命令。

Checklist When Authoring Plugins

插件开发检查清单

  • Ensure the entry file calls
    usePlugin()
    once.
  • Use
    onDispose
    to clean up timers or external connections.
  • Use
    plugin.import()
    for dependent plugins.
  • Prefer
    plugin.onMounted
    for deferred setup once contexts are ready.
  • 确保入口文件仅调用一次
    usePlugin()
  • 使用
    onDispose
    清理定时器或外部连接。
  • 使用
    plugin.import()
    加载依赖插件。
  • 优先使用
    plugin.onMounted
    在上下文准备完成后进行延迟初始化。