Pull to refresh

Пишем ХабраКвест на ASP.NET Core и Angular2

Reading time8 min
Views34K
Каждый раз с выходом нового фреймворка, хочется попробовать его в деле и написать на нем какое-то приложение. В прошлый раз отлично зашел формат квеста. По этому предлагаю посмотреть что поменялось за почти полтора года и написать еще один квест— и фреймворки посмотрим, и поиграть можно.
Результат:
сорсы на гитхабе для тех, кому интересно посмотреть на исходники
линк на квест для тех, кому интересно что получилось или потратить свое время на еще один логический квест.

Под катом описан полный процесс от создания проекта до его развертывания.


Предварительные требования


Для работы с ASP.NET Core и Angular2 подойдет почти любая IDE или текстовый редактор. Конечно для полноценной отладки ASP.NET нужна Visual Studio, но с выходом новой Core версии для разработки она не обязательна, можно работать с кодом в Sublime\Atom\… и запускать приложение (предварительно установив SDK) из командной строки, с помощью:
dotnet run

Исходный код, инсталлятор, документацию для интерфейса командой строки .NET и SDK можно найти на:
dotnet.github.io
При чем все это теперь доступно не только лишь на Windows но и на Max, Linux, а так же Docker.

Наверное, многие испытают когнитивный диссонанс, увидев
sudo apt-get install dotnet-dev-1.0.0-preview2-003121


Создаем проект


Для создания нового ASP.NET core приложения есть несколько путей:
1) С помощью Visual Studio
2) Из консоли — dotnet new
3) Используя сторонние генераторы.

Не будем углубляться во все проблемы создания и конфигурирования проекта, тем более что нам нужно не пустое приложение, а уже с подключенным Angular2 и, желательно настроенными билд скриптами.
Для этого идеально подходит ASP.NET Core JavaScript Services github.com/aspnet/JavaScriptServices, который позволяет создавать приложения для ASP.NET Core с JavaScript фреймворком на выбор: Angular 2, React, и Knockout.
Для этого нам потребуется: ASP.NET Core, Node.js и генератор yeoman с шаблоном aspnet-spa. Последний можно установить с помощью:
npm install -g yo generator-aspnetcore-spa

Теперь создание нового проекта сводится к
cd <папка_для_проекта>
yo aspnetcore-spa



Выбираем Angular2 шаблон, название проекта и генератор сам создаст всю структуру, зависимости и т.д. (это может занять несколько минут).
Сначала может показаться, что этот генератор использует слишком много библиотек, особенно, если вы не любитель последних или же мало работали с фронт-ендом. Но лично мое мнение — что это один из наиболее сбалансированных шаблонов. Особенно хочется выделить следующие свойства:

TypeScript


Конечно же разрабатывать приложения на Angular2 можно и на простом JavaScript, TypeScript дает нам возможности типизации, автодополнения, более привычный (для большинства) синтаксис для ООП. А также команда Angular2 активно использует TypeScript и похоже на то, что TypeScript будет (или уже есть) не официальным языком по умолчанию для Angular2.

Webpack


Похоже, что webpack быстро становится фаворитом в битве инструментов для фронт-енда. Особенно важно заметить его возможности при постоянном изменении кода. Фактически разработчику можно забыть о том, чтобы постоянно пересобирать проект и обновлять страницу с помощью Горячей Подмены Модулей (Hot module replacement — HMR). После того как попробовали писать фронт-енд на одном мониторе, в то время как на втором он на глазах меняется уже не хочется возвращаться назад, на инструменты без возможности горячей подмены.

Другие бонусы


Серверный пре-рендер, ленивая загрузка, удобная работа с Development и Production билдами.
Больше можно узнать в блоге одного из разработчиков JavaScriptServices:
blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core
или же увидеть реальный пример в одном из последних публичных стенд-апов команды ASP.NET:


Собираем проект


Как уже говорилось раньше, чтобы собрать и запустить проект, можно воспользоваться консольной командой:
dotnet run


Как результат, сайт будет собран и запущен локально:


Или же, сделать тоже самое из Visual Studio.
Если после билда у вас будет уведомление, что не все модули npm установлены,

скорее всего это проблема с тем, что один из модулей не поддерживается в Windows, но по скольку зависимость не обязательная, приложение должно работать нормально.

В результате у вас должно запустить рабочее приложение с тремя простыми страничками.


