03.01.2018 Запуск Angular вместе с ASP.NET Core MVC с нуля

Втупление

Angular - один из самых популярных MVC-фреймворков, созданных компанией Google, для создания клиентских приложений. Сложность в использовании фреймворка Angular оправдывается при создании так называемых одностраничных приложений (SPA-приложений, Single Page Application) Здесь я не буду в подробностях описывать, что собой представляет вышеуказанный фреймворк, а лишь объясню, как с нуля создать проект ASP.NET Core MVC, использующий Angular. При этом, в качестве IDE я буду использовать Visual Studio 2017 Community Edition.

Проще всего начать работу с проектом Angular - это создать проект веб-приложения ASP.NET Core и в качестве шаблона указать Angular, как показано на скриншоте ниже.

Выбор проекта Angular
Создания проекта ASP.NET Core MVC с использованием шаблона Angular

Если при выборе шаблона веб-приложения у вас отсутствует шаблон "Angular", то необходимо установить последнее обновление Visual Studio 2017. О том, как выполнить обновление, можно прочесть на официальном сайте Microsoft. Однако данная статья расскажет, как выполнить подключение фреймворка Angular к проекту ASP.NET Core MVC самостоятельно, без использования шаблонного проекта. Это позволит в тонкостях понять, какую работу от нас скрывает выполнение этого шаблона.

По большей части, эта статья опирается на информацию, взятую из книги Адама Фримена "Essential Angular for ASP.NET Core MVC". Я предполагаю, что у вас уже установлена среда Visual Studio 2017 совместно с .netcore2.0, среда Node.js и система контроля версий Git. О том, как установить все эти компоненты можно без труда найти в интернете.

Проверка и установка Bower

Вначале проверим, установлен ли у нас Bower - пакетный менеджер для веб. Для этого в консоли выполним команду:

npm -v bower

В случае, если Bower у вас не установлен, то выполните команду:

npm install -g bower

Подготовка к созданию проекта

Существует различные способы создания проекта Angular / ASP.NET Core MVC. Описанный в данной статье подход использует пакет @angular/cli совместно с инструментами .NET (.NET tools), которые используются для создания нового проекта ASP.NET Core MVC.

Пакет @angular/cli предоставляет интерфейс командной строки, который упрощает процесс создания и работы с новым проектом Angular. Во время разработки код фреймворка компилируется, упаковывается и предоставляется браузеру используя webpack - распространенный инструмент для создания JavaScript-бандлов (JavaScript bundles), содержащие только код, необходимый для запуска проекта.

Для создания проекта на связке Angular и ASP.NET Core MVC я начну с @angular/cli, а далее - отредактируем конфигурационный файл webpack, который используется для интеграции инструментов и библиотек Angular в ASP.NET Core MVC проект.

Начнем с того, что запустим консоль и установим пакет @angular/cli:

npm install --global @angular/cli@1.0.2

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

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

Процесс создания проекта Angular / ASP.NET Core MVC требует внимания: обе платформы разработки содержат свои собственные инструменты и соглашения, и для того чтобы все заработало вместе, необходимо выполнить определенную последовательность шагов. Далее все эти шаги будут выполнены с пояснениями.

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

На первом шаге создадим новый проект Angular с использованием ранее установленного пакета @angular/cli. Для этого откроем окно консоли и перейдем в директорию, где хранятся ваши разрабатываемые проекты, и запустим команду:

ng new AngularTestApp --skip-git --skip-commit --skip-tests --source-dir ClientApp

Команда ng предоставляется пакетом @angular/cli и создает новый проект на базе Angular. Аргумент, который начинается с --skip инструктирует @angular/cli не выполнять некоторые стандартные шаги настройки, которые обычно включаются в проект. Аргумент --source-dir определяет название директории, которая будет содержать исходный код приложения Angular. Код Angular располагается в директории ClientApp в проекте Angular / ASP.NET Core MVC.

Вышеуказанная команда создает директорию AngularTestApp, которая содержит инструменты и конфигурационные файлы для проекта на базе Angular. Команда ng new загружает большое число пакетов, что может занять длительное время.

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

cd AngularTestApp

Чтобы инструментарий Angular заработал совместно с инструментами .NET необходимо установить дополнительные пакеты npm. Чтобы их установить запустите команду:

npm install --save-dev webpack@2.3.2 aspnet-prerendering@2.0.3 aspnet-webpack@1.0.28 webpack-hot-middleware@2.17.1

Microsoft предоставляет некоторые пакеты npm, которые используются для настройки и запуска инструментов разработчика Angular внутри среды выполнения ASP.NET Core. Эти инструменты работают напрямую с webpack, который обычно скрыт во время работы с проектами, созданными с применением @angular/cli. Запустите команду, показанную ниже, находясь в директории AngularTestApp. Эта команда создаст файл конфигурации webpack, который будет использоваться для сборки и запуска проекта, и называется выпуск (ejecting) проекта из @angular/cli.

