Blazor - это новый фреймворк, который позволяет создавать интерактивные веб-интерфейсы с использованием C # вместо JavaScript. Это отличный вариант для разработчиков .NET, которые хотят применить свои навыки в веб-разработке, не изучая совершенно новый язык. Но что, если вы разработчик JavaScript? Есть ли у Blazor что-нибудь предложить вам, или вам лучше остановиться на Vue, React или Angular?

Мы собираемся взглянуть на Blazor с точки зрения разработчика JavaScript. Мы исследуем структуру приложения Blazor, как оно работает, возможные варианты использования и как оно соотносится с JavaScript. Наконец, мы рассмотрим простое приложение, демонстрирующее Blazor в действии.

Что такое Blazor?

Мы не можем представить Blazor, не упомянув WebAssembly.

WebAssembly - или просто «wasm» - это открытая спецификация для веб-браузеров, анонсированная в 2015 году. Она описывается как компактный формат двоичного кода, разработанный как переносимая цель для компиляции в Интернете для клиентских и серверных приложений.

После этого объявления некоторые организации запустили проекты, позволяющие запускать языки программирования высокого уровня поверх WebAssembly. Microsoft взяла на себя инициативу, запустив свой проект Blazor, и теперь вы можете использовать Blazor для запуска C # в клиентских веб-приложениях. Благодаря открытой стандартной спецификации WebAssembly код .NET может работать в браузерах без подключаемых модулей.

Blazor - это интерфейсная среда разработки для SPA (одностраничных приложений), использующая C # в качестве полного стека. Вы можете писать код клиентского приложения с помощью C #, не полагаясь на JavaScript, как обычно с jQuery, React или Angular, потому что Blazor заменит все это. Совместно с ASP. NET Core, это означает, что теперь у вас может быть .NET end-to-end.

Компоненты Blazor записываются как классы C #, а затем встраиваются в сборки .NET. Они отвечают за операции ввода и вывода - обработку пользовательских событий и рендеринг пользовательского интерфейса. Компоненты также могут работать как контейнеры, которые повторно используются, совместно используются и распределяются между несколькими приложениями и платформами в виде библиотек классов Razor или пакетов NuGet. (Razor - это синтаксис веб-разработки, который позволяет программировать динамические веб-страницы с помощью HTML и C #.)

HTML-страницы, содержащие функции JavaScript для выполнения клиентской логики, знакомы интерфейсным разработчикам. Точно так же типичный компонент Blazor объявляется как файл разметки (расширение .razor), содержащий элементы HTML, а также код C #, отвечающий за визуализацию HTML и обработку событий.

Как Blazor сравнивается с JavaScript

Blazor обеспечивает инкапсуляцию кода через свои повторно используемые компоненты веб-интерфейса. Blazor также позволяет как клиентскому, так и серверному коду C # совместно использовать код и библиотеки.

Компонентизация - это концепция, знакомая людям, работающим с React, Angular и другими фреймворками JavaScript. Компоненты - это строительные блоки приложения, и в типичном приложении их будет много. Они необязательно принимают входные данные и возвращают элементы HTML, описывающие, как должен выглядеть раздел пользовательского интерфейса.

ASP. NET Core предоставляет эту идею в виде компонентов Razor. Компоненты Razor также являются компонентной моделью Blazor. Следовательно, компоненты Blazor и компоненты Razor взаимозаменяемы.

Каждый компонент Blazor представляет собой отдельный элемент в структуре пользовательского интерфейса приложения, например корзину покупок, новостную ленту или раздел комментариев.

Как Blazor сравнивается с ASP. Приложения .NET Core MVC

Обычный ASP. NET Core MVC отображает пользовательский интерфейс в виде блоков строк. Blazor, с другой стороны, строит дерево рендеринга, которое является не строкой, а представлением DOM (объектной модели документа), хранящейся в памяти. Blazor сохраняет это представление. Любые изменения, внесенные в него (например, при обновлении значения привязки), вызовут обновление пользовательского интерфейса для затронутых элементов DOM. Это большое отличие от ASP. NET Core HTML Helpers и представления Razor, которые отображают строки.

