
В этом материале я хочу рассказать о том, что такое Blazor, хочу раскрыть причины того, что вокруг этого фреймворка поднято много шума, собираюсь сравнить его с инструментами из экосистемы JavaScript.
Что такое Blazor?
Blazor (Browser+Razor) — это новый веб-фреймворк, выпущенный Microsoft. Он позволяет создавать браузерные приложения, используя, помимо HTML и CSS, язык C# и синтаксис Razor.
Ранее тот, кто пользовался Razor, должен был запускать представления (view) Razor на сервере, формируя таким образом HTML-код, который мог быть выведен браузером. Теперь же представления Razor можно выполнять на стороне клиента.
Так как Blazor использует WebAssembly, нам не нужно устанавливать в браузер никаких сторонних плагинов или аддонов для выполнения соответствующего кода. В результате оказывается, что используя Blazor можно создавать клиентские и серверные части приложения на C#. Возможность совместного использования кода и библиотек на клиенте и на сервере значительно облегчает жизнь разработчика.
Вот пример кода, используемого в Blazor.

Код, используемый в Blazor
Почему вокруг Blazor поднято так много шума?
Blazor за достаточно короткое время получил немалую известность. Его начали сравнивать с популярными JavaScript-фреймворками. В интернете много говорят о будущем клиентской веб-разработки, в этих разговорах упоминается и Blazor. Всё это лишь добавляет ему популярности. Предлагаю разобраться в причинах происходящего и поговорить о том, почему к Blazor приковано столько внимания.
Как я уже говорил, главная сильная сторона Blazor — это возможность разработки браузерных приложений на C#. В последние годы JavaScript (или TypeScript) был основным языком разработки клиентских частей веб-приложений. То есть, если некто является .NET-программистом, ему, чтобы разрабатывать фуллстек-приложения для веба, необходимо было изучить JavaScript. А с использованием Blazor и клиентские и серверные части веб-приложений можно писать на C#. Лично для меня это — главная сильная сторона Blazor.
Код, написанный для Blazor, в отличие от JavaScript-кода, перед попаданием в браузер предварительно компилируется в промежуточный формат. Эта особенность даёт нам некоторые замечательные возможности при разработке браузерных приложений, требовательных к производительности. И, кроме того, Blazor-приложения подходят для решения ресурсоёмких задач на клиенте. Например — для создания PDF-файлов или для обеспечения работы игровых алгоритмов.
Но, помимо вышеперечисленного, у Blazor есть и другие интересные возможности:
- Для обеспечения работы Blazor не нужны браузерные плагины.
- При разработке для Blazor можно выполнять полноценную отладку .NET-кода.
- Фреймворк использует новейшие возможности браузеров.
- Blazor поддерживает удобную модель разработки интерфейсов.
- Фреймворк отличается хорошей браузерной поддержкой.
- Blazor поддерживает механизм внедрения зависимостей.
- Использование Blazor позволяет организовать совместное использование кода между клиентскими и серверными частями приложений.
Сравнение JavaScript-инструментов и Blazor
А теперь мы добрались до самой главной части этой статьи. Поищем ответ на вопрос о том, сможет ли Blazor стать заменой для библиотек и фреймворков, написанных на JavaScript. Сможет ли JavaScript удержать занятые им позиции? Пожалуй, любой, кто интересуется современным состоянием фронтенд-разработки, хотел бы знать ответы на эти вопросы. Полагаю, что пока слишком рано делать окончательные выводы, или даже строить некие предположения на этот счёт. Но мы, чтобы приблизиться к истине, можем сравнить с Blazor несколько ведущих JavaScript-библиотек и фреймворков.
?Сравнение Blazor и React
Многие считают React самой лучшей библиотекой для разработки веб-компонентов. Хотя и сложно сравнивать React и Blazor, мы должны признать то, что React — это тщательно проработанная библиотека, которая доказала свою пригодность для разработки реальных проектов. Вокруг React сформировалось мощное сообщество программистов.
Экосистема React полна библиотек и фреймворков, которые облегчают процесс разработки оптимизированных React-приложений. Эти библиотеки и фреймворки делают React «универсальным языком», используя который, можно создавать приложения для веба, для командной строки, для iOS и Android, для настольных систем.
Blazor, в сравнении с React, это явление достаточно новое. Но не стоит забывать о том, что за Blazor стоит серьёзная система Razor. Поэтому мы не можем говорить о том, что Blazor — это нечто, совершенно неизвестное программистам. Кроме этого, так как Blazor использует C#, это облегчает и ускоряет освоение данного фреймворка .NET-разработчиками. Хотя React, улучшаясь со временем, даёт разработчикам множество возможностей, и хотя у React есть масса сильных сторон, в Blazor, несмотря на совсем небольшой возраст этого фреймворка, тоже есть кое-что примечательное:
- Blazor-проекты, как и проекты, основанные на React, можно разворачивать в виде статических файлов.
- В Blazor-приложениях можно использовать пакеты NuGet.
- При применении Blazor на клиенте и на сервере можно использовать один и тот же код (это, конечно, справедливо и при использовании JS/TS).
- В Blazor есть встроенные механизмы для маршрутизации, для проверки данных, введённых пользователем, для обработки форм.
Это — лишь небольшой набор возможностей Blazor. Но, если ориентироваться на текущую ситуацию, можно сказать, что если некая команда уверенно пользуется JavaScript, то ей, безусловно, стоит просто пользоваться React. С другой стороны, Blazor — это отличный вариант для того, кто владеет .NET лучше, чем JavaScript, и при этом начинает работу над новым веб-проектом.
?Сравнение Blazor и Angular
JavaScript-фреймворк Angular тоже популярен в деле разработки одностраничных приложений. Если сравнить его с библиотекой React, то окажется, что он включает в себя больше стандартных возможностей. Angular предоставляет разработчику клиентских приложений архитектуру MVC, что позволяет упростить процессы создания и тестирования проектов. Если же сравнить Angular и Blazor, то окажется, что Angular занимает прочное место во фронтенд-разработке, как хорошо известный и стабильный фреймворк, пригодный для создания реальных приложений. Кроме того, Angular полностью поддерживает прогрессивные веб-приложения, в то время как серверные механизмы Blazor ещё должны развиться в этом направлении. Более того, так как в Angular используется TypeScript, этот фреймворк ближе и понятнее для C#-программистов, чем фреймворки и библиотеки, основанные на JavaScript. Учитывая все сильные стороны Angular, я не вижу причин для того, чтобы кто-то, хорошо знающий TypeScript, решил бы выбрать Blazor.
Итоги
Blazor — это, безусловно, интересный проект, который, несмотря на то, что появился он сравнительно недавно, заслуживает определённого внимания. А вопрос о том, способен ли он заменить JavaScript-инструменты в деле разработки фронтенда, пока остаётся открытым.
Пробовали ли вы Blazor?

