DevGang
Авторизоваться

Angular автомонмный маршрутизатор API

Зададим себе вопрос сколько мы можем вытрясти из связки Routers?

А давайте попробуем и рассмотрим все на примере. Начнем кодировать простое приложение с двумя лениво загружаемыми маршрутами (/movies и /shows), которое нам позволяет составить список фильмов и телепередач.

Вы можете создавать функциональные модули с отложенной загрузкой с помощью простой единственной команды.
Пример приложения, в котором перечислены фильмы и телешоу
Пример приложения, в котором перечислены фильмы и телешоу

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

Давайте сосредоточимся на самой интересной части, которая для этой статьи является размером пакета. 

Отчет о первоначальном размере пакета из обозревателя исходных карт
Отчет о первоначальном размере пакета из обозревателя исходных карт

Все приложение занимает 246,23 КБ, из них 203,17 КБ - оснговной пакет и 65,62 КБ - маршрутизатор. В настоящее время это составляет 26,6% от нашего текущего приложения. 26,6% может показаться много, но это потому, что наше приложение очень тривиально и, следовательно, очень маленькое.

Давайте реорганизуем наше приложение, чтобы использовать автономные API маршрутизатора.

Автономные API-интерфейсы

Перед использованием автономного API мы должны ознакомиться с официальными документами, чтобы понять, как полностью использовать автономные API-маршрутизаторы. 

Angular теперь предоставляет функцию provideRouter. Эта функция позволяет нам предоставить нашему приложению необходимую функциональность маршрутизатора (маршруты и функции маршрутизатора). Сегодня эти функции маршрутизатора предоставляются RouterModule.

Итак, у нас есть возможность обеспечить функциональность маршрутизатора, но как насчет компонентов и директив, таких как router-outlet или routerLink? Как мы их получим? Это довольно просто: мы можем импортировать их. Все компоненты и директивы маршрутизатора теперь доступны как автономные API.

Похоже, что новые API предоставляют все, что нам нужно. Как мы должны использовать функцию provide Router?

Мы можем передать функцию provideRouter в качестве параметра функции bootstrapApplication

const appRoutes: Routes = [];
bootstrapApplication(AppComponent,
  {
    providers: [
      provideRouter(appRoutes,
        withDebugTracing(),
        withRouterConfig({paramsInheritanceStrategy: 'always'}))
    ]
  }
);

Что такое bootstrap Application? В моем приложении мы используем функцию bootstrapModule, предоставляемую функцией platformBrowserDynamic.

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

Означает ли это, что мне нужно изменить свое приложение на автономные компоненты, чтобы воспользоваться функцией provideRouter?

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

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

Гибридный подход

Чтобы воспользоваться преимуществами функции provideRouter, мы должны преобразовать наш AppComponent в автономный компонент, добавив автономное свойство со значением true.

Поскольку в нашем шаблоне используются router-outlet и routerLink, нам дополнительно необходимо импортировать автономные API-интерфейсы RouterOutlet и RouterLinkWithHref.

import { Component } from '@angular/core';
import {RouterLinkWithHref, RouterOutlet} from "@angular/router";

@Component({
  selector: 'app-root',
  templateUrl: './app.component.html',
  styleUrls: ['./app.component.scss'],
  imports: [
    RouterOutlet,
    RouterLinkWithHref
  ],
  standalone: true
})
export class AppComponent {
}

Как только мы преобразовали наш AppComponent в автономный компонент, мы можем удалить app.module.ts и app.routing.module.ts. На данный момент остался только один шаг - настроить файл main.ts.

import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';
import {bootstrapApplication} from "@angular/platform-browser";
import {AppComponent} from "./app/app.component";
import {provideRouter, Routes} from "@angular/router";

const routes: Routes = [
{ path: 'shows', loadChildren: () => import('./app/features/shows/shows.module').then(m => m.ShowsModule) }, 
{ path: 'movies', loadChildren: () => import('./app/features/movies/movies.module').then(m => m.MoviesModule) }
];

if (environment.production) {
  enableProdMode();
}

bootstrapApplication(AppComponent, {
  providers: provideRouter(routes)
})

Мы переместили маршруты из app.routing.module.ts в наш main.ts и скорректировали пути. Затем мы передаем его функции provideRouter в опциях провайдеров функции bootstrapApplication.

Мы успешно использовали некоторые из автономных API маршрутизаторов. Давайте рассмотрим размер пакета нашего приложения. 

