file => FileExistsPlugin

  这个事件流快接近尾声了,接下来是FileExistsPlugin,很奇怪的是在最后才来检验路径文件是否存在。

  源码如下:

FileExistsPlugin.prototype.apply = function(resolver) {
var target = this.target;
resolver.plugin(this.source, function(request, callback) {
var fs = this.fileSystem;
// file => d:\workspace\doc\input.js
var file = request.path;
fs.stat(file, function(err, stat) {
// stat => 文件信息
if (err || !stat) {
if (callback.missing) callback.missing.push(file);
if (callback.log) callback.log(file + " doesn't exist");
return callback();
}
// 是否为文件
if (!stat.isFile()) {
if (callback.missing) callback.missing.push(file);
if (callback.log) callback.log(file + " is not a file");
return callback();
}
// 只做信息提示 不对结果做处理
this.doResolve(target, request, "existing file: " + file, callback, true);
}.bind(this));
});
};

  这里只是简单的对路径文件进行状态获取,然后判断是否存在?是否是文件?最后调用一个有message的doResolve方法进入到下一个事件流。

existing-file => NextPlugin

  这个插件没什么卵用,之前提到过,会直接跳到下一个事件流。

resolved => ResultPlugin

  这是最后一个插件,在注入的时候只有一个参数,代表事件流的结尾。

ResultPlugin.prototype.apply = function(resolver) {
resolver.plugin(this.source, function(request, callback) {
var obj = Object.assign({}, request);
// 调用resolver的事件流
resolver.applyPluginsAsyncSeries1("result", obj, function(err) {
if (err) return callback(err);
callback(null, obj);
});
});
};

  这里直接调用了resolver的result事件流,并没有通过doResolve方法。

  经过测试,这个事件流并不存在,所以会直接调用无参callback,这个callback是什么呢???

  找了很久很久,终于找到了,回到最开始的resolve方法中,有个函数:

function onResolve(err, result) {
// 无错误情况下调用这个
if (!err && result) {
return callback(null, result.path === false ? false : result.path + (result.query || ""), result);
} localMissing = [];
log = [];
// 错误处理
return resolver.doResolve("resolve", obj, message, createInnerCallback(onError, {
log: writeLog,
missing: localMissing,
stack: callback.stack
}));
}

  这里因为成功执行完事件流,第一个参数为null,所以会进入第一个if分支,最后返回的是path与result。

  这个callback就简单了,回到了resolve方法的调用地点:

asyncLib.parallel([
callback => this.resolveRequestArray(contextInfo, context, elements, this.resolvers.loader, callback),
callback => {
if (resource === "" || resource[0] === "?")
return callback(null, {
resource
});
this.resolvers.normal.resolve(contextInfo, context, resource, (err, resource, resourceResolveData) => {
// 从这里开始
if (err) return callback(err);
/*
resource => d:\workspace\doc\input.js
resourceResolveData =>
{
context: { issuer: '', compiler: undefined },
path: 'd:\\workspace\\doc\\input.js',
request: undefined,
query: '',
module: false,
file: false,
descriptionFilePath: 'd:\\workspace\\doc\\package.json',
descriptionFileData:{ *配置文件内容* },
descriptionFileRoot: 'd:\\workspace\\doc',
relativePath: './input.js',
__innerRequest_request: undefined,
__innerRequest_relativePath: './input.js',
__innerRequest: './input.js'
}
*/
callback(null, {
resourceResolveData,
resource
});
});
}
], (err, results) => { /**/ })

总结

  这里对之前的resolve方法所做的流程做一个总结,画一个图。

  剔除一些诸如NextPlugin这种垃圾插件以及重复加载的插件,插件加载按顺序,所有的type的before、after均视为一个事件流,特殊分支给给出说明。

