Detailed explanation WebPack-Dev-Middleware Source Code Interpretation

WebPack’s usage is currently one of the necessary skills necessary for front-end development engineers. If you want to start a development service in your local environment, you just need to increase the configuration of DEVSERVER in the WebPack configuration. The essence of DEVSERVER configuration is the function provided by WebPack-Dev-Server, and WebPack-Dev-MiddleWare is the bottom-up dependence of this package.

As of this article, the latest version of WebPack-dev-middleWare is


, the source code of this article comes from this release. This article will explain the core module of WebPack-dev-middleware, I believe that everyone will read this article, then read the source code, it will be easily understood.

What is webpack-dev-middleware?

To answer this question, let’s take a look at how to use this package:

Const WDM = Require (‘WebPack- dev-middleware ‘); const express = require (‘ express’); const webpack = require ( ‘webpack’); const webpackConf = require ( ‘./ webapck.conf.js’); const compiler = webpack (webpackConf); Const App = Express (); app.use (wdm)); app.listen (8080);

  By starting an Express service,The result of the WDM (Compiler) is registered as an intermediate function of the Express service via the app.use method. From here, we are not difficult to see the result of the WDM (Compiler) is returned to an Express middleware. As a container, store the webpack-compiled file into memory, and then return the corresponding resource output in the memory when the user accesses the Express service.  
Why use WebPack-dev-middleWare

Classmates who are familiar with WebPack know that WebPack can start through Watch Mode, why do we not use it directly? What is the change in resource changes? The answer is that the WebPack’s Watch Mode can listen to the change of the file and the package is automatically packaged, but each package will be stored in the local hard disk, and the IO operation is very resource time and cannot meet the local development and commissioning requirements.

WebPack-dev-middleWare has the following characteristics:

Starting WebPack with Watch Mode, the listening resources will automatically compile, produce the latest bundle

During the compilation, the old version of Bundle is stopped and the request is delayed to the latest compile results

WebPack compiled resources will be stored in memory, and when the user requests resources, directly Find the corresponding resource in memory, reduce the IO operation time consumption in the hard disk
  • will focus on these three characteristics and main proximity logic.
  • Source code interpretation
  • Let’s take a look at the source code directory of WebPack-dev-middleware:

… ├─LIb│ ├─ devmiddlewareerror.js│ ├─- index.js│ ├── middleWare.js│ └── Utils│ ├─ getFilenameFromurl.js│ ├── HandleRangeHeaders.js│ ├─ ─ ─ ─ ─ ─ ─ j. │ ─ Ready.js│ ├── Reporter.js│ ├── Setuphooks.js│ ├── Setuplogger.js│ ├── SetupoutputFileSystem.js│ ├─- setuprebuild.js│ └─– setupwritetodisk.js └─- Package.json …

Where the source code is source code, nearly 10 more files to be interpreted. However, the original Utils tool collection directory, its core source code file is actually only two index.js, MiddleWare.js
Let’s analyze the source code of core file index.js, MiddleWare.js Source code implementation
   Entrance file index.js 
From above we have learned that WDM (Compiler) returns an Express middleware, the entrance file index.js is a middle The container package function. It receives two parameters, one for the company’s Compiler, the other for the configuration object, after a series of processing, finally returns a middleware function. Below I will explain the core code in Index.js:

… setuphook (context); … // starT WatchingContext.watching = (Options.watchOptions, (ERR) => {if (err) {context.log.error (Err.Stack || Err); if (err.details) {Context.log.Error (Err.Details);}}}); … setupoutputFileSystem (Compiler, Context);

Index.js is the most important thing is the execution of the above three parts. The two points mentioned above were completed:

starts WebPack

in the way, outputs the contents of WebPack, output to memory

  This function is to register the corresponding processing method on the four compilation life cycles of Compiler's Invalid, Run, Done, Watchrun, registration corresponding processing method  
