责任链模式
责任链是一种行为设计模式,可让您沿着处理程序链传递请求。收到请求后,每个处理程序决定处理请求,然后将其传递给链中的下一个处理程序。
webpack责任链模式
normalModuleFactory创建normalModule实例过程中有说到normalResolver解析资源路径的过程。normalResolver会涉及下面这些插件,每个插件都有各自的功能,实际上就是责任划分,通过一个链将各个责任进行连接。
在node_modules/enhanced-resolve/lib/ResolverFactory.js实例化一系列插件,实例化插件如下:
看到每个插件都有source和target属性,source是指定插件的监听事件名称,target就是用来确定下一步的去向事件。
通过resolver.apply(plugin)注册监听插件事件,监听事件如下图所示:
下面我们看下代码实现:
//node_modules/enhanced-resolve/lib/ParsePlugin.js
function ParsePlugin(source, target) {
this.source = source;
this.target = target;
}
module.exports = ParsePlugin;
ParsePlugin.prototype.apply = function(resolver) {
var target = this.target;
resolver.plugin(this.source, function(request, callback) {
var parsed = resolver.parse(request.request);
var obj = Object.assign({}, request, parsed);
if(request.query && !parsed.query) {
obj.query = request.query;
}
if(parsed && callback.log) {
if(parsed.module)
callback.log("Parsed request is a module");
if(parsed.directory)
callback.log("Parsed request is a directory");
}
resolver.doResolve(target, obj, null, callback);
});
};
plugins.push(new ParsePlugin("resolve", "parsed-resolve"));
plugins.push(new DescriptionFilePlugin("parsed-resolve", descriptionFiles, "described-resolve"));
doResolve(type, request, message, callback) {
if(resolver.hasPlugins(type)) {
resolver.applyPluginsAsyncSeriesBailResult1(type, request, createInnerCallback(innerCallback, {
log: callback.log,
missing: callback.missing,
stack: newStack
}, message));
}
}
new ParsePlugin("resolve", "parsed-resolve")指定source为"resolve",target为"parsed-resolve" 。即ParsePlugin监听事件为"resolve",执行完resolve相关操作后,触发执行parsed-resolve事件。parsed-resolve事件在DescriptionFilePlugin插件注册监听,DescriptionFilePlugin插件执行完parsed-resolve相关操作后,然后触发described-resolve事件。关键在于职责分离,而后存在链式调用以形成执行链。