JustDont
Из абцаза выше процитированного текста можно предполагать, что сравнение всё еще идёт с JS. Ну окей:
Для JS они тоже (чудеса, правда?) не нужны.
При разработке на JS можно выполнять полноценную отладку JS. Опять же, чудо чудное, да?
А еще он отлично работает в IE11. Или нет. В любом случае, JS, внезапно, тоже использует новейшие возможности браузеров.
Ну да, работает везде, кроме тех браузеров, где не работает ;-)
Ну прям как c Node.js несколько лет назад, ага.
Отличное сравнение. Впрочем, чего еще ожидать от пустой маркетинговой статьи.
AxisPod
Только вот уровень языков очень разный. Даже TypeScript не сможет соревноваться с платформой .NET. В данном случае C# из коробки работает полноценно с модулями, и не требуется уписываться import'ами, чуть более что-то серьёзное и десятки и более строк импортов с кучей функций и компонентов. Опять же шикарная строгая типизация. Да и колосальный фреймворк, а не тот ад, что творится в JS, тысячи библиотек в зависимостях. Одну обновили и добавили баг и потом можно неделями искать эту проблему.
Как? Имея кучу гемороя с сорсмапами, когда одни работают в одних условиях, другие в других, при этом скорость компиляции знатно начинает страдать.
В общем как и JS. Внедрение новых возможностей до сих пор хромает, приходится использовать постоянно колосальное кол-во полифилов, чтобы работало в старых бразуерах, эх, мечта, иметь новые возможности, а пользоваться только старыми.
Вот не стоит путать возможности и инфраструктуру Node.js с .NET, тут опять же не требуется этот колосальный ад из тысяч бибилиотек, чтобы всё работало.
А чего так просто забыли процитировать внедрение зависимостей? Или просто сказать нечего? В том же Angular увы это костыль, а ни как не полноценное внедрение зависимостей. И это то, чего мне не хватает в JS, очень сложно построить внятную архитектуру приложения на JS. Вплоть до того, что не так давно сделал некую альтернативу для нашего проекта, да, стало проще, но всё не получается реализовать все возможности в рамках JS.
Я конечно понимаю, вы фанат JS, но не стоит плевать со своей колокольни, если на другой никогда не были.
Я работал и с .NET и с JS и могу сказать одно, я терпеть не могу JS из-за его низкого порога вхождения, это приводит к появлению кучи низкокачественного кода, им завалено всё, ад из мелких библиотек. Если смотреть на фреймворки типа Angular, даже они крайне слабы в сравнении с платформой .NET, да, я не буду отрицать, что Blazor в начале пути и пока что он не подойдёт для полноценных проектов, но потенциала у него куда больше чем у JS.
JustDont
И вы, конечно, почему-то считаете это чем-то плохим. Непонятно только, почему.
В TS не хуже. Я бы вообще сказал, что «лучше», но это вкусовщина, поэтому не буду.
Когда вы сами себе злобный буратина, и не имеете тестов, но зато имеете отличную привычку обновлять версии ваших зависимостей просто потому, что вам так захотелось? Конечно.
Вы еще давайте расскажите, как в C# нельзя выстрелить себе в ногу, чтоб мы тут дружно почитали и посмеялись.
Если вы не умеете создавать сорсмапы — честное слово, это не проблема сорсмапов. Это настолько не rocket science, что утверждать, что там всё плохо — это ну очень грустно.
Да нет, не «как». Большинство новых фич языка полифиллится, то есть, таки в итоге работает в старых браузерах. С web assembly всё просто: нет браузерной поддержки? Идите лесом, точка.
Да, пропустил и не заметил. Хвалиться «внедрением зависимостей» — это что-то из серии «а в нашем крутом инструменте можно сделать цикл со счётчиком!». DI тривиально делается в любом приличном языке (и нетривиально, но всё равно делается — в любом тьюринг-полном).
В том же ангуляре это тяжелое наследие, которое изначально было довольно убого реализовано, а теперь так и тянется. Ничего удивительного.
Вот давайте предметно: что такого вы архитектурно можете реализовать на C#, и не можете на JS?
Нет, я не фанат JS. Я просто на нем (да и даже не на нем, а на TS) пишу, и поэтому к высасываемым из пальца аргументам «за Blazor» отношусь очень пренебрежительно. Потому что реальный аргумент тут ровно один: «вы можете сбацать SPA, не вылезая из уютного C#». И после этого следует долгий разговор о цене, которую вы за это заплатите, например, о том, что весь ваш код будет результироваться в немаленькие блобы, которые любой заходящий на вашу страницу будет обязан полностью выгрузить прежде чем у него вообще начнёт хоть что-то работать. И что работать оно всё будет примерно с такой же скоростью, как и на JS.
xMushroom
TS хорош, чертовски хорош, и система типов в нём крутейшая. Проблема у него только одна — JS. Пишешь крутейший типизированный код, а потом как лбом об асфальт врезаешься в какую-нибудь простейшую вещь, которую сделать нельзя, или в какое-то совершенно неочевидное поведение, потому что JS.
В этом смысле C# выигрывает в плане стабильности — да, не так круто, зато гораздо меньше таких вот сюрпризов.
JustDont
Давайте я и у вас попрошу конкретики: что такого «простейшего» вы не смогли сделать?
xMushroom
Легко. Вот прямо вчера пример: есть тип discriminated union по строкам, ну например:
Дальше, имеется строка, полученная с вебсервиса в рантайме. Как проверить, что строка принадлежит этому типу? Быстрое гугление показало, что проще всего сделать массив со всеми валидными строками для типа и использовать его как основу для типа, а проверять через массив. К сожалению, определение типа я изменить не могу, так как он не мой, так что этот способ мне не подходит. Ну и даже этот способ, честно говоря, выглядит костылём.JustDont
Если вспомнить, что TS и его типов в рантайме не существует — то становится совершенно очевидно, что никак. Вы пытаетесь использовать инструмент не по назначению. Переход от «типов» к «коду в рантайме» силами TS принципиально не возможен.
А если вам просто не хочется писать руками тайпгарды, а хочется, чтоб они «сами» возникали — пользуйтесь автоматикой, типа такой github.com/rhys-vdw/ts-auto-guard. Генерация кода по типам в компайл-тайм — конечно же очень возможна.
xMushroom
Так я и пишу про преимущества/недостатки инструмента.
JustDont
Действительно, микроскоп имеет тот небольшой недостаток, что гвозди им забивать не очень удобно.
xMushroom
Поясните, где здесь забивание гвоздей микроскопом? Хотите сказать, что TS не предполагает работы с типами? Или работа с типами в рантайме — это какая-то плохая идея? Я лично всегда считал, что это попросту недостаток выбранной реализации (транспиляции в JS).
JustDont
Хочу сказать, что любая реализация RTTI небесплатна, а RTTI сам по себе практически никогда не является необходимой абстракцией, это скорее «решение для бедных», покрывающее проблемы системы типов конкретного языка, и открывающее бекдоры вида «если нельзя, но очень хочется — тогда таки сделаем».
Типы в рантайме в общем случае просто не нужны. А если имеется некоторый частный случай, в котором просто страсть как хочется — для этого нужно брать соответствующие частные же решения.
mayorovp
Ну вот у Typescript и есть эти самые проблемы, но нет даже "решения для бедных" в виде RTTI.
JustDont
Есть конечно, просто не в составе TS.
justboris
Typescript предоставляет опцию
emitDecoratorMetadata
, которая записывает информацию о типах в рантайм, а как её обрабатывать – это уже дело userland-библиотекJustDont
Справедливости ради, декораторы — это всё же не RTTI, да и вообще странная штука, которую до сих пор не могут толком стабилизировать.
xMushroom
JustDont
Я вам даже ссылку давал.
Lodin
… и даже медленнее, потому что WebAssembly пока что не умеет в прямую интеракцию с DOM, и там будут постоянные пробросы команд WA -> JS -> DOM и обратно.
AxisPod
Ну хорошо, подробнее.
Циклические зависимости, такой беды как это в JS, C, C++ и т.д. тут нет, если в C и C++ это можно решить, то в JS это даже решить адекватно нельзя, ну никак. Вторым пунктом тут идёт снижение объёмов бойлерплейт кода.
Я бы сказал, что хуже. В TS стогая типизация, но если хочется, то будет не строгая. В C# так сделать нельзя, да, там есть тип dynamic, но он не лежит в основе языка, при этом же код даже под dynamic идёт довольно строг. Опять же к системе типов, в JS в общем примерно как и в Java value-type идут только для примитивных типов и никак иначе, в C# этим можно управлять.
Тесты, окей. В JS и даже TS нет адекватной реализации DI и IoC, если в TS хоть какой-то костыль есть, то тут всё плохо, а в содружестве с отсутствием модулей, приходится мокать не просто передаваемые объекты внутрь кода, а приходится мокать импорты, приходится мокать хуки и т.д., что по факту убивает идею юнит-тестов и тестирования чёрного ящика, ибо надо знать внутреннюю реализацию тестируемого кода.
А обновление зависимостей временами требуется как бы, новый функционал, фиксы багов, которых обычно ой как не мало. И что уж делать, если я на пршлой неделе сделал новый проект используя create-react-app и получил десятки ворнингов несоответствия версий. В C# за весь мой опыт такого отстойного отношения к коду я ещё не видел.
Не отрицаю, в C# есть ад зависимостей, но не настолько гигантский как в JS, в .net core при этом ад стал ещё меньше.
Ага, не хочешь по 5-10 минут собирать проект, делаешь послабше сорсмапы, ах да, тут дебаггер не может трейсить код, переключаешься опять на дотошные сорсмапы, ах да, тут понадобилось подрубить css, ой, все стильники в index.js, идёшь, опять меняешь сорсмап и т.д. Это типа всё окей?
Web Assembly — этот как бы что-то похожее на ассемблер. Я не говорил про поддержку DOM, новых стандартов CSS, я тупо говорил про какие-нить функции для работы с данными. startsWith, includes и т.д.
Ну давайте покажите пример тестов вашего кода. И мы уже оценим, реально ли это в рамках JS или не особо. Особенно в условиях, когда JS сейчас тупой и процедурный и даже его крайне костыльные объектная-ориентированность не используется кучей разработчиков, чего стоят хуки реакта. Я уж лучше сделаю сервис, который мне будет IoC контейнер подсовывать сам и я не буду париться, а в тестах я сделаю простой мок. А не буду париться с попытками мокнуть импорт в Jest с кучей проблем.
Ну давайте. React+Redux+Deox+Saga и это только самый базовый набор библиотек. Все подразумевают работу в своём уникальном стиле, у всех сайд эффекты поддерживаются по своему, этим пользоваться можно, но искать код, который нужен в большом проекте задачка уже становится совсем нетривиальной. Приходится использовать кучу разных механизмов, вместо одного.
Ну тут видны консервативные взгляды, тут ключевой момент не C#, а Web Assembly, родная технология для браузеров и вам грустно становится от того, что теперь на C#, который скомпилится в Web Assembly, можно писать родной код для браузеров. И вам обидно, прям как фанатам PS, когда их эксклюзивы уходят на ПК.
JustDont
Разбиение кода на множество блоков и множество же импортов — никак не равно «циклические зависимости» и даже не способствует им.
Тот неловкий момент, когда модули называют «бойлерплейтом». А лучше вообще просто фигачить всё в один исполняемый файл, сразу в машинных кодах, а то понапридумывают этого вашего бойлерплейта, а нам писать его.
Простите, но это пустопорожняя риторика. Я вам точно так же вашими же словами скажу, что «тип any не лежит в основе языка». Про «строгость с dynamic» вообще смешно. Какая «строгость», если компайл-тайм проверки типов к dynamic просто не применяются?
Вы вообще о чём сейчас? Вы говорите о языке с first-class functions, где IoC выражается просто передачей функции в качестве параметра. Рюшечки сверх этого можно навернуть какие угодно самостоятельно или взять готовые. Вы всерьез что ли думаете, что в экосистеме нет решений по IoC с каким угодно произвольным числом наворотов? Есть.
Я уже в который раз замечаю, что вы пишете так, как будто вы недавно узнали много разных баззвордов, но не удосужились узнать их значение. Юнит-тесты по определению основаны на знании внутренней реализации «юнитов» (чем бы они у вас не были).
Create-react-app — не эталон прекрасного кода, а средство для бедных, которые не могут разобраться с тем, что там с чем соединить, чтоб у них проект получился. Не пользуйтесь плохими сторонними решениями, что я вам могу сказать.
Это не «базовый набор», а жуткая сборная солянка, которую вы сами же себе устроили, а теперь говорите, что не можете с ней справиться. Не можете — так и не берите. Есть вещи даже проще голого реакта, что уж говорить про попытке собрать стейт-менеджер из всего, что только под руку попало.
И этот же человек выше говорит про «бойлерплейт», а сам пытается писать со стеком, с которым без множества вождений руками вокруг навязываемых архитектур ничего не пишется.
Вы не удосужились ознакомиться с дорожной картой реализации WA. Там нет «сделаем так, чтоб было удобно сбацать сайтик на C#, C++, Rust, итд», это всего лишь побочный эффект.
WA реализован как механизм подключения в JS числодробилок, и именно в этом плане он работает максимально хорошо. Использование WA в других контекстах — связано с солидным объемом проблем. В первую очередь с большими блобами, которые к тому же не дают никакого преимущества по скорости работы страницы.
Я вообще нахожу очень забавным, что всё те же самые люди, которые при случае всегда любят пнуть JS за «сайты стали толстыми, надо грузить мегабайты JSа» — в разговорах о web assembly всегда помалкивают о том, сколько там юзеру придётся грузить скомпилированного кода.
AxisPod
Ээээ, тут только одна State-magament либа и это Redux. А всё остальное, это лишь необходимость для исправления архитектурных проблем этого самого Redux. Ну и контексты реакта, спасибо, не надо, для калькулятора хватит, а вот посерьёзнее проект не переживёт, особенно если хочется к примеру Redu/Undo добавить.
Я в курсе что такое WA и как оно работает. И WA так или иначе родная для браузеров технология, тут уже какое-то словоблудие начинается.
Как бы часто неподконтрольные перерисовки, а и часто ненужные перерисовки со стороны React как бы не даёт никакого преимущества по скорости работы.
Ну и хватит кормить тролля. Уже все ваши доводы скатились до уровня Страуструпа, когда он был против тех или иных пропосалов в новые стандарты C++. «А это ведь можно вот так сделать» и выдаёт раз в 5-10 больше кода. Да, можно, но зачем? Если можно сделать проще, если можно не заботиться о проблемах, если уже есть готовые решения. Зачем страдать? Но вот все ваши доводы уже скатились до уровня: Можно ведь и пострадать. Развитие ЯП сводится не к удовлетворению вашего эго, а к снижению трудозатрат. И blazor это может дать. А если уж у разработчиков не хватит ума-разума, чтобы это понять, это не вина платформы, увы.
JustDont
Ну так и что вам мешает не брать редакс, раз он такой плохой?
Если вы не в состоянии совладать с «неподконтрольными» перерисовками в реакте, почему стоит ожидать, что у вас в blazor будет всё лучше?
А, изучение подходящих инструментов у вас теперь называется «можно пострадать». Ну, бывает. А не страдать — это, видимо, пользоваться как можно большим количеством текущих абстракций, и все протечки молча игнорировать. Блобы большие? Ну так это не наша проблема, у нас всё скомпилировалось же и работает. Пускай либы сишарпа в сам браузер положат, авось поменьше станут ;-) Работает небыстро? Пускай делают нативный доступ к DOM из WA, а потом это в каком-нибудь blazor реализовывают, а мы тут не при чём ;-)
Sm1le291
вы мне напоминаете одного моего коллегу фронтендера-тролля. Все это выглядит преимуществом для дот нет разработчика. Я у себя на работе успешно перешел на блейзор за пару дней.
А если вы знали js то само собой для вас ничего не поменяется и blazor вам не нужен и преимуществ нет никаких, да и какие они могут быть если это просто другой язык программирования
JustDont
Вы, собственно, сами выложили единственное преимущество, которое тут есть. «Не надо учить этот ваш мерсссский JS».
Sm1le291
а что плохого когда есть альтернативы и возможность выбора?
И да, то что он мерзкий я не говорил, извините но мерзкий здесь вы
JustDont
Ничего плохого. Просто выложенный в статье «список преимуществ» высосан из пальца и ничего общего с реальностью не имеет, и ровно об этом я и писал под тем самым вашим постом, в котором вы прибежали меня обвинять в троллинге.
Ну так учить вы тоже не хотите ;-)
Kanut79
Да статья конечно так себе…
На мой взгляд преимущества пока только для тех кто пишет на C#. То есть не надо учить JS и можно использовать уже имеющиеся библиотеки.
И именно переходить на Blazor c каких-нибудь Angular/React/Vue лично я пока не вижу никакого смысла.