- PVSM.RU - https://www.pvsm.ru -
Каждый раз с выходом нового фреймворка, хочется попробовать его в деле и написать на нем какое-то приложение. В прошлый раз [1] отлично зашел формат квеста. По этому предлагаю посмотреть что поменялось за почти полтора года и написать еще один квест— и фреймворки посмотрим, и поиграть можно.
Результат:
— сорсы на гитхабе [2] для тех, кому интересно посмотреть на исходники
— линк на квест [3] для тех, кому интересно что получилось или потратить свое время на еще один логический квест.

Под катом описан полный процесс от создания проекта до его развертывания.
Для работы с ASP.NET Core и Angular2 подойдет почти любая IDE или текстовый редактор. Конечно для полноценной отладки ASP.NET нужна Visual Studio, но с выходом новой Core версии для разработки она не обязательна, можно работать с кодом в SublimeAtom… и запускать приложение (предварительно установив SDK) из командной строки, с помощью:
dotnet run
Исходный код, инсталлятор, документацию для интерфейса командой строки .NET и SDK можно найти на:
dotnet.github.io [4]
При чем все это теперь доступно не только лишь на 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 [5], который позволяет создавать приложения для 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 шаблон, название проекта и генератор сам создаст всю структуру, зависимости и т.д. (это может занять несколько минут).
Сначала может показаться, что этот генератор использует слишком много библиотек, особенно, если вы не любитель последних или же мало работали с фронт-ендом. Но лично мое мнение — что это один из наиболее сбалансированных шаблонов. Особенно хочется выделить следующие свойства:
Конечно же разрабатывать приложения на Angular2 можно и на простом JavaScript, TypeScript дает нам возможности типизации, автодополнения, более привычный (для большинства) синтаксис для ООП. А также команда Angular2 активно использует TypeScript и похоже на то, что TypeScript будет (или уже есть) не официальным языком по умолчанию для Angular2.
Похоже, что webpack быстро становится фаворитом в битве инструментов для фронт-енда. Особенно важно заметить его возможности при постоянном изменении кода. Фактически разработчику можно забыть о том, чтобы постоянно пересобирать проект и обновлять страницу с помощью Горячей Подмены Модулей (Hot module replacement — HMR). После того как попробовали писать фронт-енд на одном мониторе, в то время как на втором он на глазах меняется уже не хочется возвращаться назад, на инструменты без возможности горячей подмены.
Серверный пре-рендер, ленивая загрузка, удобная работа с Development и Production билдами.
Больше можно узнать в блоге одного из разработчиков JavaScriptServices:
blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core [6]
или же увидеть реальный пример в одном из последних публичных стенд-апов команды 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 Core проблем возникнуть не должно. В крайнем случае — можно просмотреть документацию на docs.efproject.net/en/latest/intro.html [7]
Сначала ставим nuget пакеты для самого EF, а также для инструментов для работы с базой (версия последнего пока не стабильна):
Install-Package Microsoft.EntityFrameworkCore.SqlServer
Install-Package Microsoft.EntityFrameworkCore.Tools –Pre
github.com/gbdrm/HabraQuest/commit/959f4cb6c253dad0cc5e6eb34756ee5cc9c920f9 [8]
Дальше, добавляем команды инструментов в 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 [9]
Следующий шаг, типичная история с миграциями — добавляем начальную миграцию и просим базу обновиться.
Add-Migration Initial
Update-Database
Поскольку база еще не существует, после второй команды она должна быть создана. Это можно проверить, посмотрев, какие базы данных существуют если присоединиться к SQL-серверу с помощью Visual или SQL Management студии.
github.com/gbdrm/HabraQuest/commit/09b42dc0a8e45da1f461b38c2b41d79c4fc0b88a [10]
Давайте добавим простой метод в Home контроллер и попробуем минимально использовать соединение с базой. Добавим метод создания нового игрока, который будем возвращать его токен.
github.com/gbdrm/HabraQuest/commit/e67a322184517aa929d1347f6fd638c6290bf9d3 [11]
Если теперь мы запустим приложение, можно протестировать этот метод, добавив /home/registernewplayer в конец адреса. В результате мы должны получить токен нашего игрока.

По скольку мы уже создали примитивный back-end, то можем попробовать его использовать на клиенте. Попробуем сделать следующее:
когда новый пользователь заходит на страницу — проверить, есть ли у него cookie с токеном и, если нету, попросить его из сервера. Чтобы не создавать собственный велосипед, попробуем использовать существующую библиотеку для работы с cookie. Например, ng2-cookies.
Для этого нам надо установить ее и подключить в компоненте home.
github.com/gbdrm/HabraQuest/commit/8c7aadd9607a0c4d0a1039707b08b0c4b720112c [12]
Сложно описать мои следующие несколько часов упорной борьбы со стереотипами JavaScript и первого Angular. Оказалось, что во второй версии фреймворка все абсолютно иначе. Могу лишь сказать, что закончилось это тем, что я решил пока не использовать сервисы (решил сначала лучше разобраться с rxjs observable, который активно используется в Angular 2), обновил пакеты до следующего релиз кандидата (четвертого), добавил новые формы (оказалось, что они были сильно переделаны и этот процесс еще не закончен) и решил максимально упросить код (большинство логики в одну компоненту). Для начала нужно сделать что-то рабочее, а потом будем думать о хороших практиках. Так же добавил несколько заглушек на серверную часть.
github.com/gbdrm/HabraQuest/commit/60c8239a89cae2357d0521973e091781027186ba [13]
Из интересных особенностей — то ли студия то ли решарпер умеют подтягивать правильные импорты для TypeScript, так же в большинстве случаев работает штатная навигация по методах. Из-за такого рода особенностей писать код для клиентской части становиться значительно приятней, нету больше чувства, что вы пишете какой-то скрипт, который может упасть где угодно. Вместо этого основные элементы синтаксиса проверяются автоматически и есть уверенность, что все не поломается где-то посредине. А даже если и поломается, то выполнится еще одна проверка на уровне webpack и в результате на странице будет показа ошибка, даже без перезапуска.

