Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 1.

Моя основная работа связанна с разработкой программ для встроенных систем и утилит, которые их обслуживают. Но мне всегда нравился Web и технологии связанные с ним. Мое знакомство с Web программированием началось давно, а первым серверным языком был старый и ужасный ASP. Это тот, который на Visual Basic. После этого был PHP и Perl. Ни один из них мне не нравился. У каждого были свои проблемы и до идеальной платформы разработки Web приложений они явно не дотягивали (PHP тоже не айс, хотя он и широко используется для самых разных проектов). А еще мне всегда нравилась платформа Windows. Поэтому появление ASP.NET было просто как божий дар для меня – платформа для разработки Web приложений, ориентирован на Windows IIS и при помощи моего любимого языка C# с мощной поддержкой в лице .NET Framework.

Но через некоторое время стало понятно, что Web Pages – тоже не лучшее решение для легковесных и быстрых сайтов и онлайн сервисов. PageState, неправильный HTML и перегруженные мегабайтами страницы плохо подходят для быстрого web сервиса. Для корпоративного сегмента – да, это было приемлемо, но для простых веб сайтов эта технология проигрывала более быстрым и простым технологиям на основе Linux платформы.

Но хорошие вещи случаются, и Microsoft выпускает ASP.NET MVC. Именно этот фреймворк стал моим любимым инструментом для разработки web сервисов и web сайтов. ASP.NET MVC – это простой и понятный паттерн MVC, чистый код разделенный по контроллерам, отделенное представление от основного кода (Views), чистый HTML, легко подключаемые client-side библиотеки, легко тестируемый код и все та же мощь .NET Framework. Несколько рабочие web сервисов были написаны и до сих пор неплохо работают именно на этой платформе.

Но время идет, а я все отстаю от него. Некоторое время назад стали очень популярны одностраничные веб приложения (SPA – Single Page Application). Они работают намного быстрее чем многостраничные, они используют RESTful API, предоставляет интеграцию с другими сервисами через это API и они нравятся пользователям и заказчикам. И вот, наблюдая, как в очередной раз загружается новая страница в моем сервисе, я понял — пора переходить на новый уровень. Нужно изучить одностраничные приложения. Для отправной точки в этом путешествии к постижению дзен SPA я решил остановиться на такой связке: ASP.NET MVC Core (основа для серверной части) + Angular 4 (JavaScript Framework для реализации быстрого UI на стороне пользователя в виде SPA ).

Так почему Angular, а не другой фреймворк или набор библиотек, таких как Knockout, Ember, ReactJS, Redux и другие? После долгого листания интернета и чтения достоинств и недостатков самых популярных библиотек и фреймворков я решил, что начну с Angular, так как последняя версия этого фреймворка достаточно хороша и дает все что нужно прямо из коробки. У нее есть свои минусы, но я готов с ними смириться. Кроме того Angular очень хорошо развивается, имеет большое сообщество и хорошую документацию, так что изучать его будет намного проще. Но это мое субъективное мнение. В любом случае выбор сделан, давайте начнем кодить!

Создание проекта

Тут можно скачать архив с законченным Visual Studio 2017 проектом ASP.NET MVC Core + Angular SPA

Первое с чего стоит начать – с создание нового проекта ASP.NET MVC Core.
Выбираем в главном меню File -> New -> Project …
В открывшемся окне в левой части выбираем Templates -> Visual C# -> Web.

Создаем новый ASP.NET MVC Core проект

Создаем новый ASP.NET MVC Core проект

В списке проектов выбираем ASP.NET Core Web Application (.NET Core)

Я выбрал имя проекта как AgularSpa. Оставил отмеченными чекбоксы Create directory for solution и Create new Git repository.
Нажимаем ОК.

Создаем новый ASP.NET MVC Core проект

Создаем новый ASP.NET MVC Core проект

В новом окне настроек все оставляем по умолчанию. Тип приложения — Web Application, No Authentication. Нажимаем ОК.
После непродолжительного времени получаем новенький проект.

Visual Studio с новым проектом

Visual Studio с новым проектом

Нажимаем Ctrl+F5 и запускаем наш проект. По умолчанию проект используем IIS Express и после сборки откроется в вашем браузере по умолчанию.

Вид по умолчанию нового приложения ASP.NET MVC Core

Вид по умолчанию нового приложения ASP.NET MVC Core

Добавим в наш проект Angular Quick Start Application