.33-浅析webpack源码之doResolve事件流(5)的更多相关文章

  1. .30-浅析webpack源码之doResolve事件流(1)

    这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...

  2. .30-浅析webpack源码之doResolve事件流(2)

    这里所有的插件都对应着一个小功能,画个图整理下目前流程: 上节是从ParsePlugin中出来,对'./input.js'入口文件的路径做了处理,返回如下: ParsePlugin.prototype ...

  3. .29-浅析webpack源码之doResolve事件流(1)

    在上一节中,最后返回了一个resolver,本质上就是一个Resolver对象: resolver = new Resolver(fileSystem); 这个对象的构造函数非常简单,只是简单的继承了 ...

  4. .31-浅析webpack源码之doResolve事件流(2)

    放个流程图: 这里也放一下request对象内容,这节完事后如下(把vue-cli的package.json也复制过来了): /* { context: { issuer: '', compiler: ...

  5. .32-浅析webpack源码之doResolve事件流(4)

    流程图如下: 重回DescriptionFilePlugin 上一节最后进入relative事件流,注入地点如下: // relative plugins.push(new DescriptionFi ...

  6. .34-浅析webpack源码之事件流make(3)

    新年好呀~过个年光打游戏,function都写不顺溜了. 上一节的代码到这里了: // NormalModuleFactory的resolver事件流 this.plugin("resolv ...

  7. 浅析libuv源码-node事件轮询解析(3)

    好像博客有观众,那每一篇都画个图吧! 本节简图如下. 上一篇其实啥也没讲,不过node本身就是这么复杂,走流程就要走全套.就像曾经看webpack源码,读了300行代码最后就为了取package.js ...

  8. .27-浅析webpack源码之事件流make(2)

    上一节跑到了NormalModuleFactory模块,调用了原型方法create后,依次触发了before-rsolve.factory.resolver事件流,这节从resolver事件流开始讲. ...

  9. .17-浅析webpack源码之compile流程-入口函数run

    本节流程如图: 现在正式进入打包流程,起步方法为run: Compiler.prototype.run = (callback) => { const startTime = Date.now( ...

随机推荐

  1. [Phalcon-framework]2016-04-13_安装使用 Phalcon 框架

    1. 获取你的 PHP Version,操作系统是 x86 还是 64bit的,以及 Compiler 是什么 VC, 你可以直接同时 phpinfo() 函数获取到,如下截图: 2.  下载对应的 ...

  2. PowerDesigner常用功能介绍

    PowerDesigner常用功能:1:把SQL脚步导入PowerDesigner打开powerdesigner,选择File --> Reverse Engineer --> Datab ...

  3. 个人作业四--Alpha阶段个人总结

    一.个人总结 在alpha 结束之后, 每位同学写一篇个人博客, 总结自己的alpha 过程: 请用自我评价表:http://www.cnblogs.com/xinz/p/3852177.html 有 ...

  4. .NET Core中使用EF Core连接MySQL

    最近一直在捣鼓.NET Core方面的东西,顺便写下点东西记录下 1.打开vs2017,新建一个项目 2.vs会自动生成一个项目,然后打开NuGet搜索MySql.Data.EntityFramewo ...

  5. Python之分支结构

    if lengeh >= 100: #每个条件后面要使用冒号 if lengeh>=10000: ") elif lengeh>=1000: ') else: pass e ...

  6. 关于axios及其在vue中的配置

    什么是axios?官方解释:axios 是一个基于 promise 的 HTTP 库,可以用在浏览器和 node.js 中. 具有以下特点: 从浏览器中创建 XMLHttpRequests 从 nod ...

  7. Vue.js之下拉列表及选中触发事件

    老早就听说了Vue.js是多么的简单.易学.好用等等,然而我只是粗略的看了下文档,简单的敲了几个例子,仅此而已. 最近由于项目的需要,系统的看了下文档,也学到了一些东西. 废话不多说,这里要说的是下拉 ...

  8. iOS---代理、协议、通知 详解

    一.代理 1.代理的介绍 代理是一种通用的设计模式 代理使用方式:A 让 B 做件事,空口无凭,签个协议. 所以代理有三部分组成: 委托方: 定义协议 协议   : 用来规定代理方可以做什么,必须做什 ...

  9. tensorflow学习总结之reduce_sum函数

    tensorflow里面集成了许多基于统计的数学函数,类似于reduce_sum,reduce_mean,reduce_min,reduce_max,等,根据字面意思分别是求和,求平均,求最大,求最小 ...

  10. Git基本命令学习

    Git是一个由林纳斯·托瓦兹为了更好地管理linux内核开发而创立的分布式版本控制/软件配置管理软件,如今已经超越CVS.SVN称为主流的版本控制器.许多著名的开源项目都用Git管理,比较火的托管服务 ...