ng eject

Процесс выпуска (ejection process) обновляет файл package.json, который используется npm для отслеживания пакетов, используемых в проекте. В некоторых случаях процесс выпуска добавит дополнительные npm-пакеты в файл package.json, поэтому выполните команду, показанную ниже, чтобы убедиться, что новые пакеты загружены и установлены.

npm install

Этой командой мы обновляем пакеты npm.

Создание ASP.NET Core MVC части проекта

После того как мы настроили Angular-проект, на следующем шаге создадим проект ASP.NET Core MVC в той же самой директории AngularTestApp. Выполните команду, показанную ниже, в директории AngularTestApp:

dotnet new mvc --language C# --auth None --framework netcoreapp2.0

Далее, выполните команду, показанную ниже в директории AngularTestApp, чтобы добавить NuGet-пакет, который является дополнением к npm-пакетам, установленными нами ранее. Этот NuGet-пакет используется для интеграции инструментов Angular в Visual Studio.

dotnet add package Microsoft.AspNetCore.SpaServices --version 2.0.1

При желании, можно выполнить команду:

dotnet restore

Эта команда загрузит необходимые пакеты. В принципе, для проекта под Visual Studio для этого нет необходимости, так как сама среда успешно загрузит указанные пакеты.

Настройка проекта

Запустите Visual Studio 2017 и выберите "Файл ? Открыть Решение или проект", перейдите в директорию AngularTestApp и выберите файл AngularTestApp.csproj Далее, выберите "Файл ? Сохранить все" и сохраните файл AngularTestApp.sln, который в дальнейшем можно использовать для открытия проекта. Затем выберите "Проект ? Свойства", перейдите в раздел "Отладка" и убедитесь, что выбран IIS Express в поле "Запустить", как показано на изображении ниже.

Настройка проекта
Настройка проекта

Убедитесь, что отмечен чекбокс "Запустить браузер" и укажите http://localhost:5000 в поле "URL-адрес приложения", как показано на рисунке выше. Затем, при необходимости, добавьте переменную окружения ASPNETCORE_ENVIRONMENT со значением Development. Сохраните изменения и закройте окно свойств проекта.

Создание и редактирование файлов конфигурации

Добавьте файл TypeScript с именем boot.ts в директории AngularTestApp/ClientApp, который содержит следующий код:

import { enableProdMode } from "@angular/core";
import { platformBrowserDynamic } from "@angular/platform-browser-dynamic";
import { AppModule } from "./app/app.module";
const bootApplication = () => {
  platformBrowserDynamic().bootstrapModule(AppModule);
};

if (module["hot"]) {
  module["hot"].accept();
  module["hot"].dispose(() => {
    const oldRootElem = document.querySelector("app-root");
    const newRootElem = document.createElement("app-root");
    oldRootElem.parentNode.insertBefore(newRootElem, oldRootElem);
    platformBrowserDynamic().destroy();
  });
}

if (document.readyState === "complete") {
  bootApplication();
} else {
  document.addEventListener("DOMContentLoaded", bootApplication);
}

Этот файл отвечает за загрузку приложения Angular и отслеживает изменения кода клиентской стороны. Далее, отредактируйте файл Startup.cs и измените код в методе Configure, как показано в листинге ниже. Эти изменения задействуют интеграцию между инструментами разработки ASP.NET Core и Angular.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Threading.Tasks;
using Microsoft.AspNetCore.Builder;
using Microsoft.AspNetCore.Hosting;
using Microsoft.Extensions.Configuration;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.AspNetCore.SpaServices.Webpack;

namespace AngularTestApp
{
    public class Startup
    {
        public Startup(IConfiguration configuration)
        {
            Configuration = configuration;
        }

        public IConfiguration Configuration { get; }

        // This method gets called by the runtime. Use this method to add services to the container.
        public void ConfigureServices(IServiceCollection services)
        {
            services.AddMvc();
        }