Так почему же Blazor работает с деревьями рендеринга вместо строк? Помните, что код Blazor в частности (и код wasm в целом) не может напрямую обращаться к элементам DOM. Это ограничение отличается от ASP. NET Core HTML Helpers и Razor Views, которые зависят от JavaScript для получения полного доступа к элементам пользовательского интерфейса. Таким образом, Blazor прибегает к визуализации деревьев, чтобы вернуться к своему представлению DOM, искать определенные части DOM, затем обновлять их, редактировать, удалять и т. Д. Платформа Blazor будет прослушивать изменения, внесенные в модель данных, и манипулировать деревом рендеринга, чтобы применить изменения. Этот механизм позволяет C # работать на стороне клиента.

Но почему вы должны выбрать разработку с использованием Blazor, а не чистого клиентского JavaScript или ASP. NET Core MVC / Razor? Давайте обсудим некоторые различия между ними, чтобы вы могли принять обоснованное решение, прежде чем прилагать какие-либо усилия к разработке нового проекта Blazor.

Плюсы клиентского Blazor

  1. Blazor позволяет запускать код .NET прямо в браузере. Он нарушает монополию JavaScript / Node.JS на профессионалов полного стека, потому что с ним разработчикам .NET не нужно программировать полиглоты. Они могут создавать законченные решения без написания кода JavaScript.
  2. Код Blazor компилируется в .NET Intermediate Language, что означает, что он потенциально может быть быстрее, чем эквивалентный код JavaScript. Эта модель компиляции может иметь значение для браузерных приложений, ориентированных на производительность, таких как игры.
  3. Вы можете поделиться кодом проверки между клиентскими и серверными приложениями. Допустим, у вас есть логика проверки формы, которая будет применяться как в браузере, так и в серверной части. С помощью Blazor вы можете создать библиотеку классов в .NET Standard 2.0 и поделиться ею между клиентскими и серверными приложениями. Любое изменение логики проверки автоматически применяется к обеим платформам.

Минусы клиентского Blazor

  1. Чтобы запустить Blazor в браузере, вы должны не только загрузить в браузер библиотеки .wasm и .NET приложения, но также и Mono.wasm, среду выполнения .NET, поверх которой работает Blazor. Mono.wasm можно кэшировать, но загрузка этих ресурсов в первый раз приведет к задержке запуска приложения. Так что даже крошечное приложение Blazor потребует загрузки мегабайтов кода. В JavaScript таких накладных расходов нет.
  2. Blazor не может напрямую управлять элементами DOM. Иногда ваше клиентское приложение должно иметь большой контроль над элементами HTML. Поскольку Blazor не предоставляет эту возможность сам по себе, вы должны использовать JavaScript Interop, чтобы заполнить этот пробел.
  3. В целом Blazor на стороне клиента в настоящее время работает медленнее, чем JavaScript, во время большинства аспектов запуска приложения (не только при запуске). Microsoft определенно работает над повышением производительности, и, учитывая их послужной список по настройке производительности на других платформах, со временем эта проблема должна быть решена.

Также стоит отметить, что в настоящее время возможности отладки ограничены. Blazor еще предстоит улучшить в этой области. Вы можете использовать вкладку отладки в Chrome для отладки и проверки значений типов int, bool и string, и не более того. Если вы хотите отлаживать более эффективно, вам следует включить ведение журнала консоли во все клиентское приложение.

Два лица Blazor

