zoukankan      html  css  js  c++  java
  • .33-浅析webpack源码之doResolve事件流(5)

    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:workspacedocinput.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:workspacedocinput.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均视为一个事件流,特殊分支给给出说明。

  • 相关阅读:
    WampServer软件
    ASP.NET Core中返回 json 数据首字母大小写问题
    区块链的入门与应用(1)
    阿里云oss 的坑==》 路径有区分大小写
    uni-app 学习笔记 小于号问题
    uni-app 学习笔记-引用外部js并调用
    net core 简单读取json配置文件
    net core 3 使用 autofac
    js 获取对应的url参数
    postman 跟restsharp 模拟请求http
  • 原文地址:https://www.cnblogs.com/QH-Jimmy/p/8397760.html
Copyright © 2011-2022 走看看