说起来,面向切面编程(AOP)自从诞生之日起,一直都是计算机科学领域十分热门的话题,但是很奇怪的是,在前端圈子里,探讨AOP的文章似乎并不是多,而且多数拘泥在给出理论,然后实现个片段的定式)难免陷入了形而上学的尴尬境地,本文列举了两个生产环境的实际例子论述webpack和AOP预编译处理的结合,意在抛砖引玉。当然,笔者能力有限,如果有觉得不妥之处,还请大家积极的反馈出来,共同进步哈。
<强> AOP: >强面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
<>强联合点:强>表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它联合点。
<强>建议:强>建议定义了在切入点里面定义的程序点具体要做的操作,它通过之前,和之后在来区别是在每个交接点之前,之后还是代替执行的代码。
通过前面的定义,我们可以提炼出一句更简单的定义,利用静/动态的方式使代码块在何时/何地运行。
项目的背景是一个利用vue + webpack打造的多页面应用(多入口点),她的结构大概是这个样子的
var baseConf={//代码 条目:{ 指数:“src/指数”, 名单:“src/列表”, 细节:src/细节,//所以> 从“Vue”进口Vue 导入应用程序从“/App。” 新Vue ({ 埃尔:“#应用”, 呈现:h=比;h(应用) })
期望引入一个vue插件,能够自动的监控当前页面的性能,于是,代码看起来像是这个样子
从“Vue”进口Vue Vue.use(性能)//性能统计 导入应用程序从“/App。” 新Vue ({ 埃尔:“#应用”, 呈现:h=比;h(应用) })
由于这种方式意味着每个入口点均需要进行修改,(实际上这个项目的入口点超过30个,而且随时可能继续增加下去)简直就是一个体力活,所以,让我们用AOP的思想来考虑一下如何处理这个问题
<强>首先观察入口点逻辑强>
原:引入vue→引入应用程序组件→实例化vue组件
新:引入vue→应用性能统计组件→引入应用程序组件→实例化vue组件
<>强套用到我们的定义上,可以轻松的得到强>
接合点(何处)引入vue
建议(何时)之后
这样理论上的东西似乎闭着眼睛都可以推论出来,但是如何将这样的步骤替换到每一个入口点就是一个大问题了五体投地。幸运的是这是一个导入,而翻阅webpack的文档恰好有着这样一个神奇的属性——别名
解决:{ 别名:{ “vue美元”:解决(src/vueHook.js) }
src/vueHook.js
从“进口vue vue/dist/vue.common ' vue.use(性能) 出口默认vue
这样,我们就完成了一个vue的全局钩子模块,我们按照步骤归纳,并且找到注入的位置,最后利用替换的方式成功的完成了无侵入式的组件应用
<强>代码拆分强>
可能上面的例子有点小打小闹的感觉,那么我们换一个案例,再来体验一下这种静态替换式的注入的威力,我们采用官方支持较差的反应作为参考(vue在代码拆分方面做得真心是超级棒~)
从“. ./. ./进口SingleImage组件模块/magic-single-image/src/指数”; 从“. ./. ./进口DoubleImage组件模块/magic-double-image/src/指数”; 从“. ./. ./进口ThreeImage组件模块/magic-three-image/src/指数”;//这里的许多组件 开关(componentName) { 例“SingleImage”: PreviewingComponent=SingleImage; 打破; 例“DoubleImage”: PreviewingComponent=DoubleImage; 打破; 例“ThreeImage”: PreviewingComponent=ThreeImage; 打破;//这里的许多组件 } 返回(& lt; PreviewingComponent> & lt;/PreviewingComponent>)
一段中规中矩的代码,对吧?相信大家已经发现了,在上述的代码里面似乎并不是每个组件都是必须的,那么,基于以上的思考,可以对上面组件进行按需加载处理,包。jsx
进口的反应,从“反应”{组件,proptype}; 类包扩展组件{ 静态proptype={ 负载:PropTypes.func, 孩子们:PropTypes.func, } 状态={ 国防部:空, } componentWillMount () { this.load (this.props); } componentWillReceiveProps (nextProps) { 如果(nextProps。负载!==this.props.load) { this.load (nextProps); } } 加载(道具){ this.setState ({ 国防部:空, }); props.load(),然后((mod)=比;{ this.setState ({//处理es进口和cj 国防部:mod.default & # 63;mod.default:国防部, }); }); } 呈现(){ this.state返回。国防部& # 63;this.props.children (this.state.mod):空; } } 出口默认包;浅谈webpack下的AOP式无侵入注入