五分鐘了解微軟 Blazor 技術(shù)
當(dāng)前位置:點(diǎn)晴教程→知識管理交流
→『 技術(shù)文檔交流 』
2019年4月中旬微軟推出了 Blazor,當(dāng)時(shí)的我感覺 Blazor 簡直是個(gè)劃時(shí)代的東西,竟然能讓 C# 運(yùn)行到瀏覽器中。想著以后可能沒有 C/S 架構(gòu)什么事兒了,可以卸載掉所有的 App,電腦上有個(gè)瀏覽器就夠了。近來終于有了能夠系統(tǒng)了解 Blazor 的時(shí)間,下面把我了解到信息寫下來分享給你,希望能對你有所幫助。 Blazor 可以使用強(qiáng)類型語言 C# 來替換 Javascript 實(shí)現(xiàn)邏輯,可以前后端復(fù)用邏輯,也可以使用 nuget 1 中的包。它的其中一部分是基于 WebAssembly 實(shí)現(xiàn)的,所以不依賴任何的插件,讓我們來快速了解一下 Blazor 是如何讓 C# 運(yùn)行在瀏覽器中的吧。 Blazor 涉及技術(shù)Blazor 2 是 apt.net core 生態(tài)的組成部分,所涉及到的技術(shù)也大部分和 .net 相關(guān)。 視圖層,使用 Razor 3 技術(shù)進(jìn)行前端的編排渲染。Razor是一種標(biāo)記語法,是 asp.net core 的默認(rèn)視圖語法,最顯著的特點(diǎn)是強(qiáng)類型(C#、VB等)的代碼可以和 HTML 寫在一個(gè)文件中,當(dāng)然也可以分開。在 razor 文件中,@符號后面的都是強(qiáng)類型語言,可以是一行中的一部分,也可以是一整行,還可以是一個(gè)段落。在 asp.net core 中的大致做法是把 VB、C# 等強(qiáng)類型語言嵌入到網(wǎng)頁,當(dāng)網(wǎng)頁被請求的時(shí)候,在服務(wù)器端執(zhí)行嵌入的代碼,動態(tài)生成頁面。 以 Blazor WebAssembly 開發(fā)方式運(yùn)行時(shí),依賴 WebAssembly 4 技術(shù),可以做成靜態(tài)頁面不依賴任何后端服務(wù)器。 以 Blazor Server 方式開發(fā)運(yùn)行時(shí),依賴 SignalR 5 技術(shù),并且需要后端服務(wù)器端配合。 Blazor 簡介Blazor 是一個(gè)使用 .NET 生成的交互式客戶端 Web UI 的框架。和前端同學(xué)所熟知的 Vue、React、Angular 有巨大差異。 其最大的特色是使用 C# 代碼(理論上可以是 .NET 生態(tài)的任何語言)代替 Javascript 來實(shí)現(xiàn)邏輯。 有兩種不同開發(fā)模式 Blazor WebAssembly, C# 代碼運(yùn)行在瀏覽器中。 Blazor WebAssembly讓我們先簡單了解一下 WebAssembly (Wasm)4。 WebAssembly 是一種基于堆棧虛擬機(jī)的二進(jìn)制指令格式。 那么現(xiàn)在讓我們來思考一個(gè)問題,如何讓 C# 代碼,在瀏覽器中運(yùn)行? 首先簡單回憶一下 C# 代碼是如何運(yùn)行起來的。如下圖所示,我們首先要把 C# 源碼進(jìn)行編譯成 dll 文件,然后由 .net runtime 進(jìn)行加載執(zhí)行。 那如何讓 C# 在瀏覽器中運(yùn)行起來呢?看起來只缺少一個(gè)在瀏覽器中運(yùn)行的 .net runtime。所以要用 Javascript 來寫一個(gè) .net runtime 嗎?不要著急,dotnet 社區(qū)有更好的方案。 在 dotnet/runtime 6 源碼的 Directory.Build.props 7 文件中,我們可以看到,是有以 wasm 為編譯目標(biāo)的,也就是基于 WebAssembly 實(shí)現(xiàn)的 .net runtime 。現(xiàn)在我們已經(jīng)知道 C# 代碼可以運(yùn)行在瀏覽器中了, Blazor 的生存土壤也就有了。(當(dāng)然,事實(shí)情況是 mono 社區(qū)最先實(shí)現(xiàn) WebAssembly 版本的 .net runtime。后來才合并到 dotnet core runtime 中) 接下來看一下如何創(chuàng)建 Blazor 工程。有兩種方式,1、使用命令行,2、使用IDE,如 Visual Studio 。 命令行工具,僅供不想安裝 Visual Studio 這類巨型工具,還想嘗鮮的同學(xué)使用??纱钆淙魏尉庉嬈鳎热?Visual Studio Code。以下是具體步驟: 首先,需要下載 dotnet core 8。這里順便給出 dotnet core 刪除工具 dotnet-core-uninstall 9 。 終于到了能上代碼的時(shí)間了! 先來看兩個(gè)關(guān)鍵文件,C# 的入口文件 Program.cs 和 HTML 的入口文件 index.html 。 // Program.cs 文件 using Microsoft.AspNetCore.Components.WebAssembly.Hosting; using Microsoft.Extensions.DependencyInjection; using System;using System.Net.Http; using System.Threading.Tasks; namespace BlazorWebAssembly{ public class Program { public static async Task Main(string[] args) { var builder = WebAssemblyHostBuilder.createDefault(args); builder.RootComponents.Add<App>("#app"); // 上一行我們可以理解為,在 ID 是 app 的元素中渲染展示 Blazor WebAssembly,所以讓網(wǎng)頁的某一部分使用 Blazor 技術(shù)渲染也是可行的。 builder.Services.AddScoped(sp => new HttpClient { BaseAddress = new Uri(builder.HostEnvironment.BaseAddress) }); await builder.Build().RunAsync(); } } } <!-- index.html 文件 --> <!DOCTYPE html> <html> <head> <meta charset="utf-8" /> <meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no" /> <title>BlazorWebAssembly</title> <base href="/" /> <link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" /> <link href="css/app.css" rel="stylesheet" /> <link href="BlazorWebAssembly.styles.css" rel="stylesheet" /> </head> <body> <div id="app">Loading...</div> <div id="blazor-error-ui"> An unhandled error has occurred. <a href="" class="reload">Reload</a> <a class="dismiss">X</a> </div> <script src="_framework/blazor.webassembly.js"></script> <!-- blazor.webassembly.js 文件的作用有兩個(gè)。 1、下載 .net runtime, 依賴的類庫以及項(xiàng)目編譯后的文件。 2、從 blazor.boot.json 中找到 C# 程序入口,并初始化運(yùn)行。 --> </body> </html> 在編譯之后的文件中,我們可以看到一些后綴名是 br 的文件,是因?yàn)?Blazor 默認(rèn)使用了壓縮率更高的 brotli 10 進(jìn)行壓縮,我覺得在這里應(yīng)該推薦一下,brotli 比 gzip 更能節(jié)省空間。 Blazor WebAssembly 方式開發(fā)的簡單架構(gòu),如上圖所示,.net 代碼的執(zhí)行和 DOM 元素的渲染重繪都是在瀏覽器中進(jìn)行的。 缺點(diǎn):首次打開網(wǎng)站時(shí)需要加載大量依賴文件( .net runtime 以及依賴的各種類庫);需要瀏覽器支持 WebAssembly 。在 caniuse 中可以查看到各瀏覽器對 WebAssembly 的支持情況 11 。 C# 和 Javascript 的交互操作有兩種不同的交互方式,1、從 C# 調(diào)用 Javascript 的代碼 12,2、從 Javascript 調(diào)用 C# 的代碼 13。 首先,從 C# 調(diào)用 Javascript 的代碼 先寫一個(gè) Javascript 的全局函數(shù),準(zhǔn)備給 C# 使用。 function buildObjctString(name, age) { const obj = { name, age } return JSON.stringify(obj) } 在 C# 中就可以這么調(diào)用 @inject IJSRuntime JS private async Task CSharpCallJS() { var methodName = "buildObjctString"; var name = "zpfe group"; var age = 18; var data = await JS.InvokeAsync<string>(methodName, name, age); } 然后,從 Javascript 調(diào)用 C# 的代碼 // 這里的 C# 代碼也是拿全局函數(shù)來示例,在函數(shù)頭上加了注解。[JSInvokable] public static Task<string> GetTime(string param) { return Task.fromResult($"{param},后面的來自C# {DateTime.Now.ToString("yyyy-MM-dd HH:mm:ss")}"); } 在 Javascript 中的調(diào)用方式是 // 如果 C# 函數(shù)有參數(shù),不傳遞會報(bào)錯(cuò) const result = await DotNet.invokeMethodAsync("BlazorWebAssembly", "GetTime", "這個(gè)是 js 傳入的參數(shù)"); alert(result) 這里只是最簡單的例子,更詳盡的還請從參考鏈接 1213中查看 。 調(diào)試使用 Visual Studio 調(diào)試將會很容易,和普通的 C# 調(diào)試方式一樣,只在需要調(diào)試的代碼最前面用鼠標(biāo)點(diǎn)出調(diào)試的斷點(diǎn),按下 F5 就可以調(diào)試了。Javascript 代碼也可以使用相同的方式進(jìn)行調(diào)試。 Blazor Server個(gè)人認(rèn)為 Blazor Server 是為了彌補(bǔ) Blazor WebAssembly 的不足而創(chuàng)造出來的。Blazor Server 開發(fā)方式將會強(qiáng)依賴 SignalR 5 。這里先簡單介紹一下 SignalR ,它也源自 ASPNET Core 社區(qū),是基于 RPC 協(xié)議的一種實(shí)現(xiàn)。簡單來說,就是可以在瀏覽器中使用 Javascript 代碼通過 SignalR 來調(diào)用服務(wù)器上開發(fā)的函數(shù),也可以在服務(wù)器上使用 SignalR 來調(diào)用瀏覽器中的 Javascript 函數(shù)。這種方式能夠避免網(wǎng)站首次打開時(shí)需要加載大量依賴文件的問題,也能夠彌補(bǔ)瀏覽器對WebAssembly的支持問題,甚至能夠在 IE 中運(yùn)行。但是這種方式開發(fā)的網(wǎng)站 UI 更新、事件處理等都需要通過 SignalR 調(diào)用服務(wù)器進(jìn)行處理,需要和服務(wù)器頻繁交互數(shù)據(jù),對服務(wù)器算力要求頗高。以我的理解這種方式只適合用戶量不大的網(wǎng)站。 使用命令創(chuàng)建的方式是 使用 Visual Studio 創(chuàng)建就不講了。 以 Blazor Server 開發(fā)方式的簡單架構(gòu),如上圖所示。 所有使用 C# 處理的 UI 更新,都需要在服務(wù)器端進(jìn)行,通過 SignalR 技術(shù)將更新結(jié)果發(fā)送到瀏覽器中進(jìn)行更新。用 C# 編寫的事件處理函數(shù)以及 C# 和 Javascript 之間的互操作 ,也需要相同的邏輯。 Other我覺得比較有意思的兩個(gè)功能 1、Blazor Destkop (.net core 6 將會支持),使用 Blazor WebAssembly 的方式開發(fā)桌面應(yīng)用。2、Browser extension (開源社區(qū)的創(chuàng)意 14),使用 Blazor WebAssembly 的方式開發(fā)瀏覽器插件。 更多更有意思的項(xiàng)目請關(guān)注 awesome blazor 15。 文中涉及到的代碼已經(jīng)共享到了 GitHub 16。 該文章在 2023/6/2 17:48:13 編輯過 |
關(guān)鍵字查詢
相關(guān)文章
正在查詢... |