Теперь перейдем к следующему шагу – скачаем Angular Quick Start Application с официального туториала по Angular и поместим его в наше ASP.NET Core приложение.
Если вам нужно подтянуть свои знания по Angular – то вам на официальный сайт Angular. Там есть отличный туториал.
Для начала сделаем копию Angular Quick Start Application из репозитория Git. Открываем командную строку и запускаем следующую команды:


cd c:\Temp 
git clone https://github.com/angular/quickstart

 

Clone Angular Quickstart Application

Clone Angular Quickstart Application

В результате мы получим в папке c:\Temp\quickstart файлы Angular проекта.

Файлы приложения Angular Quickstart

Файлы приложения Angular Quickstart

Теперь откроем эту папку и скопируем нужные нам файлы в наш проект. Файлы можно просто перетаскивать мышкой из папки в Windows Explorer прямиком в окно Solution в Visual Studio 2017.

Копирование файлов Angular Quickstart Application

Копирование файлов Angular Quickstart Application

Копирование файлов Angular Quickstart Application

Копирование файлов Angular Quickstart Application

Так выглядит проект перед копированием файлов.

Вид проекта перед копированием Angular Quickstart Application файлов

Вид проекта перед копированием Angular Quickstart Application файлов

Так выглядит проект после копирования новых файлов.

Вид проекта после скопированных Angular Quickstart Application файлов

Вид проекта после скопированных Angular Quickstart Application файлов

Теперь нужно отредактировать файл package.json. Этот файл нужен для настройки пакетов, которые используются проектом. Этот файл будет обрабатываться пакетным менеджером NPM.
В итоге у вас должно остаться следующая конфигурация:

{
  "dependencies": {
    "@angular/common": "~4.0.0",
    "@angular/compiler": "~4.0.0",
    "@angular/core": "~4.0.0",
    "@angular/forms": "~4.0.0",
    "@angular/http": "~4.0.0",
    "@angular/platform-browser": "~4.0.0",
    "@angular/platform-browser-dynamic": "~4.0.0",
    "@angular/router": "~4.0.0",

    "angular-in-memory-web-api": "~0.3.0",
    "systemjs": "0.19.40",
    "core-js": "^2.4.1",
    "rxjs": "5.0.1",
    "zone.js": "^0.8.4"
  },
  "devDependencies": {
    "typescript": "~2.1.0",
    "tslint": "^3.15.1"
  },
  "repository": {}
}

Следующий файл который нужно отредактировать, это tsconfig.json. Это файл который конфигурирует TypeScript приложение. После редактирования файл должен быть таким:

{
  "compilerOptions": {
    "diagnostics": true,
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "lib": [ "es2015", "dom" ],
    "listFiles": true,
    "module": "commonjs",
    "moduleResolution": "node",
    "noImplicitAny": true,
    "outDir": "app",
    "removeComments": false,
    "rootDir": "app",
    "sourceMap": true,
    "suppressImplicitAnyIndexErrors": true,
    "target": "es5"
  },
  "exclude": [
    "node_modules"
  ]
}

Так как расположение файлов немного изменилось, относительно начальной структуры в Angular Quickstart приложении, то нужно подправить пути в файле wwwroot/app/main.ts
Строчку кода

import { AppModule } from './app/app.module';

заменяем на

import { AppModule } from './app.module';

И последние, прежде чем запустить процесс компиляции нам нужно удалить один TypeScript файл — app.component.spec.ts. Этот файл используется для тестов. Так как я не собираюсь запускать тесты, то его нужно удалить. Этот файл находится в папке wwwroot/app/
Теперь можно собрать приложение и в результате Visual Studio скомпилирует *.ts файлы в готовые *.js файлы, которые будут соответствовать стандарту ES5. *.js файлы будут загружаться в браузер, *.js.map файлы будут использоваться для отладки, когда ошибка в *.js будет связана с кодом в TypeScript файле.

Скомпилированные файлы TypeScript

Скомпилированные файлы TypeScript

Прежде чем мы сможем открыть Angular приложение, нам нужно скопировать еще пару файлов из quickstart проекта в наш проект. Это файлы index.html и styles.css. Скопировать их нужно в папку wwwroot. index.html — это статический файл, который будет агружен в браузер. Так же он имеет минимальную разметку для Angular приложения и подключает все необходимые файлы. Styles.css – набор стилей. Он используется внутри index.html.