Обычно мы говорим о Blazor как о коде C #, работающем поверх WebAssembly в браузере, но это только половина дела. Чтобы увидеть полную картину, вы должны понимать, что эти приложения могут быть созданы для работы как на стороне клиента Blazor, так и на стороне сервера Blazor. Когда вы создаете приложение, вы сначала выбираете одну из моделей хостинга. Эта конфигурация радикально изменит способ работы приложения «под капотом», даже если приложение останется прежним.

Клиентская часть Blazor - более знакомая JavaScript-разработчикам модель хостинга. Разработчики развертывают ресурсы приложения на веб-сервере, который, в свою очередь, может обслуживать клиентские браузеры с набором статических файлов. После того, как браузер загрузит эти файлы, приложение может работать поверх WebAssembly. Это поведение не сильно отличается от клиентских приложений JavaScript, за исключением того факта, что приложение работает на WebAssembly вместо JavaScript.

Теперь поговорим о серверном Blazor.

Серверное приложение Blazor работает исключительно на сервере и построено на основе ASP. NET Core SignalR, коммуникационная библиотека в реальном времени на основе WebSockets. На стороне сервера Blazor может работать на сервере поверх полного ASP. NET Core без ограничений, налагаемых WebAssembly при запуске приложений в браузере.

Текущие инструменты и поддержка Blazor

Когда Microsoft запустила Blazor, это была экспериментальная среда для одностраничных приложений .NET, которые можно было запускать в браузере. Но Microsoft обязуется поставлять его как поддерживаемую платформу веб-интерфейса. Он поддерживается в Windows, Linux и Mac OS и распространяется Microsoft как компонент ASP. NET, флагмана компании в области веб-разработки. ASP. Конвейер .NET Core теперь включает Blazor в свое официальное развертывание.

Создание образца приложения Blazor

Готовы к практической работе? Чтобы более четко понять, как работает Blazor, выполните следующие действия:

Установите последнюю версию .NET Core 3.0 Preview SDK.

Установите шаблоны Blazor, выполнив следующую команду в командной оболочке:

dotnet new -i Microsoft.AspNetCore.Blazor.Templates::3.0.0-preview9.19424.4

Установите Visual Studio Code и последнюю версию C # для расширения Visual Studio Code или установите Visual Studio 2019 Preview.

Самая простая форма Blazor требует только клиентского проекта. Но поскольку нам нужен клиентский опыт работы с серверным серверным проектом, выполните следующую команду в командной оболочке:

dotnet new blazorwasm -o BlazorClientServer --hosted

Откройте решение BlazorClientServer.sln в Visual Studio или откройте папку BlazorClientServer в Visual Studio Code.

Запустите решение.

В браузере перейдите по адресу https: // localhost: 5001.

Здесь мы видим домашнюю страницу приложения.

Теперь перейдите к двум другим пунктам меню, счетчику и выборке данных:

Это очень похоже на обычный ASP. NET Core MVC. Вы можете думать о решении Blazor как о новой разновидности ASP. NET Core, который заменяет JavaScript кодом C #, как мы сейчас увидим.

Теперь давайте внимательно посмотрим на проекты, содержащиеся в сгенерированном ранее решении:

BlazorClientServer.Client - это проект, написанный на .NET Standard 2.0. Это SPA, который содержит страницы и компоненты Blazor, которые запускаются внутри браузера и не требуют перезагрузки страницы во время использования.

BlazorClientServer.Server - это ASP. NET Core для служб HTTP API. Он содержит контроллер и действие, предназначенное для возврата данных прогноза погоды по запросу браузера.

BlazorClientServer.Shared - это проект .NET Standard 2.0, содержащий класс WeatherForecast, который используется как в клиентских, так и в серверных проектах.

Когда вы запускаете приложение, сборка BlazorServer.Client.dll компилируется и развертывается на localhost, но веб-сервер не запускает ее. Вместо этого localhost ждет, пока браузер запросит этот файл. После загрузки эта сборка будет запускаться локально в браузере как WebAssembly.

