设计插件
底层原理 动态的 import 文件
async function loadJs(path) {
console.log(path);
let { plugin } = await import(path);
console.log(plugin);
console.log(plugin(ctx).uploader);
}
async function requirePlugin(name) {
let home = await homeDir();
const pluginDir = join(home, ".atoolsplugin/node_modules/");
// eslint-disable-next-line @typescript-eslint/no-var-requires
const plugin = require(pluginDir + name)(this.ctx);
console.log(plugin);
}
设计基类 包含插件属性
this.configPath = configPath //配置文件
this._pluginLoader = new PluginLoader(this) //加载插件
this.pluginHandler = new PluginHandler(this) //管理插件
this.lifecycle = new Lifecycle(this) //生命周期
//帮助方法
this.helper = {
transformer: new LifecyclePlugins('transformer'),
uploader: new LifecyclePlugins('uploader'),
beforeTransformPlugins: new LifecyclePlugins('beforeTransformPlugins'),
beforeUploadPlugins: new LifecyclePlugins('beforeUploadPlugins'),
afterUploadPlugins: new LifecyclePlugins('afterUploadPlugins')
}
//核心函数
async upload(input) {
if (this.configPath === '') {
return []
}
//核心代码 通过 调用 生命周期函数 在其内部 调用插件中的方法
// upload from path
const { output } = await this.lifecycle.start(input)
return output
}
加载插件
private readonly ctx: IPicGo //传入基类信息
private list: string[] = [] //全部插件
private readonly pluginMap: Map<string, IPicGoPluginInterface> = new Map() //可通过名称获取插件
// 没有 就导入
async getPlugin(name) {
if (this.pluginMap.has(name)) {
return this.pluginMap.get(name)
}
let re= await exists('.atoolsplugin/'+name, { dir: BaseDirectory.Home });
if (re){
let path = join(this.ctx.baseDir,'.atoolsplugin/',name,'index.js')
let { plugin } = await import(path);
this.pluginMap.set(name, plugin)
return plugin
}
}
registerPlugin(name, plugin) {
this.fullList.add(name)
try {
// register local plugin
if (!plugin) {
if (this.ctx.getConfig(`picgoPlugins.${name}`) === true || (this.ctx.getConfig(`picgoPlugins.${name}`) === undefined)) {
this.list.push(name)
setCurrentPluginName(name)
// 核心语句 获取到插件后 调用 插件内的注册方法
//将当前上下文传入后 即可 在插件内部 设置上下文的信息了
this.getPlugin(name).register(this.ctx)
const plugin = `picgoPlugins[${name}]`
this.ctx.saveConfig(
{
[plugin]: true
}
)
}
} else {
// register provided plugin
// && won't write config to files
this.list.push(name)
setCurrentPluginName(name)
const pluginInterface = plugin(this.ctx)
this.pluginMap.set(name, pluginInterface)
// 核心语句 获取到插件后 调用 插件内的注册方法
//将当前上下文传入后 即可 在插件内部 设置上下文的信息了
pluginInterface.register(this.ctx)
}
} catch (e) {
this.pluginMap.delete(name)
this.list = this.list.filter((item) => item !== name)
this.fullList.delete(name)
}
}