基于web/h5应用的插件/扩展/业务剥离方案设计(第二篇 ECMA5.1方案)
系列目录
基于web/h5应用的插件/扩展/业务剥离方案设计(第一篇 简介)
介绍
本文重点讲述传统类(js不经过编译和混淆,源码===生产代码)网站的扩展实现,后续会讲解ES6+vue方案
在传统不经过压缩和预编译的情况下,我们设计基于应用的扩展变得相对容易很多,我们不需要关注webpack的底层打包逻辑, 也不需要关注代码混淆原理,因为这对新手来说不太友好。
下面列举一个简单的例子
- 我们想在张三进入系统后,给他弹出来一个欢迎语,
- 在他进入个人中心时,如果是国庆节,我们在它的头像上加一个小红旗。(具体代码就不讲解了,就是判断时间,获取节点,追加一个小红旗图片(图片没上传的可以用base64))
管理员端(后端)
- 设计一张扩展表,用来存储用户独特的脚本
- 字段大致是,用户account,执行时机moduleName,扩展内容content等
- 我们新建两个扩展分配给张三,分配后数据库数据如下
用户account(谁在用这个) | 执行时机moduleName(在进入哪个模块时生效) | 扩展内容content |
---|---|---|
张三 | init | alert("欢迎您,"+data.account) |
张三 | mine | ... |
- 提供一个获取当前用户扩展的接口给前端
服务端用来给前端存储扩展,提供给管理员增删改查的权限,提供给用户查自己扩展的权限。
浏览器端 (前端)
- 客户在进入系统时候,调用后台提供的查询当前用户扩展的接口。
- 获取到该用户所有的模块名为初始化的扩展,执行他们
- 在模块进入的地方埋下钩子,扩展会在用户触发时生效。
- 此时例子中的功能已经实现。伪代码如下。
//假如我们使用的jquery
var index = {
extensions:[],
evalExtensions:function(moduleName,data) {
for(var i=0;i<index.extensions.length;i++){
//便利集合,找到当前模块所属的扩展
if(index.extensions[i].moduleName===moduleName){
try{
//执行当前扩展,并把调用时传的data,或者当前扩展传进去
new Function("data",index.extensions[i].content)(data||index.extensions[i])
}catch (e) {
console.error(e)
}
}
}
},
toModule:function(moduleName) {
index.evalExtensions(moduleName);
//其他基础代码
}
};
function init(){
//初始化获取当前用户的扩展列表
$.get("扩展的后台接口地址",function(extensions) {
index.extensions=extensions;
//然后直接执行模块名为init的扩展
index.evalExtensions("init");
});
$("#mine").on("click",function() {
index.toModule("mine")
})
}
init()
上述代码只是随便书写,目的是讲解扩展的思路如何实现,实际需要根据你所在的项目,结合自身的代码去书写(比如钩子函数埋在哪,以及将什么样的参数传给扩展等),大致思路是不会变的。
总结
我们做到了基础功能和扩展功能的脱离,不用因活动而增加代码,因活动结束而移除代码。
试想一下,当我们在凌晨上线一个功能后,如果测试没发现问题,第二天有用户反馈有问题,我们选择上紧急版本修复?回滚?这些都会涉及到领导和自己的考核,如果不是主链路, 我们可以上一个全局扩展(将某个扩展分配给所有人)来解决此问题,扩展管理就变成了漏洞修复功能,其实扩展和热更新的思路差不多,可以变成增加功能,也可以去动态修复问题。
结束语:如果遇到了问题,欢迎在评论区交流,如果觉得不错,可以点赞和收藏,持续更新 。
博客中标注原创的文章,版权归原作者 苦中作乐才是人生巅峰 所有;转载或者引用本文内容请在评论区说明,以及注明来源及原作者;