Сейчас уже можно запустить приложение (нажмите F5) и открыть страницу Angular примера. Для этого нужно открыть в браузере файл index.html. Как видите, пока загружается только статический HTML, а сам Angular не работает.

Первый результат

Первый результат

Если открыть консоль разработчика, то будет видно, что некоторые файлы не подгрузились.

Некоторые файлы не подгружаются

Некоторые файлы не подгружаются

Ожидается, что файлы библиотек будут загружаться из wwwroot/node_modules, но они фактически находятся в корне проекта. Это не очевидно, пока вы не включите опцию Show All Files.

Опция для отображения всех файлов в папке проекта

Опция для отображения всех файлов в папке проекта

Как только вы включите эту опцию, вы увидите папку, выделенную серым цветом, чтобы указать, что она не является частью проекта, но добавлена в папку проекта.

Вид проекта вместе со скрытыми папками и файлами

Вид проекта вместе со скрытыми папками и файлами

Скрытые папки и файлы можно спрятать снова (просто выключив опцию Show All Files). Теперь нужно исправить проблему с расположением библиотечных файлов. Самый простой способ – установить NuGet пакет Microsoft.AspNetCore.SpaServicesusing. Открываем консоль для управления пакетами NuGet.

Открытие консоли NuGet

Открытие консоли NuGet

Теперь запустим команду для установки пакета

Install-Package Microsoft.AspNetCore.SpaServices
Установка пакета NuGet SpaServices

Установка пакета NuGet SpaServices

Далее снова нужно немножко поправить код. Открываем файл Startup.cs. Нас интересует метод

public void Configure(IApplicationBuilder app, IHostingEnvironment env, ILoggerFactory loggerFactory)

Этот метод вызывается средой выполнения что бы сконфигурировать конвеер обработки HTTP запросов. Находим код:

app.UseStaticFiles();

app.UseMvc(routes =>
{
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
});

И заменяем этот код на такой:

app.UseDefaultFiles();
app.UseStaticFiles();
app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules")), RequestPath = "/node_modules"
});

app.UseMvc(routes =>
{
    routes.MapRoute(
    name: "default",
    template: "{controller=Home}/{action=Index}/{id?}");
    routes.MapSpaFallbackRoute("spa-fallback", new { controller = "home", action = "index" });
});
app.UseDefaultFiles();

Этот вызов позволяет web серверу возвращать клиенту файл по умолчанию (index.html для примера). Т.е. он конфигурирует доступность фалов по умолчанию для URL, которые ведут в корень web сайта.

app.UseStaticFiles();

Этот вызов позволяет отдавать web серверу файлы с папки /wwwroot (без указания папки wwwroot в самом URL конечно).

app.UseStaticFiles(new StaticFileOptions
{
    FileProvider = new PhysicalFileProvider(Path.Combine(env.ContentRootPath, "node_modules")), RequestPath = "/node_modules"
});

Этот вызов конфигурирует доступность статических файлов из папки /node_modules. Т.е. если на сервер будет послан запрос типа /node_modules/zone.js то сервер будет искать статический файл в папке /node_modules а не в папке /wwwroot/node_modules (как это включается по умолчанию).
Кроме того, не забудьте добавить эти строчки в начале файла:

using Microsoft.Extensions.FileProviders;
using System.IO;

Эти пространства имен нужны для PhysicalFileProvider и Path классов.
Далее нам нужно отредактировать файл index.html

Заменим эту строчку кода

System.import('main.js').catch(function(err){ console.error(err); });

На эту:

System.import('app/main.js').catch(function(err){ console.error(err); });

Так как мы переместили файл main.ts из корневой папки в папку /app то нужно просто отредактировать путь к этому фалу.
Теперь можно сохранить все файлы и запустить проект. После запуска вы должны увидеть страничку index.html (так как после наших манипуляций в файле Startup.cs файл /wwwroot/index.html выигрывает у пути по умолчанию). И на этой страничке уже должен работать Angular! Именно он пишет текст Hello Angular!

Наконец работающие Angular Quickstart Application

Наконец работающие Angular Quickstart Application

Исходный код

Тут можно скачать архив с Visual Studio 2017 проектом ASP.NET MVC Core + Angular SPA

Все части серии

Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 1 [читаете сейчас].
Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 2.
Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 3.
Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 4.
Single Page Application : ASP.NET MVC .NET Core + Angular 4. Часть 5.
Single Page Application : ASP.NET MVC .NET Core 2 + Angular 5. Часть 6.

Добавить комментарий

Ваш e-mail не будет опубликован.