ES6 Class插件系统核心是约定清晰与生命周期可控:定义Plugin基类强制实现install方法;Core类通过use注册、installPlugins调用插件;支持同步/异步安装、命名空间隔离及钩子控制。

用 ES6 Class 实现插件系统,核心是让主类支持动态注册、实例化和调用插件,同时保证插件有统一接口、可配置、不互相干扰。关键不在“多高级”,而在“约定清晰 + 生命周期可控”。
定义插件基类(统一接口)
所有插件必须继承一个基类,强制实现 install 方法——这是插件被加载时的入口,接收主实例和配置项。
例如:
class Plugin {
constructor(options = {}) {
this.options = options;
}
install(instance, pluginOptions) {
// 必须由子类重写,用于扩展 instance 的方法/属性/事件等
throw new Error('Plugin.install() must be implemented');
}
}
这样能避免插件随意命名初始化方法,也方便主系统统一调用。
主类支持插件注册与安装
主类内部维护插件列表,提供 use 方法注册插件,installPlugins 方法批量执行安装逻辑。
示例结构:
class Core {
constructor() {
this.plugins = [];
}
use(PluginClass, options = {}) {
this.plugins.push({ PluginClass, options });
return this; // 支持链式调用
}
installPlugins() {
this.plugins.forEach(({ PluginClass, options }) => {
const plugin = new PluginClass(options);
plugin.install(this, options);
});
}
}
- 插件以类(而非实例)传入,便于每次 new 出独立实例,避免状态污染
-
install 方法中可直接修改 this(即主实例),比如挂载方法:
this.sayHello = () => console.log('hi'); - 也可通过事件、钩子等方式解耦,比如在 install 中监听
this.on('ready', ...)
插件内安全扩展主实例
插件不应直接覆盖主类已有属性,推荐使用命名空间或 Symbol 避免冲突。
- 挂载到子属性:如
instance.ui = { render() {}, hide() {} } - 用 Symbol 做私有键:
const PRIVATE_KEY = Symbol('myPluginData'); instance[PRIVATE_KEY] = {...} - 若需注入方法,优先用箭头函数绑定 this,防止丢失上下文
支持异步插件与安装时机控制
有些插件需要异步初始化(如加载远程配置、连接服务)。可在基类中约定 install 返回 Promise,并在主类中 await 所有插件完成。
async installPlugins() {
await Promise.all(
this.plugins.map(async ({ PluginClass, options }) => {
const plugin = new PluginClass(options);
await plugin.install(this, options); // 允许 install 是 async
})
);
}
再配合生命周期钩子(如 beforeInit、afterInit),就能灵活控制插件执行顺序。


















