標籤:core tor art cert balance 編譯 字串 read soft
asp.net core mvc 中介軟體之WebpackDevMiddleware
WebpackDevMiddleware
中介軟體主要用於開發SPA應用,啟用Webpack
,增強網頁開發體驗。好吧,你想用來幹嘛就幹嘛,這次主要是通過學習該中介軟體,學習如何在core中啟用Webpack
支援
- 通過上上篇asp.net core mvc 管道之中介軟體,大致可以瞭解中介軟體是什麼東西,現在就以中介軟體為單位,一個一個點學習各種中介軟體,瞭解並掌握,最後學會自己寫中介軟體
- 該中介軟體源碼
說明WebpackDevMiddleware
-
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.
- 大概意思是
Webpack
編譯器執行個體存在於記憶體,始終提供最新編譯的資源,增量編譯比重新編譯速度要快得多。任何請求Webpack
編譯後的檔案,都原樣返回,如果請求到達時編譯沒完成,響應將暫停,直到編譯完成,輸出準備就緒
NodeServices
-
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.
- WebpackDevMiddleware不共用Node執行個體,也不共用使用的DI配置。因為檔案改變時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);}
樣本
asp.net core mvc 中介軟體之WebpackDevMiddleware