.32-analysis of Webpack source Doresolve event Stream (4)

Source: Internet
Author: User
Tags symlink

  The flowchart is as follows:

Back to Descriptionfileplugin

The last section finally enters the relative event stream, where it is injected as follows:

// relativePlugins.push (new descriptionfileplugin ("relative", Descriptionfiles, " Described-relative "));p Lugins.push (new nextplugin (" After-relative "," described-relative "));

This feeling of déjà vu, this is not parsing Package.json plug-in, and call again.

But there is a subtle difference, the request object is as follows when the plug-in is called for the first time:

/*     {        context: {issuer: ', compiler:undefined},        path: ' D:\\workspace\\doc ',        request: './input.js ' ,        query: ',        module:false,        directory:false,        file:false    }* /

After the baptism of several plugins, it becomes the following:

/*     {        context: {issuer: ', compiler:undefined},        path: ' D:\\workspace\\doc\\input.js ',        request: Undefined,        query: ',        module:false,        directory:false,        file:false,        descriptionfilepath: ' d:\\ Workspace\\doc\\package.json ',        descriptionfiledata: {*package.json*},        descriptionfileroot: ' d:\\ Workspace\\doc ',        relativepath: './input.js ',        __innerrequest_request: './input.js ',        __innerrequest _relativepath: '. ',        __innerrequest: './input.js '    }* /

The main change is that path is changed from file directory to file path and request is set to undefined.

Since the plugin source code ran before, but there is a different point, is the path in the Foreachbail.

var descriptionfilepath = resolver.join (directory, filename);

The directory here is the above path,filename has not changed, is Package.json.

Before looking at the source code analysis, here is to get the map value of the corresponding directory, and then get the map key to filename of the path string, because the parameter changes, so here a new map to save the new directory path.

So here's the problem, then take a look at how to handle the path:

Module.exports =functionJoin (path, request) {/*Path = d:\\workspace\\doc\\input.js request = Package.json*/    if(!request)returnnormalize (path); if(Absolutewinregexp.test (Request))returnNormalize (Request.replace (/\//g, "\ \")); if(Absolutenixregexp.test (Request))returnnormalize (request); if(Path = = "/")returnNormalize (path +request); //regular check that still satisfies the absolute path    //The stitching turned into a d:\workspace\doc\input.js\package.json.    if(Absolutewinregexp.test (path))returnNormalize (Path.replace (/\//g, "\ \") + "\ \" + Request.replace (/\//g, "\ \"))); if(Absolutenixregexp.test (path))returnNormalize (path + "/" +request); returnNormalize (path + "/" +request);};

is completely an illegal path, so the following code will directly error:

if(Resolver.fileSystem.readJson) {//Illegal PathResolver.fileSystem.readJson (Descriptionfilepath,function(err, content) {if(err) {/*{Error:ENOENT:no Such file or directory, open ' D:\workspace\doc\input.js\packag                    E.json ' errno: -4058, Code: ' ENOENT ', Syscall: ' Open ', Path: ' D:\\workspace\\doc\\input.js\\package.json '}*/            //Enter this if branch            if(typeofErr.code!== "undefined")returncallback (); returnOnjson (ERR); } Onjson (NULL, content); });}

Notice that the callback is called without a reference, and the branches are different:

function(err, result) {if(ERR)returncallback (ERR); //before reading Package.json successfully entered this branch    if(Result) {returnCallbackNULL, result); }    //this time it's here .    Else{directory=cdup (directory); if(!directory) {            returncallback (); } Else {            returnFinddescriptionfile (); }    }}

This wonderful cdup function name is very spiritual, see what the Ghost.

//directory = D:\workspace\doc\input.jsfunctioncdup (directory) {if(Directory = = = "/")return NULL; //search for path characters from backward forward    vari = Directory.lastindexof ("/"), J= Directory.lastindexof ("\ \"); varp = i < 0? J:j < 0? I:i < J?j:i; if(P < 0)return NULL; //Cutting Strings    //back to D:\workspace\doc    returnDirectory.substr (0, p | | | 1);}

In fact, there is nothing, ternary super-expression with the return of the cut is to get the corresponding directory.

Get to the corresponding directory, call the Finddescriptionfile function again, that is, read the configuration file Iife. This time directory becomes a directory, and the same goes for the first time.

Described-relative = Filekindplugin

In the end, nothing is done, triggering the next event stream described-relative, which is relatively simple:

FileKindPlugin.prototype.apply =function(resolver) {vartarget = This. Target; Resolver.plugin ( This. Source,function(Request, callback) {//false        if(request.directory)returncallback (); varobj =object.assign ({}, request); Deleteobj.directory; Resolver.doresolve (target, obj,NULL, callback); });};

Because the file attributes were previously parsed in Parseplugin, the non-file directory is determined, so the doresolve is called directly for the next event stream.

To tell the truth, I am a little afraid to call callback here, because again think, this is which callback???

Raw-file = Trynextplugin

The event stream is injected as follows:

// Raw-file // default is False if (! enforceextension)    Plugins.push(new trynextplugin ("Raw-file", "no extension", "file"));p Lugins.push (New concordextensionsplugin ("Raw-file", {}, "file"), Extensions.foreach (function( Item) {    Plugins.push (new appendplugin ("Raw-file", Item, "File");});

Seemingly so many plug-ins, in fact, the first plugin directly skipped.

function (resolver) {    varthis. Target;     var  This . Message;    Resolver.plugin (thisfunction(request, callback) {        //  Gives a message directly triggering the target event stream         resolver.doresolve (target, request, message, callback);    }) ;

If you do not set the Exforceextension property to True, the Raw-file event stream is skipped and goes directly to the file event stream.

File

This place is almost at the end of the scene and the injection site is as follows:

//file//identical calls.Alias.foreach (function(item) {Plugins.push (NewAliasplugin ("File", Item, "Resolve"));}); Plugins.push (NewConcordmodulesplugin ("File", {}, "resolve")); Aliasfields.foreach (function(item) {Plugins.push (NewAliasfieldplugin ("File", Item, "Resolve"));});//default is not defined to trueif(symlinks) Plugins.push (NewSymlinkplugin ("File", "relative"));p Lugins.push (NewFileexistsplugin ("File", "Existing-file"));

The first few plug-ins are exactly the same, this time even the same parameters, so lazy to see, jump directly.

Symlinkplugin

This plugin is new and internally implemented as follows:

SymlinkPlugin.prototype.apply =function(resolver) {vartarget = This. Target; Resolver.plugin ( This. Source,function(Request, callback) {var_this = This; varFS =_this.filesystem; //Cutting Path        varPathsresult =getpaths (Request.path); varPathseqments =pathsresult.seqments; varpaths =pathsresult.paths; varContainssymlink =false; //New Method        //actually, it's just an iterative function with an index parameter.Foreachbail.withindex (Paths,function(path, IDX, callback) {//Asynchronous Read link            //the same way all the idiots failed.Fs.readlink (Path,function(err, result) {if(!err &&result) {Pathseqments[idx]=result; Containssymlink=true; //Shortcut when absolute symlink found                    if(/^(\/| [A-za-z]:($|\\))/. Test (Result))returnCallbackNULL, IDX);            } callback ();        }); }, function(err, idx) {//Direct return            if(!containssymlink)returncallback (); varResultseqments =typeofIDX = = = "Number"? Pathseqments.slice (0, idx + 1): Pathseqments.slice (); varresult = Resultseqments.reverse (). Reduce (function(A, b) {return_this.join (A, b);            }); varobj =object.assign ({}, request, {path:result}); Resolver.doresolve (target, obj,"Resolved symlink to" +result, callback);    }); });};

First look at the path cut:

Module.exports =functiongetpaths (path) {varParts = Path.split (/(. *?[ \\\/]+)/); varpaths =[path]; varSeqments = [parts[parts.length-1]]; varPart = Parts[parts.length-1]; Path= Path.substr (0, Path.length-part.length-1);    Paths.push (path); /*paths = [' d:\\workspace\\doc\\input.js ', ' input.js '] parts = [' ', ' d:\\ ', ' ', ' workspace\\ ', ', ' doc\\ ', ' input.js '] path = ' Input.js '*/     for(vari = parts.length-2; i > 2; I-= 2) { part=Parts[i]; //Cutting DirectoryPath = PATH.SUBSTR (0, path.length-part.length) | | "/";        Paths.push (path); //get the corresponding Folder/file nameSeqments.push (part.substr (0, Part.length-1)); } part= Parts[1]; Seqments.push (Part.length> 1? Part.substr (0, Part.length-1): part); /*{paths: [' d:\\workspace\\doc\\input.js ', ' d:\\workspace\\doc ', ' d:\\workspace ', ' d: '] se Qments: [' input.js ', ' Doc ', ' Workspace ']}*/    return{paths:paths, seqments:seqments};};

The folder name of the file directory is cut and the corresponding directory, and finally an object is returned.

Next call a file read method Readlink, just at first I thought with ReadFile the same as the path to read the file content, and later found that all the paths passed in all the error.

That is, one has not read, the direct callback returned.

What is this stupid method? Because no FQ, Baidu Search is garbage content, only the officer net to see the original: http://man7.org/linux/man-pages/man2/readlink.2.html

It is worth noting that there is only one sentence:readlink, readlinkat-read value of a symbolic link

Symbolic link? This is what, check for a long, the original is a symbolic link, belongs to a similar to the shortcut of something, can be understood as a file pointer.

It took me a lot of effort to realize the purpose of this API.

This assumes that I want to create a symbolic link in the D-disk, the target is the Windows folder of C, open cmd, and enter the following command:

MKLINK/D D:\symbolic C:\Windows

A hint will pop up: for the symbolic link created for * * * <<===>> * *, when you open D, you will see a folder similar to a shortcut, open to see the contents of Windows.

It looks like a shortcut, actually there is a difference, the most intuitive is the path, the symbol link opens the path is still the current folder, but the shortcut will jump to the reference place, that is:

  

Open the symbolic link, it seems as if you copied all the contents of Windows into the link, the shortcut is understood, do not show.

Back to the method, if the symbolic link is passed in, the above example returns: C:\Windows, which is the corresponding path.

The bottom line is that this kind of user to me is basically no egg.

This is the first verse.

.32-analysis of Webpack source Doresolve event Stream (4)

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.