Modern.js 框架插件开发指南:扩展自定义 Hook 模型
2025-07-08 07:00:54作者:廉皓灿Ida
前言
Modern.js 作为一款现代化的前端开发框架,其插件系统提供了强大的扩展能力。本文将深入讲解如何在 Modern.js 中通过动态注册 Hook 模型来扩展插件功能,帮助开发者构建更灵活的插件体系。
什么是 Hook 模型
Hook 模型是 Modern.js 插件系统的核心机制之一,它允许插件在特定生命周期节点注入自定义逻辑。通过 Hook 模型,不同插件可以在不直接耦合的情况下相互协作。
Modern.js 内置了多种 Hook 类型,包括:
- Waterfall(瀑布流):前一个插件的输出作为下一个插件的输入
- Bail(保险丝):任一插件返回非 undefined 值则终止后续执行
- Parallel(并行):所有插件并行执行
创建自定义 Hook
1. 初始化项目
首先确保你已经创建了一个 Modern.js 项目。如果尚未创建,可以通过以下命令初始化:
npx @modern-js/create@latest modern-js-demo
2. 定义 Hook 模型
我们以创建一个控制台消息收集 Hook 为例:
import { createWaterfall } from '@modern-js/plugin';
// 创建一个 Waterfall 类型的 Hook,用于收集字符串数组
const message = createWaterfall<string[]>();
这里我们选择了 Waterfall
类型,因为消息收集通常需要将多个插件的输出串联起来。
3. 注册 Hook 模型
在插件中注册我们定义的 Hook:
import type { CliPlugin } from '@modern-js/core';
export const myPlugin = (): CliPlugin => ({
name: 'my-plugin',
registerHook: {
message, // 注册自定义 Hook
},
});
4. 扩展类型声明
为了让 TypeScript 能够识别我们的新 Hook,需要扩展核心类型:
declare module '@modern-js/core' {
export interface Hooks {
message: typeof message; // 将 message Hook 添加到类型系统
}
}
使用自定义 Hook
1. 创建命令调用 Hook
我们可以在插件中创建一个命令来触发 Hook 执行:
setup(api) {
return {
commands({ program }) {
program.command('message').action(async () => {
const hookRunners = api.useHookRunners();
// 执行 message Hook,初始传入空数组
const messages = hookRunners.message([]);
console.log(messages.join('\n'));
});
},
};
}
2. 完整插件代码
将以上部分组合起来,完整的插件代码如下:
import { createWaterfall } from '@modern-js/plugin';
import type { CliPlugin } from '@modern-js/core';
const message = createWaterfall<string[]>();
export const myPlugin = (): CliPlugin => ({
name: 'my-plugin',
registerHook: {
message,
},
setup(api) {
return {
commands({ program }) {
program.command('message').action(async () => {
const hookRunners = api.useHookRunners();
const messages = hookRunners.message([]);
console.log(messages.join('\n'));
});
},
};
},
});
declare module '@modern-js/core' {
export interface Hooks {
message: typeof message;
}
}
3. 配置插件
在项目配置文件中启用我们的插件:
import { defineConfig } from '@modern-js/app-tools';
import { myPlugin } from './config/plugin/myPlugin';
export default defineConfig({
plugins: [myPlugin()],
});
扩展 Hook 功能
1. 创建提供消息的插件
现在我们可以创建另一个插件来提供消息内容:
import type { CliPlugin } from '@modern-js/core';
export const otherPlugin = (): CliPlugin => ({
name: 'other-plugin',
setup(api) {
return {
message(list) {
// 在现有列表基础上添加两条消息
return [...list, '[foo] line 0', '[foo] line 1'];
},
};
},
});
2. 更新配置
同时启用两个插件:
import { defineConfig } from '@modern-js/app-tools';
import { myPlugin } from './config/plugin/myPlugin';
import { otherPlugin } from './config/plugin/otherPlugin';
export default defineConfig({
plugins: [myPlugin(), otherPlugin()],
});
3. 运行命令
现在执行命令可以看到输出:
npx modern message
[foo] line 0
[foo] line 1
高级用法
多插件协作
多个插件可以共同贡献内容到同一个 Hook:
// 第三个插件
export const thirdPlugin = (): CliPlugin => ({
name: 'third-plugin',
setup(api) {
return {
message(list) {
return [...list, '[bar] additional message'];
},
};
},
});
配置三个插件后,输出将包含所有插件的贡献:
[foo] line 0
[foo] line 1
[bar] additional message
Hook 执行顺序
Hook 的执行顺序通常由插件注册顺序决定。Modern.js 提供了优先级机制来控制执行顺序:
export const highPriorityPlugin = (): CliPlugin => ({
name: 'high-priority-plugin',
pre: ['my-plugin', 'other-plugin'], // 确保在其他插件之前执行
setup(api) {
// ...
},
});
总结
通过扩展 Hook 模型,Modern.js 插件可以实现高度灵活的协作模式。本文展示了:
- 如何创建自定义 Hook 模型
- 如何注册和使用 Hook
- 多插件如何通过 Hook 协作
- 控制 Hook 执行顺序的方法
这种机制使得 Modern.js 插件系统具备了极强的扩展性,开发者可以根据项目需求自由组合各种功能插件。