由於 Blazor-WebAssembly 是在瀏覽器中運行的,通常不需要執行伺服器代碼,只要有個“窩”能托管並提供相關文件的下載即可。所以,當你有一個現成的 Blazor wasm 項目,沒必要用其他語言重寫,或者你不想用 ASP.NET Core 來托管(有些大材小用了),就可以試試用 node ...
由於 Blazor-WebAssembly 是在瀏覽器中運行的,通常不需要執行伺服器代碼,只要有個“窩”能托管並提供相關文件的下載即可。所以,當你有一個現成的 Blazor wasm 項目,沒必要用其他語言重寫,或者你不想用 ASP.NET Core 來托管(有些大材小用了),就可以試試用 node.js 來托管。
要實現這個不需要掌握什麼新的知識,所以咱們直接開工幹活。
首先,咱們做好 Blazor wasm 應用的開發。
dotnet new blazorwasm-empty -n Demo -o .
blazorwasm-empty 模板創建的項目只帶一些基本代碼和 Hello World,沒有演示代碼——無Counter無假天氣預報。
然後,Program.cs 文件也可以精簡一下。
var builder = WebAssemblyHostBuilder.CreateDefault(args); builder.RootComponents.Add<App>("#app"); await builder.Build().RunAsync();
#app 是CSS篩選器,即選擇 id 為 app 的元素來呈現 Razor 組件。這個相信各位都懂。
為了更好地演示,咱們把 Index 組件改一下,加一點交互功能,以便後面可以驗證 Blazor 是否正常啟動。
@page "/" <h1>Hello, world!</h1> <button @onclick="ClickMe">點這裡中大獎</button> <div>@Message</div> @code{ private string? Message{get;set;} void ClickMe() { int xx = Random.Shared.Next(100, 700); Message = $"恭喜你獲得{xx}萬假鈔!"; } }
這個不複雜,就是點擊一下按鈕,然後生成個隨機整數,並修改 Message 屬性。處理 click 事件要註意加上 @,如果是 onclick 你只能用 js 去寫,要想用 C# 來寫代碼,就得用 @onclick。
接著,試執行一下,保證沒有錯誤,能正常運行。
現在,你打開 \bin\Debug\net7.0\wwwroot 目錄,裡面你看到有個 _framework 目錄,這個目錄就是我們要的。不過,這個體積太大,不適合。咱們將項目發佈一下,這樣體積會變小很多。
我們不需要 wwwroot 目錄下的東東,把整個目錄“咔嚓”掉(這裡指的是項目中的 wwwroot 目錄,不是輸出目錄的)。為了防止重新生成時有文件錯誤(一般不會),可以把 obj 和 bin 目錄也刪除。
執行發佈命令。
dotnet publish -c PublishRelease
-c 參數也可以用 Release,差別不大。
另外新建一個目錄,路徑隨便,不要有非英文字元(防止出錯),比如這裡我命名為 Server。把剛纔發佈的整個 _framework 目錄複製到 Server 目錄中。現在你可以關閉 Blazor 項目了,沒它什麼事了。
在 Server 目錄下新建一個文件,叫 index.html。
<!DOCTYPE html> <html lang="zh-CN"> <head> <meta charset="utf-8"/> <title>高級示例</title> </head> <body> <div id="app">正在載入……</div> <script src="_framework/blazor.webassembly.js"></script> </body> </html>
這裡註意兩處:
1、要有一個 id 為 app 的元素,它用來呈現組件。
2、<script> 要引用 blazor.webassembly.js 文件。
在 Server 目錄下再新建一個文件,名為 app.js。這個用來寫伺服器主程式(js 代碼)。
const url = require("node:url"); const path = require("node:path"); const http = require("node:http"); const fs = require("node:fs"); // 主機 const host = 'localhost'; // 埠 const port = 6748; // MIME 映射 function getFileMap(fileExt) { switch(fileExt) { case ".js": case ".mjs": return "text/javascript"; case ".json": return "application/json"; case ".htm": case ".html": return "text/html"; case ".css": return "text/css"; case ".jpg": case ".jpeg": return "image/jpeg"; // 其他的自己看情況添加 default: // 其餘的如.dll、.gz等,就是二進位文件 return "application/octet-stream"; } } http.createServer((request, response)=> { // 獲取請求路徑 let reqPath = url.parse(request.url).pathname; // 去掉路徑開頭的“/” let fileName = reqPath.substring(1); // 如果空白,預設文件名 index.html if(fileName.length === 0) { fileName = "index.html"; } // 讀取文件內容 fs.readFile(fileName, (err, data)=>{ // 如果出錯 if(err) { // 直接回個404 response.writeHead(404, {"Content-Type": "text/html"}); } else { // 獲取文件擴展名,以決定MIME類型 let ext = path.extname(fileName); let mimeType = getFileMap(ext.toLowerCase()); // 發送HTTP頭 response.writeHead(200, {"Content-Type": mimeType}); // 發送正文 response.write(data); } // 這一行必須,結束響應消息 response.end(); }); }) .listen(port, host); console.log(`伺服器:${host}:${port}`);
運行它,執行:node app.js。接著在瀏覽器中輸入地址:http://localhost:6748。再驗證 Blazor 應用程式是否成功啟動。
如果看到隨機數能正確生成,說明運行成功了。