        // This method gets called by the runtime. Use this method to configure the HTTP request pipeline.
        public void Configure(IApplicationBuilder app, IHostingEnvironment env)
        {
            app.UseDeveloperExceptionPage();
            app.UseWebpackDevMiddleware(new WebpackDevMiddlewareOptions {
                HotModuleReplacement = true
            });

            //if (env.IsDevelopment())
            //{
            //    app.UseDeveloperExceptionPage();
            //}
            //else
            //{
            //    app.UseExceptionHandler("/Home/Error");
            //}

            app.UseStaticFiles();

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

Далее, откройте файл webpack.config.js в директории AngularTestApp, найдите строку module.exports, показанную в листинге ниже, и внесите изменения. Этот файл содержит много конфигурационных параметров, но тот блок, который необходимо найти, расположен ближе к началу файла.

...
module.exports = {
  "devtool": "source-map",
  "resolve": {
    "extensions": [
      ".ts",
      ".js"
    ],
    "modules": [
      "./node_modules"
    ]
  },
  "resolveLoader": {
    "modules": [
      "./node_modules"
    ]
  },
  "entry": {
    "main": [
      "./ClientApp\\boot.ts"    // меняем имя файла на boot.ts
    ],
    "polyfills": [
      "./ClientApp\\polyfills.ts"
    ],
    "styles": [
      "./ClientApp\\styles.css"
    ]
  },
  "output": {
    "path": path.join(process.cwd(), "wwwroot/dist"),   // меняем путь на "wwwroot/dist"
    "filename": "[name].bundle.js",
    "chunkFilename": "[id].chunk.js",
    "publicPath": "/app/"   // добавляем строку "publicPath": "/app/"
  },
...

Обновление пакета Bootstrap

Чтобы обновить версию пакета Bootstrap, что используется в проекте, создайте файл bower.json в директории AngularTestApp со следующим содержимым:

{
  "name": "asp.net",
  "private": true,
  "dependencies": {
    "bootstrap": "4.0.0-alpha.6",
    "jquery": "2.2.0",
    "jquery-validation": "1.14.0",
    "jquery-validation-unobtrusive": "3.2.6"
  }
}

Сохраните файл. Visual Studio загрузит и установит указанные пакеты.

Некоторые файлы в проекте можно удалить. Ниже приведены эти файлы.

  • .editorconfig - этот файл содержит настройки текстового редактора, специфические для проекта и он используется Visual Studio для переопределения настроек, заданных в меню Средства ? Параметры, включая настройки размера табуляции в два пробела;
  • e2e - эта директория содержит тесты для Protractor, который осуществляет полное тестирование приложений на Angular;
  • protractor.conf.js - файл конфигурации Protractor;
  • README.md - файл содержит обзор инструментария @angular/cli.

Обновление контроллера, файла макета (Layout) и представления

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

using Microsoft.AspNetCore.Mvc;

namespace AngularTestApp.Controllers
{
    public class HomeController : Controller
    {
        public IActionResult Index()
        {
            return View();
        }
    }
}

Отредактируйте файл _Layout.cshtml в директории Views/Shared и замените его содержимое на следующее:

<!DOCTYPE html>
<html>
<head>
    <meta charset="utf-8" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>SportsStore @ViewData["Title"]</title>
    <link rel="stylesheet" href="~/lib/bootstrap/dist/css/bootstrap.css" />
</head>
<body>
    @RenderBody()
    @RenderSection("Scripts", required: false)
</body>
</html>

Отредактируйте файл Index.cshtml в директории Views/Home и замените его содержимое на следующее:

@section scripts {
    <script src="~/dist/inline.bundle.js" asp-append-version="true"></script>
    <script src="~/dist/polyfills.bundle.js" asp-append-version="true"></script>
    <script src="~/dist/vendor.bundle.js" asp-append-version="true"></script>
    <script src="~/dist/main.bundle.js" asp-append-version="true"></script>
}
<div class="navbar bg-inverse">
    <a class="navbar-brand text-white">@(ViewBag.Message ?? "Angular Test Application")</a>
</div>
<div class="p-1">
    <app-root></app-root>
</div>

Элементы script в этом представлении включают бандлы (связки) файлов JavaScript, которые содержат фреймворк Angular и клиентский код приложения. Бандлы будут созданы автоматически инструментом webpack, когда файлы в Angular-части проекта будут изменены.

Элемент app-root будет заменен динамическим содержимым, созданным приложением Angular. Остальные элементы - это обычный HTML, стилизованный с помощью Bootstrap.

Запуск проекта

Теперь запустите проект из Visual Studio. Отроется новое окно браузера с адресом http://localhost:5000, что является тем самым URL, который мы настроили ранее. Если все прошло успешно, то вы увидите страницу, как показано на изображении ниже.

Запуск веб-приложения Angular
Запуск веб-приложения Angular

Если по каким-либо причинам у вас страница отличается от указанной, то вы можете, находясь в директории AngularTestApp, запустить веб-сервер из командной строки с помощью команды:

dotnet run

После запуска произойдет сборка проекта и запустится ASP.NET Core HTTP сервер. При этом в консоли вы можете отслеживать ошибки. Например, во время создания данного примера, я забыл создать файл boot.ts и с помощью сообщений в консоли установил причину неработоспособности Angular части проекта:

Module not found: Error: Can't resolve './ClientApp\boot.ts' in 'd:\Stas\src\Visual Studio 2017\AngularTestApp'