小议webpack下的AOP式无侵入注入
说起来, 面向切面编程(AOP)自从诞生之日起,一直都是计算机科学领域十分热门的话题,但是很奇怪的是,在前端圈子里,探讨AOP的文章似乎并不是多,而且多数拘泥在给出理论,然后实现个片段的定式)难免陷入了形而上学的尴尬境地,本文列举了两个生产环境的实际例子论述webpack和AOP预编译处理的结合,意在抛砖引玉。当然,笔者能力有限,如果有觉得不妥之处,还请大家积极的反馈出来, 共同进步哈。
重要的概念
AOP: 面向切面编程,通过预编译方式和运行期动态代理实现程序功能的统一维护的一种技术。
Joint point:表示在程序中明确定义的点,典型的包括方法调用,对类成员的访问以及异常处理程序块的执行等等,它自身还可以嵌套其它 joint point。
Advice:Advice 定义了在 pointcut 里面定义的程序点具体要做的操作,它通过 before、after 和 around 来区别是在每个 joint point 之前、之后还是代替执行的代码。
通过前面的定义,我们可以提炼出一句更简单的定义,利用静/动态的方式使代码块在何时/何地运行。
性能统计
项目的背景是一个利用vue+webpack打造的多页面应用 (多入口点),她的结构大概是这个样子的
var baseConf = {
// code here
entry: {
index: 'src/index',
list: 'src/list',
detail: 'src/detail',
// and so on ...
},
// code here
}
然后以index入口点举例,大概代码为src/index/index.js
import Vue from 'vue'
import App from './app'
new Vue({
el: '#app',
render: h => h(App)
})
期望引入一个vue插件,能够自动的监控当前页面的性能,于是,代码看起来像是这个样子
import Vue from 'vue'
Vue.use(performance) //性能统计
import App from './app'
new Vue({
el: '#app',
render: h => h(App)
})
由于这种方式意味着每个入口点均需要进行修改,(实际上这个项目的入口点超过30个,而且随时可能继续增加下去)简直就是一个体力活。所以,让我们用AOP的思想来考虑一下如何处理这个问题
首先观察入口点逻辑
原:引入vue -> 引入app组件 -> 实例化vue组件
新:引入vue -> 应用性能统计组件 -> 引入app组件 -> 实例化vue组件
套用到我们的定义上,可以轻松的得到
- Joint point(何处) 引入vue
- advice(何时) 之后
这样理论上的东西似乎闭着眼睛都可以推论出来,但是如何将这样的步骤替换到每一个入口点就是一个大问题了orz。幸运的是这是一个import,而翻阅webpack的文档恰好有着这样一个神奇的属性--alias
resolve: {
alias: {
'vue$': resolve('src/vueHook.js')
}
src/vueHook.js
import vue from 'vue/dist/vue.common'
vue.use(performance)
export default vue
这样,我们就完成了一个vue的全局钩子模块,我们按照步骤归纳,并且找到注入的位置 ,最后利用替换的方式成功的完成了无侵入式的组件应用
code spliting
可能上面的例子有点小打小闹的感觉,那么我们换一个案例,再来体验一下这种静态替换式的注入的威力,我们采用官方支持较差的react作为参考(vue在code spliting方面做得真心是超级棒~)
import SingleImage from '../../component-modules/magic-single-image/src/index';
import DoubleImage from '../../component-modules/magic-double-image/src/index';
import ThreeImage from '../../component-modules/magic-three-image/src/index';
// many component here
switch (componentName) {
case 'SingleImage':
PreviewingComponent = SingleImage;
break;
case 'DoubleImage':
PreviewingComponent = DoubleImage;
break;
case 'ThreeImage':
PreviewingComponent = ThreeImage;
break;
// many component here
}
return(<PreviewingComponent></PreviewingComponent>)
一段中规中矩的代码,对吧?相信大家已经发现了,在上述的代码里面似乎并不是每个组件都是必须的,那么,基于以上的思考,可以对上面组件进行按需加载处理。 Bundle.jsx
import React, { Component, PropTypes } from 'react';
class Bundle extends Component {
static propTypes = {
load: PropTypes.func,
children: PropTypes.func,
}
state = {
mod: null,
}
componentWillMount() {
this.load(this.props);
}
componentWillReceiveProps(nextProps) {
if (nextProps.load !== this.props.load) {
this.load(nextProps);
}
}
load(props) {
this.setState({
mod: null,
});
props.load().then((mod) => {
this.setState({
// handle both es imports and cjs
mod: mod.default ? mod.default : mod,
});
});
}
render() {
return this.state.mod ? this.props.children(this.state.mod) : null;
}
}
export default Bundle;
以及相应的alias hook
export default (
<Bundle
load={() => import(/* webpackChunkName: "widget" */
`../../component-modules/magic-single-image/src/index`
)}
>
{Widget => <Widget {...props} />}
</Bundle>
)
思考,当组件多的时候每一个模块都需要一个人口点吗,可以从webpack.context角度简化这个问题吗?
以上两个例子均是模块引用作为join point来进行注入操作的,而且完成了无侵入式的功能增强,这得益于webpack将js模块作为一等公民。我们拥有着超多的权利完成静态式的注入工作。 本文并没有在技术上涉及太多,还是那句话,抛砖引玉哈~~~
如果你喜欢我们的文章,关注我们的公众号和我们互动吧。

小议webpack下的AOP式无侵入注入的更多相关文章
- 使用AOP思想无侵入式申请权限,解决组件化中权限问题(一)
首先介绍AspectJx使用 https://github.com/HujiangTechnology/gradle_plugin_android_aspectjx 在根项目的build.gradle ...
- Android免Root无侵入AOP框架Dexposed
Dexposed框架是阿里巴巴无线事业部近期开源的一款在Android平台下的免Root无侵入运行期AOP框架,该框架基于AOP思想,支持经典的AOP使用场景,可应用于日志记录,性能统计,安全控制,事 ...
- Android平台免Root无侵入AOP框架Dexposed使用详解
Dexposed是基于久负盛名的开源Xposed框架实现的一个Android平台上功能强大的无侵入式运行时AOP框架. Dexposed的AOP实现是完全非侵入式的,没有使用任何注解处理器,编织器或者 ...
- Android新技术学习——阿里巴巴免Root无侵入AOP框架Dexposed
阿里巴巴无线事业部近期开源的Android平台下的无侵入运行期AOP框架Dexposed,该框架基于AOP思想,支持经典的AOP使用场景.可应用于日志记录,性能统计,安全控制.事务处理.异常处理等方面 ...
- Dexposed:android免Root无侵入Aop框架
在网上看到了阿里推出的一个android开源项目,名为Dexposed, 是一个Android平台下的无侵入运行期AOP框架.旨在解决像性能监控.在线热补丁等移动开发常见难题,典型使用场景为: AOP ...
- Hook 无侵入式埋点(页面统计)
一.技术原理 Method-Swizzling 黑魔法 方法交换(不懂的可以查) 二.页面统计 某盟页面统计SDK需要开发者在APP基类里实现ViewDidAppear和viewDidDisappea ...
- 无侵入方面编程-用HttpModule+SoapExtension监视页面执行参数(二)
上一篇文章 "无侵入方面编程-用HttpModule+SoapExtension监视页面执行参数(一)"中,我们实现了监视每个页面的执行情况和调用WebService的简单信息. ...
- 单点登录CAS使用记(八):使用maven的overlay实现无侵入的改造CAS
前期在学习CAS部署的过程中,都是网上各种教程,各种方案不停的尝试. 期间各种侵入改源码,时间久了,改了哪个文件,改了哪段配置,增加了哪段代码,都有可能混淆不清了. 而且最大的问题是,万一换个人来维护 ...
- 消息点击率翻倍的背后——闲鱼无侵入可扩展IFTTT系统
一.面临问题 在闲鱼生态里,用户之间会有很多种关系.其中大部分关系是由买家触发,联系到卖家,比如买家通过搜索.收藏.聊天等动作与卖家产生联系:另外一部分是平台与用户之间的关系.对这些关系分析之后我们发 ...
随机推荐
- 【技巧】datagrid锁定列后重新加载时出现错位问题的解决
[问题描述]:有时候datagrid设置了锁定列后,在重新加载datagrid数据时,出现锁定列与非锁定列数据错位的问题,如图: [问题分析]:查看css样式我们发现,锁定的列和非锁定的列属于两个不同 ...
- ASP.NET没有魔法——开篇-用VS创建一个ASP.NET Web程序
为什么写这一系列文章? 本系列文章基于ASP.NET MVC,在ASP.NET Core已经发布2.0版本,微服务漫天的今天为什么还写ASP.NET?. 答:虽然现在已经有ASP.NET Core并且 ...
- Python自学笔记-列表生成式(来自廖雪峰的官网Python3)
感觉廖雪峰的官网http://www.liaoxuefeng.com/里面的教程不错,所以学习一下,把需要复习的摘抄一下. 以下内容主要为了自己复习用,详细内容请登录廖雪峰的官网查看. 列表生成式 列 ...
- ubuntu的应用程序哪里找
一般来说11.04以前的桌面是gnome,点左上角的那个小圆圈,会出来一个下拉菜单,里面就有应用程序. 11.10以后的桌面换成unity 在dash中寻找应用程序很不方便,知道名字的还好,不知道名字 ...
- 调用js中文乱码
JS文件是GB2312编码的,如果需要js中的中文不出现乱码,在UTF-8编码中调用语句为: <script src="myjs001.js" charset="g ...
- 使用Entify Framework 6.x的事务操作
public void TransactionsTest() { using (var context = new testContext()) { //使用EF事务 在vs2013中先升级Entit ...
- C# App 中嵌入 Chrome 浏览器
http://www.codeceo.com/article/cefsharp-charp-app-chrome.html http://developer.51cto.com/art/201304/ ...
- 备忘:有MTU值设置不当导致的部分网站无法访问问题
如题,有时候突然weibo.com,webQQ等网站网络连接超时,怎么找也没得原因,今天管理电信的光猫,发现设置的MTU的1400,突然想起之前电脑和路由器上设置的MTU是1500,感觉可能是这个问题 ...
- emacs 配置
个人的Emacs配置,环境是archlinux,参考了不少网上资料,因为太多,就不一一列举了,在这里感谢那些作者的辛苦经验劳动. (custom-set-variables ;; custom-set ...
- 理解JDK1.5的自动装箱拆箱
JDK1.5的升级引入了装箱和拆箱概念,简单说就是为了简化书写. JDK1.5之前,创建Integer对象是需要这么写的 Integer i = new Integer("3") ...