Приступаем к работе


Рассмотрим главные отличия, в сравнении с предыдущими версиями фреймворков.

Структура проекта


Похоже, структура проекта JavaScriptServices webpack-ориентирована. То есть это npm + webpack, соответственно отсутствуют gulp и bower. На сколько я понимаю bower просто решили не добавлять в стартовый проект, так как нет много зависимостей от JavaScript библиотек, со всем справляется npm. А все функции gulp (или grunt) теперь выполняет webpack.

Что касается файловой структуры, то по части серверных файлов все так же, как и раньше, а вот на front-end есть некоторые отличия. Например, в папке со статическими файлами wwwroot есть только папка dist, куда, фактически, компилируется весь JavaScript.
В сравнении с первой версией Angular бросается в глаза то, что нет никаких представлений и контроллеров — все в компонентах и для каждой html части компоненты есть TypeScript часть.

Особенности в процессе


Webpack конечно очень радует в плане горячей замены модулей, разработка front-end части из-за этого значительно приятнее.
Стоит так же заметить, что ошибки WebPack отлично показываются уже на уровне ASP.NET, очень удобная интеграция. Правда после ошибочного состояния (например, подтягивание не существующей компоненты) горячая замена у меня не заработала, возможно в таких случаях все же надо обновлять страницу вручную.

Так же очень удобно то, что дебажить в браузере можно TypeScript и все это уже встроено по умолчанию


В первую очередь я переделал страницы с примерами на те, что нужны мне. Это оказалось очень просто, несмотря на то, что мои знания Angular2 и TypeScript близки к нулю. Вообще синтаксис нового Angular кажется очень читабельным, как минимум с первого взгляда. А возможность описывать интерфейсы, классы и типы в TypeScript делают его очень понятным.
Пример простой компоненты:

Думаю большинство разработчиков, которые видят TypeScript в первый раз сразу поймут что здесь происходит.

Entity Framework и база данных


Если вы знакомы с предыдущими версиями Entity Framework то с Entity Framework Core проблем возникнуть не должно. В крайнем случае — можно просмотреть документацию на docs.efproject.net/en/latest/intro.html

Сначала ставим nuget пакеты для самого EF, а также для инструментов для работы с базой (версия последнего пока не стабильна):
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools –Pre

github.com/gbdrm/HabraQuest/commit/959f4cb6c253dad0cc5e6eb34756ee5cc9c920f9

Дальше, добавляем команды инструментов в project.json, для этого открываем его, находим настройки tools и добавляем
"Microsoft.EntityFrameworkCore.Tools": "1.0.0-preview2-final",

Возможно в вашем шаблоне инструменты уже будут добавлены. Тогда ничего менять не надо.

Добавляем классы модели нашего приложения и DbContext и регистрируем их в Startup.cs.
Ну и конечно ConnectionString в appsettings.json и так же добавляем код для конфигурации в Startup.cs.
github.com/gbdrm/HabraQuest/commit/7411eb4262bdef9f5fb810f6cf7d5a239221c0b5

Следующий шаг, типичная история с миграциями — добавляем начальную миграцию и просим базу обновиться.
Add-Migration Initial
Update-Database

Поскольку база еще не существует, после второй команды она должна быть создана. Это можно проверить, посмотрев, какие базы данных существуют если присоединиться к SQL-серверу с помощью Visual или SQL Management студии.
github.com/gbdrm/HabraQuest/commit/09b42dc0a8e45da1f461b38c2b41d79c4fc0b88a

Давайте добавим простой метод в Home контроллер и попробуем минимально использовать соединение с базой. Добавим метод создания нового игрока, который будем возвращать его токен.
github.com/gbdrm/HabraQuest/commit/e67a322184517aa929d1347f6fd638c6290bf9d3

Если теперь мы запустим приложение, можно протестировать этот метод, добавив /home/registernewplayer в конец адреса. В результате мы должны получить токен нашего игрока.


Первые шаги в Angular 2


По скольку мы уже создали примитивный back-end, то можем попробовать его использовать на клиенте. Попробуем сделать следующее:
когда новый пользователь заходит на страницу — проверить, есть ли у него cookie с токеном и, если нету, попросить его из сервера. Чтобы не создавать собственный велосипед, попробуем использовать существующую библиотеку для работы с cookie. Например, ng2-cookies.
Для этого нам надо установить ее и подключить в компоненте home.
github.com/gbdrm/HabraQuest/commit/8c7aadd9607a0c4d0a1039707b08b0c4b720112c