Правда, иногда, это начинает напрягать, когда после каждого сохранения файла — страница начинает перерисовываться. Но думаю это вопрос привычки.
Весь следующий код не представляет особой важности. В основному это реализация заглушенных моментов. Если вам все же интересно просмотреть — исходники доступны на github.com/gbdrm/HabraQuest [2]
По скольку бек-енд написан на .Net то деплоить наше приложение будем на Azure. Кстати за последние год-полтора тут тоже изменений хоть отбавляй, с первого раза не разберешься что и куда. Для нашего приложения нам достаточно будет создать самый базовый сайт с базой (Web App + SQL).
С деплойментом, как всегда, не очень гладко. Во-первых, он не проходит без ошибок. Сам сайт работает, но в итоге Visual Studio показывает ошибки в каких-то внешних модулях TypeScript. Пока так и не разобрался что это. Во-вторых, бывает, что при открытии сайта вылетает ошибка «TaskCanceledException: A task was canceled». С этим тоже пока не до конца ясно, но похоже проблема где-то на уровне . И кроме этого, немного поигрался с миграциями.
Хотя, в общем, я этим шагом остался доволен. Очень детальный и понятный лог, все можно сконфигурировать (база, миграции). Первый раз, правда, нужно подождать некоторое время (несколько минут) пока все билдится, копируется. Да и вообще, похоже, что процесс довольно сложный, на сколько я понял сначала все копируется локально, а потом уже перебрасывается на Azure, но это уже детали.
Все получилось так, как и планировалось. Новыми фреймворками лично я доволен, с радостью бы на них перешел. Конечно есть еще не очень стабильные моменты, Angular 2 еще и совсем не выпущен официально. Но выглядит все уже довольно интересно и, главное, работает.
Очень радует развитие инструментов, подходов в разработке которые позволяют делать меньше рутинных задач, типа обновления станицы, контролирования структуры базы данных.
Так же, очень много блогов, вопросов, документации в сети, так что с решением типичных задач уже должно быть все просто.
Все результаты можно найти на:
github.com/gbdrm/HabraQuest [2]
habraquest.azurewebsites.net [3]
Получилось довольно сумбурно, так как много разных тем. Какие из них вам наиболее интересны для описания в будущем?
Автор: Gbdrm
Источник [15]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/net/163676
Ссылки в тексте:
[1] прошлый раз: https://habrahabr.ru/post/250009/
[2] сорсы на гитхабе: https://github.com/gbdrm/HabraQuest
[3] линк на квест: http://habraquest.azurewebsites.net/
[4] dotnet.github.io: https://dotnet.github.io/
[5] github.com/aspnet/JavaScriptServices: https://github.com/aspnet/JavaScriptServices/
[6] blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core: http://blog.stevensanderson.com/2016/05/02/angular2-react-knockout-apps-on-aspnet-core/
[7] docs.efproject.net/en/latest/intro.html: https://docs.efproject.net/en/latest/intro.html
[8] github.com/gbdrm/HabraQuest/commit/959f4cb6c253dad0cc5e6eb34756ee5cc9c920f9: https://github.com/gbdrm/HabraQuest/commit/959f4cb6c253dad0cc5e6eb34756ee5cc9c920f9
[9] github.com/gbdrm/HabraQuest/commit/7411eb4262bdef9f5fb810f6cf7d5a239221c0b5: https://github.com/gbdrm/HabraQuest/commit/7411eb4262bdef9f5fb810f6cf7d5a239221c0b5
[10] github.com/gbdrm/HabraQuest/commit/09b42dc0a8e45da1f461b38c2b41d79c4fc0b88a: https://github.com/gbdrm/HabraQuest/commit/09b42dc0a8e45da1f461b38c2b41d79c4fc0b88a
[11] github.com/gbdrm/HabraQuest/commit/e67a322184517aa929d1347f6fd638c6290bf9d3: https://github.com/gbdrm/HabraQuest/commit/e67a322184517aa929d1347f6fd638c6290bf9d3
[12] github.com/gbdrm/HabraQuest/commit/8c7aadd9607a0c4d0a1039707b08b0c4b720112c: https://github.com/gbdrm/HabraQuest/commit/8c7aadd9607a0c4d0a1039707b08b0c4b720112c
[13] github.com/gbdrm/HabraQuest/commit/60c8239a89cae2357d0521973e091781027186ba: https://github.com/gbdrm/HabraQuest/commit/60c8239a89cae2357d0521973e091781027186ba
[14] хостинга: https://www.reg.ru/?rlink=reflink-717
[15] Источник: https://habrahabr.ru/post/306292/?utm_source=habrahabr&utm_medium=rss&utm_campaign=best
Нажмите здесь для печати.