Размер пакета нашего приложения, которое теперь использует некоторые автономные API-интерфейсы маршрутизаторов, а также RouterModule.
Размер пакета нашего приложения, которое теперь использует некоторые автономные API-интерфейсы маршрутизаторов, а также RouterModule.

Общий размер приложения уменьшился до 243,08 КБ. Интересная часть заключается в том, что даже общий размер приложения уменьшился, сам маршрутизатор увеличился на 0,13 КБ.

Это потому, что мы теперь используем функцию provideRouter в сочетании RouterModule, который мы еще используем в модулях функций с отложенной загрузкой.

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

Полноценные автономные компоненты

Давайте преобразуем наши модули маршрутизации с отложенной загрузкой в автономные компоненты с отложенной загрузкой. 

Для этого мы сначала удалим файлы  movies.routing.module.ts и movies.module.ts. Далее мы должны преобразовать movies.component.ts в отдельный компонент.

import {Component} from '@angular/core';
import {NgFor} from "@angular/common";

import {MoviesService} from "./movies.service";
import {MovieCardComponent} from "./movie-card/movie-card.component";

@Component({
  selector: 'app-movies',
  templateUrl: './movies.component.html',
  styleUrls: ['./movies.component.scss'],
  standalone: true,
  imports: [MovieCardComponent, NgFor]
})
export class MoviesComponent {

  movies = this.moviesService.getMovies();

  constructor(private moviesService: MoviesService) { }

}

Мы устанавливаем для параметра standalone в декораторе компонентов значение true и добавляем массив imports, содержащий значения  MovieCardComponent и NgFor.

Уже преобразовал компонент видеокарты в отдельный компонент.

Те же шаги должны быть выполнены для маршрута shows. Я полагаю, вы не хотели бы, чтобы снова перечислял из здесь.

После того, как мы преобразовали наши функции в автономные компоненты, нам нужно пересмотреть и реорганизовать маршруты в main.ts, чтобы использовать метод loadComponent вместо loadChildren.

const routes: Routes = [{ path: 'shows', loadComponent: () => import('./app/features/shows/shows.component').then(c => c.ShowsComponent) }, { path: 'movies', loadComponent: () => import('./app/features/movies/movies.component').then(c => c.MoviesComponent) }];

if (environment.production) {
  enableProdMode();
}

bootstrapApplication(AppComponent, {
  providers: [provideRouter(routes)]
})

Как следует из названия loadComponent позволяет нам лениво загружать компонент (автономно) без использования модуля.

Мы успешно преобразовали наше приложение в автономные компоненты. Кроме того, наше приложение больше не использует RouterModule, вместо этого оно теперь использует только автономные API маршрутизаторов.

Давайте снова создадим наше приложение и проверим полученный пакет. 

Размер пакета после преобразования нашего приложения в автономные компоненты и автономные API маршрутизаторов
Размер пакета после преобразования нашего приложения в автономные компоненты и автономные API маршрутизаторов

Общий размер пакета теперь составляет 233,61 КБ. Это общее уменьшение на 12,62 КБ для того же набора функций. Но нас особенно интересует маршрутизатор, 

Размер маршрутизатора теперь составляет 60,54 КБ. Это уменьшение на 5,08 КБ. Это 7,74%. 7,74% соответствуют моему упрощенному варианту использования с использованием source-map-explorer в качестве инструмента измерения. Очень хорошо могу представить, что в более сложных сценариях или, возможно, с другим инструментом измерения вы можете получить до 11%.

Вывод

Новые автономные API-интерфейсы маршрутизаторов просто фантастичны. Они позволяют нам реализовать те же потрясающие функции, что и в случае с пакетами меньшего размера. 

Имейте в виду, что в настоящее время они находятся в предварительном просмотре для разработчиков и будут стабильны в версии 15. Поэтому я не стал бы их использовать сегодня для продуктивного кода. Кроме того, они вынуждают вас использовать автономные компоненты во всем нашем приложении.

В зависимости от размера вашего приложения частичная миграция может быть хорошим способом перевести ваше приложение на автономные API-интерфейсы маршрутизатора. Однако имейте ввиду, что смешивание provideRouter с RouterModule должно быть только промежуточным шагом, а не конечным решением.

#Angular
Комментарии
Чтобы оставить комментарий, необходимо авторизоваться

Присоединяйся в тусовку

В этом месте могла бы быть ваша реклама

Разместить рекламу