WebpackDevMiddleware
中間件主要用於開發SPA應用,啓用Webpack
,加強網頁開發體驗。好吧,你想用來幹嗎就幹嗎,此次主要是經過學習該中間件,學習如何在core中啓用Webpack
支持Enables Webpack dev middleware support. This hosts an instance of the Webpack compiler in memory
in your application so that you can always serve up-to-date Webpack-built resources without having
to run the compiler manually. Since the Webpack compiler instance is retained in memory, incremental
compilation is vastly faster that re-running the compiler from scratch.
Incoming requests that match Webpack-built files will be handled by returning the Webpack compiler
output directly, regardless of files on disk. If compilation is in progress when the request arrives,
the response will pause until updated compiler output is ready.html
Webpack
編譯器實例存在於內存,始終提供最新編譯的資源,增量編譯比從新編譯速度要快得多。任何請求Webpack
編譯後的文件,都原樣返回,若是請求到達時編譯沒完成,響應將暫停,直到編譯完成,輸出準備就緒Unlike other consumers of NodeServices, WebpackDevMiddleware dosen't share Node instances, nor does it
use your DI configuration. It's important for WebpackDevMiddleware to have its own private Node instance
because it must not restart when files change (if it did, you'd lose all the benefits of Webpack
middleware). And since this is a dev-time-only feature, it doesn't matter if the default transport isn't
as fast as some theoretical future alternative.node
var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices); var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServicesOptions);
devServerOptions
,包含設置webpack.config.js
的路徑以及整合在Stratup.cs
的設置、模塊熱加載斷點等。這些設置須要傳到Node
的aspnet-webpack
模塊,若是是自定義的模塊,那麼參數也是本身定義啦var devServerOptions = new { webpackConfigPath = Path.Combine(nodeServicesOptions.ProjectPath, options.ConfigFile ?? DefaultConfigFile), suppliedOptions = options, understandsMultiplePublicPaths = true, hotModuleReplacementEndpointUrl = hmrEndpoint };
nodeServices
,執行指定aspnet-webpack
模塊裏面的方法並獲得結果。參數分別是模塊文件路徑、要調用的方法、傳遞的參數。傳遞給js模塊的參數先序列成json字符串,模塊接收參數後再反序列化成對象var devServerInfo = nodeServices.InvokeExportAsync<WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer", JsonConvert.SerializeObject(devServerOptions, jsonSerializerSettings)).Result;
Webpack
編譯以後的輸出目錄,循環輸出目錄,添加請求代理,代理到全部輸出目錄。超時時間100s, /__webpack_hmr
無限超時foreach (var publicPath in devServerInfo.PublicPaths) { appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath + hmrEndpoint, devServerInfo.Port, Timeout.InfiniteTimeSpan); appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath, devServerInfo.Port, TimeSpan.FromSeconds(100)); } // Note that this is hardcoded to make requests to "localhost" regardless of the hostname of the // server as far as the client is concerned. This is because ConditionalProxyMiddlewareOptions is // the one making the internal HTTP requests, and it's going to be to some port on this machine // because aspnet-webpack hosts the dev server there. We can't use the hostname that the client // sees, because that could be anything (e.g., some upstream load balancer) and we might not be // able to make outbound requests to it from here. // Also note that the webpack HMR service always uses HTTP, even if your app server uses HTTPS, // because the HMR service has no need for HTTPS (the client doesn't see it directly - all traffic // to it is proxied), and the HMR service couldn't use HTTPS anyway (in general it wouldn't have // the necessary certificate). var proxyOptions = new ConditionalProxyMiddlewareOptions( "http", "localhost", proxyToPort.ToString(), requestTimeout); appBuilder.UseMiddleware<ConditionalProxyMiddleware>(publicPath, proxyOptions);
Webpack
服務,只須要建立Node
實例,調用本身寫的模塊便可。模塊根據傳過來的配置運行服務便可var nodeServicesOptions = new NodeServicesOptions(appBuilder.ApplicationServices); // node配置 var nodeServices = NodeServicesFactory.CreateNodeServices(nodeServicesOptions); // 建立node實例 // dev服務配置 var devServerOptions = new { webpackConfigPath = Path.Combine(nodeServicesOptions.ProjectPath, options.ConfigFile ?? DefaultConfigFile), suppliedOptions = options, understandsMultiplePublicPaths = true, hotModuleReplacementEndpointUrl = hmrEndpoint }; // 調用js模塊,運行dev服務,返回輸出目錄 var devServerInfo = nodeServices.InvokeExportAsync<WebpackDevServerInfo>(nodeScript.FileName, "createWebpackDevServer", JsonConvert.SerializeObject(devServerOptions, jsonSerializerSettings)).Result; // 添加輸出目錄到代理 foreach (var publicPath in devServerInfo.PublicPaths) { appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath + hmrEndpoint, devServerInfo.Port, Timeout.InfiniteTimeSpan); appBuilder.UseProxyToLocalWebpackDevMiddleware(publicPath, devServerInfo.Port, TimeSpan.FromSeconds(100)); } private static void UseProxyToLocalWebpackDevMiddleware(this IApplicationBuilder appBuilder, string publicPath, int proxyToPort, TimeSpan requestTimeout) { var proxyOptions = new ConditionalProxyMiddlewareOptions( "http", "localhost", proxyToPort.ToString(), requestTimeout); appBuilder.UseMiddleware<ConditionalProxyMiddleware>(publicPath, proxyOptions); }