由於 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 應用程式是否成功啟動。
如果看到亂數能正確生成,說明執行成功了。