Но когда браузер скачивает этот файл? Если вы посмотрите на index.html, вы увидите, что он не ссылается на BlazorServer.Client.dll. Вместо этого он указывает URL-адрес для blazor.webassembly.js:

<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8" />
<meta name="viewport" content="width=device-width" />
<title>BlazorClientServer</title>
<base href="/" />
<link href="css/bootstrap/bootstrap.min.css" rel="stylesheet" />
<link href="css/site.css" rel="stylesheet" />
</head>
<body>
<app>Loading...</app>
<script src="_framework/blazor.webassembly.js"></script>
</body>
</html>

Но подождите - мы сказали, что Blazor не требует JavaScript, верно? Это правда. Тем не менее, файл blazor.webassembly.js необходим для загрузки среды выполнения Mono.wasm, библиотек DLL .NET и DLL приложений. Когда эти ресурсы загружены, приложение готово к запуску как WebAssembly.

Верхние элементы в дереве компонентов Blazor определены в файле App.razor. Компонент Router ниже, который предоставляется шаблоном Blazor, устанавливает макет по умолчанию в MainLayout:

<Router AppAssembly="@typeof(Program).Assembly">
<Found Context="routeData">
<RouteView RouteData="@routeData" DefaultLayout="@typeof(MainLayout)" />
</Found>
<NotFound>
<LayoutView Layout="@typeof(MainLayout)">
<p>Sorry, there's nothing at this address.</p>
</LayoutView>
</NotFound>
</Router>

То, что мы видим выше, представляет собой структуру, состоящую из компонентов, подобных той, которую вы ожидаете от компонентно-ориентированного фреймворка, такого как React, Angular или Vue.JS. Каждый компонент определяется в отдельном файле .razor.

Компонент MainLayout, в свою очередь, определяет структуру макета в простом HTML-коде с помощью классов CSS. Макет приложения отображается в виде меню боковой панели и тела центральной страницы:

@inherits LayoutComponentBase
<div class="sidebar">
<NavMenu />
</div>
<div class="main">
<div class="top-row px-4">
<a href="http://blazor.net" target="_blank" class="ml-md-auto">About</a>
</div>
<div class="content px-4">
@Body
</div>
</div>

Обратите внимание, что указанный выше компонент MainLayout наследуется от другого LayoutComponentBase. Что это обозначает? Наследование дает компоненту возможность опираться на более простой компонент. Это уменьшает дублирование кода и упрощает разработку приложений. Тело - это RenderFragment, который должен отображаться внутри макета.

public abstract class LayoutComponentBase : ComponentBase
{
protected LayoutComponentBase();
//
// Summary:
//     Gets the content to be rendered inside the layout.
[Parameter]
public RenderFragment Body { get; set; }
}

Помимо компонентов, которые визуализируют части пользовательского интерфейса, Blazor также имеет концепцию страниц, как и любое обычное приложение HTML. Здесь мы видим простую страницу со счетчиком и кнопкой IncrementCount.

@page "/counter"
<h1>Counter</h1>
<p>Current count: @currentCount</p>
<button class="btn btn-primary" @onclick="IncrementCount">Click me</button>
@code {
int currentCount = 0;
void IncrementCount()
{
currentCount++;
}
}

Но чем эта страница отличается от обычной HTML-страницы?

В первой строке вы можете увидеть директиву страницы: @page «/ counter». Он не только объявляет, что файл должен рассматриваться как страница, но также определяет, что эта страница должна отображаться всякий раз, когда пользователь запрашивает маршрут «/ counter».

@CurrentCount определяет выражение привязки, которое просто отображает переменную currentCount внутри HTML. И @onclick - это обратный вызов события, который запускает IncrementCount при нажатии кнопки.

Но как это клиентское приложение Blazor взаимодействует с серверной частью? Давайте исследуем страницу FetchData.razor, чтобы выяснить это.