Context.Compiler.hooks.invalid.tap (‘WebPackDevmiddleWare’, Invalid); Context.Compiler.hook.Run.tap (‘WebPackDevmiddleWare’, Invalid); Context.Compiler. Hooks.done.TAP (‘WebPackDevmiddleWare’, Done); Context.Compiler.hook.watchrun.tap (‘WebPackDevmiddleWare “, (COMP, Callback => {Invalid (Callback);};

    Registered Done method on the DONE life cycle, the method is mainly information compiled by Report and Execute the Context.Callbacks callback function
  • Register the Invalid method in the life cycle of Invalid, Run, Watchrun, which is mainly the status information compiled by Report

This section is to call the COMPILER’s Watch method, and the WebPack will listen to the file change. Once the file changes are detected, the compilation will be re-executed.


The action is to replace the file system object for Compiler using the MEMORY-FS object, allowing WebPack’s compiled files to memory.
  FILESYSTEM = New MemoryFileSystem (); // eslint-disable-next-line no-param-correctionCompiler.outputFilesystem = filesystem;  
    With the execution of the above three parts, we launched WebPack in Watch Mode. Once the monitoring file changes, we will re-compile the package, and we also change the file storage method to memory storage. Improve the storage read efficiency of the file. Finally, we only need to return the middleware of Express, and the middleware is called Middlewa.The RE (Context) function is obtained. Below, let’s take a look at how MiddleWare is implemented.

This file returns a package function of an Express middleware function, and its core processing logic is mainly for the Request request, according to various Conditional judgment, eventually returned to the corresponding file content:

function gonext () {if (! Context.Options.serversiderender) {return next ();} return new promise (resolve) => {ready (context, () => {// eslint-disable-next-line no-param-reason = context.webpackstats = context.webpackstats; // eslint-disable-next-line no- PARAM-RESIGN RES.LOCALS.FS = context.fs; resolve (NEXT ());}, req);};}

First, MiddleWare is defined. A gonext () method, this method determines if it is a server rendering. If so, call the ready () method (this method is the ready.js file, the effect is based on the context.state status to determine the callback or callback in the callabacks queue). If not, the next () method is called directly to the next Express middleware.

constlyptedMethods = context.Options.methods || [‘get’, ‘head’]; if (acceptedMethods.indexof (Req.Method) === -1) {return gonext ();}
  Next, it is determined that the type of request for the HTTP protocol is determined if the request is not included in the configuration (the default GET, HEAD request), then directly calls the gonext () method processing request: 
Let filename = getFileNameFromurl (Context.Options.publicPath, Context.Compiler, Req.ur); if (filename === false) {returnomext ();}

Then, according to the request’s REQ.URL address, find the corresponding file in the compiler memory file system. If the lookup is not found, the gonext () method processing request is called directly. :

Return New Promise ((resolve) => {// eslint-disable-next-line consistent-returnction processRequest () {…} … Ready (Context, ProcessRequest, Req);

  Finally, the middleware returns a promise instance, and in the instance, first define a processRequest method, this method doUse the FileName path found in the above to obtain the corresponding file content, and construct the Response object returns, then call the Ready (Context, ProcessRequest, REQ) function, and perform the ProcessRequest method. Here we focus on the contents of the Ready method:  
i (context.WebPackStats);} (`Wait Until Bundle finished: $ {req.URL ||} `); context.callbacks.push (fn);
Very simple method, judgment context.state The state will directly perform the callback function fn, or add a callback function Fn in Context.Callbacks. This also explains another feature mentioned above “During the compilation, stop the old version of Bundle and the request is delayed to the latest compilation result.” If WebPack is still in compilation, context.State will be set to false, so when the user initiates a request, the corresponding file content will not be returned directly, but will add the callback function processRequest to Context.callbacks, and in the above We said that this function will be executed after registering the callback function done, after the compilation is completed, and cycled CONTEXT.CALLBACKS.

 The source of the source is a very boring process, but its income is also huge. The source code interpretation of the above is the main analysis of webpack-dev-middleware how it implements it.Some features, how to deal with the main function points of the user's request, not including other branch logic processing, fault tolerance. It is also necessary to read the detailed source code on this article, and I hope that this article can help your reading process.   
This article on the WebPack-dev-middleWare source code is introduced to this, more related WebPack-dev-middleWare source code interpretation, please search for Tumi clouds or continue to browse The following related articles I hope everyone will support Tumi clouds in the future!
© Copyright Notice
Just support it if you like
comment Grab the couch

Please log in to comment