Сложно описать мои следующие несколько часов упорной борьбы со стереотипами JavaScript и первого Angular. Оказалось, что во второй версии фреймворка все абсолютно иначе. Могу лишь сказать, что закончилось это тем, что я решил пока не использовать сервисы (решил сначала лучше разобраться с rxjs observable, который активно используется в Angular 2), обновил пакеты до следующего релиз кандидата (четвертого), добавил новые формы (оказалось, что они были сильно переделаны и этот процесс еще не закончен) и решил максимально упросить код (большинство логики в одну компоненту). Для начала нужно сделать что-то рабочее, а потом будем думать о хороших практиках. Так же добавил несколько заглушек на серверную часть.
github.com/gbdrm/HabraQuest/commit/60c8239a89cae2357d0521973e091781027186ba

Из интересных особенностей — то ли студия то ли решарпер умеют подтягивать правильные импорты для TypeScript, так же в большинстве случаев работает штатная навигация по методах. Из-за такого рода особенностей писать код для клиентской части становиться значительно приятней, нету больше чувства, что вы пишете какой-то скрипт, который может упасть где угодно. Вместо этого основные элементы синтаксиса проверяются автоматически и есть уверенность, что все не поломается где-то посредине. А даже если и поломается, то выполнится еще одна проверка на уровне webpack и в результате на странице будет показа ошибка, даже без перезапуска.


Правда, иногда, это начинает напрягать, когда после каждого сохранения файла — страница начинает перерисовываться. Но думаю это вопрос привычки.

Весь следующий код не представляет особой важности. В основному это реализация заглушенных моментов. Если вам все же интересно просмотреть — исходники доступны на github.com/gbdrm/HabraQuest

Развертывание


По скольку бек-енд написан на .Net то деплоить наше приложение будем на Azure. Кстати за последние год-полтора тут тоже изменений хоть отбавляй, с первого раза не разберешься что и куда. Для нашего приложения нам достаточно будет создать самый базовый сайт с базой (Web App + SQL).
С деплойментом, как всегда, не очень гладко. Во-первых, он не проходит без ошибок. Сам сайт работает, но в итоге Visual Studio показывает ошибки в каких-то внешних модулях TypeScript. Пока так и не разобрался что это. Во-вторых, бывает, что при открытии сайта вылетает ошибка «TaskCanceledException: A task was canceled». С этим тоже пока не до конца ясно, но похоже проблема где-то на уровне хостинга. И кроме этого, немного поигрался с миграциями.

Хотя, в общем, я этим шагом остался доволен. Очень детальный и понятный лог, все можно сконфигурировать (база, миграции). Первый раз, правда, нужно подождать некоторое время (несколько минут) пока все билдится, копируется. Да и вообще, похоже, что процесс довольно сложный, на сколько я понял сначала все копируется локально, а потом уже перебрасывается на Azure, но это уже детали.

Результат, выводы


Все получилось так, как и планировалось. Новыми фреймворками лично я доволен, с радостью бы на них перешел. Конечно есть еще не очень стабильные моменты, Angular 2 еще и совсем не выпущен официально. Но выглядит все уже довольно интересно и, главное, работает.
Очень радует развитие инструментов, подходов в разработке которые позволяют делать меньше рутинных задач, типа обновления станицы, контролирования структуры базы данных.
Так же, очень много блогов, вопросов, документации в сети, так что с решением типичных задач уже должно быть все просто.

Все результаты можно найти на:
github.com/gbdrm/HabraQuest
habraquest.azurewebsites.net

Получилось довольно сумбурно, так как много разных тем. Какие из них вам наиболее интересны для описания в будущем?
Only registered users can participate in poll. Log in, please.
Какие из описанных тем наиболее интересны?
63.29% Angular 2250
73.16% ASP.NET Core289
38.48% EF Core152
45.06% TypeScript178
9.11% yeoman, JavaScriptServices36
29.87% WebPack, инструменты сборки118
40.51% Кросс-платформенность .NET160
10.63% Azure42
8.1% Квест32
395 users voted. 51 users abstained.
Tags:
Hubs:
Total votes 39: ↑34 and ↓5+29
Comments63

Articles