@page "/fetchdata"
@using BlazorClientServer.Shared
@inject HttpClient Http
<h1>Weather forecast</h1>
<p>This component demonstrates fetching data from the server.</p>
@if (forecasts == null)
{
<p><em>Loading...</em></p>
}
else
{
<table class="table">
<thead>
<tr>
<th>Date</th>
<th>Temp. (C)</th>
<th>Temp. (F)</th>
<th>Summary</th>
</tr>
</thead>
<tbody>
@foreach (var forecast in forecasts)
{
<tr>
<td>@forecast.Date.ToShortDateString()</td>
<td>@forecast.TemperatureC</td>
<td>@forecast.TemperatureF</td>
<td>@forecast.Summary</td>
</tr>
}
</tbody>
</table>
}
@code {
WeatherForecast[] forecasts;
protected override async Task OnInitializedAsync()
{
forecasts = await Http.GetJsonAsync<WeatherForecast[]>("WeatherForecast");
}
}

При инициализации страница FetchData извлекает данные прогноза погоды асинхронно через HTTP-запрос GET. Обычно JavaScript реализует это требование как функцию AJAX. Здесь эту роль выполняет метод Http.GetJsonAsync ().

Внутреннее приложение (проект BlazorClientServerApp.Server) мало что делает. Он просто размещает серверное приложение на локальном хосте и обеспечивает реализацию конечной точки сервера для функции прогноза погоды.

А вот и сама функция прогноза погоды WeatherForecastController.cs.

[ApiController]
[Route("[controller]")]
public class WeatherForecastController : ControllerBase
{
//code block removed for the sake of brevity
//...
[HttpGet]
public IEnumerable<WeatherForecast> Get()
{
var rng = new Random();
return Enumerable.Range(1, 5).Select(index => new WeatherForecast
{
Date = DateTime.Now.AddDays(index),
TemperatureC = rng.Next(-20, 55),
Summary = Summaries[rng.Next(Summaries.Length)]
})
.ToArray();
}
}

Наконец, у нас есть проект BlazorClientServerApp.Shared, который содержит только класс WeatherForecast. Это не кажется слишком важным, но этот же класс может работать в браузере, через WebAssembly или на сервере внутри полного ASP. NET Core.

Blazor реализует .NET Standard 2.0, спецификацию API-интерфейсов, совместно используемых различными реализациями .NET. Библиотеки классов .NET Standard могут быть распределены по разным платформам, включая Blazor, .NET Framework, .NET Core, Xamarin и Mono.

Класс WeatherForecast довольно прост:

public class WeatherForecast
{
public DateTime Date { get; set; }
public int TemperatureC { get; set; }
public string Summary { get; set; }
public int TemperatureF => 32 + (int)(TemperatureC / 0.5556);
}

Blazor и ваши приложения на JavaScript: что дальше?

В этой статье мы представили Blazor и концепцию WebAssembly и обсудили, как эта структура сравнивается с традиционным JavaScript и ASP. NET программирования.

Мы увидели, как одно и то же приложение работает по-разному в зависимости от того, использует ли оно хостинг на стороне клиента или на стороне сервера, взвесив плюсы и минусы клиентского подхода Blazor.

Наконец, мы провели экскурсию по различным частям примера клиент-серверного приложения Blazor, чтобы продемонстрировать его в действии, указав, чем оно отличается от приложения JavaScript.

Хотя Blazor впечатляет, ему есть куда совершенствоваться, особенно в инструментах и ​​отладке. Программирование на JavaScript живо и хорошо и останется таковым еще долгое время. Но WebAssembly - это технология, которую фронтенд-разработчики не могут игнорировать слишком долго. Blazor - прекрасная возможность для .NET-профессионалов воспользоваться преимуществами этой новой инфраструктуры и стать полнофункциональными разработчиками без необходимости изучать новый язык.

автор Марсело Рикардо де Оливейра

Первоначально опубликовано на https://www.grapecity.com 29 октября 2019 г.