关于前端插件化
什么是前端插件化
插件化是将软件应用的功能模块化,使各个单位模块都可以独立开发、部署和更新。通过将不同功能封装成插件,开发者可以灵活地添加或移除功能,而不影响主应用的整体结构。这种方式不仅提高了代码的可维护性和复用性,还使团队能够并行开发不同的功能模块。
从上图中可以看出,主要由两部分组成:Core + plugin,也就是一个内核和多个插件。通常来说:
- 内核主要负责一些基础功能、核心功能以及插件的管理;
- 插件则是一个独立的功能模块,用来丰富和加强内核的能力。
常见的前端插件架构
常见的前端插件架构包括:
- Webpack:作为模块打包器,支持通过插件扩展功能,如代码压缩和热重载等。
- Vue插件:Vue.js支持通过插件系统来扩展功能,允许开发者添加全局方法、混入和自定义指令等。
- React HOCs(高阶组件) :通过函数式编程来实现组件的复用与功能扩展等。
- jQuery:通过扩展 jQuery 的原型,使开发者能够创建可重用的功能模块。
- 。。。。。
Demo
项目截图
- 技术栈:electron + React + vite
首先,先在 /public 文件夹下声明10个js插件(当然有条件的话可以放私服),这里图方便,每个插件都输出类似的对象。这里采用esmodule规范编写插件代码,最后导出定义好的方法变量。
// App.tsx
useEffect(() => {
// 安装已下载插件
const plugins = getDownloadPlugins();
if (plugins && plugins.length) {
plugins.forEach((e) => {
importPlugin(e);
});
}
}, []);
然后在入口处,项目初始化的时候,将缓存在electron缓存中的已下载目录依次导入
// /utils/index.tsx
/**
* 导入插件至全局
* @params id 插件id
*/
export const importPlugin = (id) => {
const script = document.createElement("script");
script.src = `pluginList/p${id}.js`;
script.type = "module";
document.body.appendChild(script);
import(/* @vite-ignore */ `../../pluginList/p${id}.js`).then((res) => {
window.$plugins[`P${id}`] = res.default;
});
notification.open({
message: `插件${id}运行成功`,
description: `插件${id}运行成功`,
icon: <SmileOutlined style={{ color: "#108ee9" }} />,
});
};
通过动态创建script标签,将模块插件注入到项目中,并且挂载到全局对象window.$plugins对象上
<script> 标签加上 type="module" 后,该脚本会变成异步加载的,不会阻塞浏览器的渲染,然后等到整个页面渲染完,再执行模块脚本,等同于打开了 <script> 标签的defer属性。如果网页有多个<script type="module">,它们会按照在页面出现的顺序依次执行。
详细可见 JavaScript modules
插件安装后的效果:
安装完就可以直接使用插件里面暴露出来的内容:
当然,对于其他没有安装的话,直接调用肯定会报错,为此这里借助Vue3响应式原理用到的Proxy特性进行拦截:
// App.tsx
window.$plugins = new Proxy(
{},
{
get(target, key) {
if (!Reflect.has(target, key)) {
message.warning("请先至插件市场下载插件~~~");
return false;
}
return Reflect.get(target, key);
},
}
);
最后,灵活插拔作为插件化的一个亮点,为此这里还设计插件市场和插件管理两个页面,方便进行可插拔操作。
未完成清单
- 借助webpack工作流程的思路,后续可以加入发布监听模式,扩展功能。
- 目前仅支持js文件,后续可以研究一下其他类型语言接入的可行性。
- 。。。。。。
欢迎各位道友指导!!!🤝