Skip to content

事件 ​

事件是 Cormi 的扩展点。umi 里 api.modifyXxx、api.onXxx 的用途,在这里由事件承担。

ts
ctx.on('build/after', async ({ outDir }) => {
  await writeFile(join(outDir, 'version.txt'), version)
})

ctx.on() 是 effect:插件卸载时监听随之移除。

分发方式 ​

每个事件都写明它的分发方式,决定了监听器如何被调用、返回值有什么意义:

方式调用返回值
emit同步调用所有监听器忽略
parallel并行调用所有监听器,等待全部完成忽略
serial依次调用,等待每一个第一个不为 undefined 的返回值
bail同步依次调用第一个不为 undefined 的返回值,之后的监听器不再调用
waterfall环绕式中间件:最后一个参数是 next,调用它进入下一个监听器由监听器决定

Node 端 ​

事件方式时机
router/update(routes)emit路由表重新计算且发生变化之后
app/generate()emitsrc/.cormi 写入之后
build/before()parallelVite 构建开始之前
build/after(result)parallel客户端与服务端 bundle 写入之后;result 含 outDir、assets、inputs、server
workspace/update(packages)emit工作区的插件包增加或减少之后

浏览器端 ​

事件方式时机
router/change(location, action)emit位置变化,包括初始位置
app/bootstrap()bail入口即将挂载应用;返回 true 表示由该插件接管挂载
app/mount()emit应用渲染进页面之后
app/props(props)emit宿主(如 qiankun 主应用)更新了传入的 props

插件的事件 ​

官方插件也通过事件开放扩展点:

事件方式插件用途
request/fetch(url, init, config, next)waterfallrequest拦截请求,可修改请求或替换响应
request/error(error, config)bailrequest全局错误处理,返回 true 表示已处理
initialState/load()serialinitial-state提供初始状态
dva/create(app)emitdvadva 实例创建之后,可以注册模型、插件
reactQuery/client(client)emitreact-queryQueryClient 创建之后
federation/load(name, ctx)emitfederation一个子包加载完毕

例如给所有请求加上令牌:

ts
import type { Context } from '@cormijs/cormi/client'
import type {} from '@cormijs/plugin-request/client'

export default (ctx: Context) => {
  ctx.on('request/fetch', async (url, init, config, next) => {
    init.headers.set('authorization', `Bearer ${localStorage.getItem('token')}`)
    return next()
  })
}

声明自己的事件 ​

事件通过声明合并(declaration merging)声明,名字采用 命名空间/动作 的形式,并在注释里写明分发方式:

ts
declare module 'cordis' {
  interface Events {
    /**
     * The search index is about to be written.
     * @mode waterfall
     */
    'search/index'(documents: Document[], next: () => Promise<Document[]>): Promise<Document[]>
  }
}

// 触发
const documents = await ctx.waterfall('search/index', collected, async () => collected)
触发方法对应方式
ctx.emit(name, ...args)emit
ctx.parallel(name, ...args)parallel
ctx.serial(name, ...args)serial
ctx.bail(name, ...args)bail
ctx.waterfall(name, ...args, next)waterfall

以 MIT 许可发布 · 基于 Cordis 4、React 19 与 Vite 7