JavaRush /Курсы /Модуль 4: Node.js, Next.js и Angular /Создание сервиса через CLI: ...

Создание сервиса через CLI: ng generate service

Модуль 4: Node.js, Next.js и Angular
15 уровень , 2 лекция
Открыта

1. Зачем нужен Angular CLI для создания сервисов

В мире Angular есть две категории людей: те, кто любит делать всё вручную (создавать файлы, писать boilerplate-код, называть всё своими именами), и те, кто предпочитает, чтобы за них работал робот. Если вы относитесь ко второй категории (а это очень разумно!), Angular CLI — ваш лучший друг.

Angular CLI — это мощная утилита командной строки, которая помогает автоматизировать рутину: создавать компоненты, сервисы, модули, пайпы и многое другое. С помощью CLI можно не только сэкономить время, но и избежать типичных опечаток, ошибок в структуре файлов и других "человеческих" проблем.

Создание сервиса через CLI — это:

  • Быстро.
  • Безопасно (CLI не даст вам назвать файл не по правилам).
  • Удобно (CLI сразу добавит нужные аннотации и boilerplate-код).
  • Гарантирует, что ваш сервис будет совместим с системой DI Angular.

Синтаксис команды ng generate service

Для создания сервиса через CLI используется команда:

ng generate service имя_сервиса

или, что короче и чаще встречается:

ng g s имя_сервиса

Здесь:
- ng — это команда запуска Angular CLI.
- generate (или коротко g) — действие "создать".
- service (или коротко s) — тип создаваемого артефакта.
- имя_сервиса — имя вашего будущего сервиса (в формате kebab-case, то есть через дефис).

Пример:

ng generate service user

или

ng g s user

В результате Angular CLI создаст два файла:

  • user.service.ts — сам сервис.
  • user.service.spec.ts — файл для unit-тестов (его можно не использовать, если вы пока не пишете тесты).

2. Как работает команда на практике

Давайте рассмотрим процесс пошагово на примере создания сервиса для работы с пользователями (user).

Запуск команды

Откройте терминал в корне вашего Angular-проекта и выполните:

ng g s user

Результат выполнения

В консоли вы увидите примерно следующее:

CREATE src/app/user.service.ts (138 bytes)
CREATE src/app/user.service.spec.ts (352 bytes)

В папке src/app/ появятся два новых файла. Если вы хотите, чтобы сервис лежал в поддиректории (например, services), укажите путь:

ng g s services/user

В результате файлы окажутся в src/app/services/.

Содержимое сгенерированного сервиса

Откройте файл user.service.ts. Вот что там будет по умолчанию:

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

@Injectable({
  providedIn: 'root'
})
export class UserService {
  constructor() { }
}

Обратите внимание на аннотацию @Injectable с параметром { providedIn: 'root' }. Это значит, что сервис будет доступен как синглтон на уровне всего приложения (область видимости — "root"). Подробнее о разных областях видимости мы поговорим позднее, а пока просто помните: это самый частый и рекомендуемый вариант.

3. Параметры команды ng generate service

Angular CLI позволяет гибко настраивать создание сервисов с помощью различных параметров. Вот самые полезные из них:

--flat

По умолчанию CLI создаёт для сервиса отдельную папку (например, user/), а в ней — файлы сервиса и теста. Если вы хотите, чтобы файлы лежали прямо в указанной папке, используйте флаг --flat:

ng g s user --flat

Теперь файлы появятся в src/app/, а не в src/app/user/.

--skip-tests

Если вы не хотите создавать файл для тестов (например, пока вы не планируете их писать), добавьте флаг --skip-tests:

ng g s user --skip-tests

В этом случае будет создан только user.service.ts.

--module

Иногда бывает нужно, чтобы сервис автоматически регистрировался в определённом модуле (например, если вы не хотите использовать providedIn: 'root'). Для этого есть опция --module:

ng g s shared/logger --module=app

CLI попытается найти файл модуля (app.module.ts) и добавить туда ваш сервис (в секцию providers). Однако с появлением providedIn: 'root' это используется редко.

Все параметры

Посмотреть все доступные опции можно командой:

ng g s --help

4. Практика: создание сервиса для учебного приложения

Пусть в нашем учебном приложении есть список задач (tasks), и нам нужен сервис для работы с этим списком.

Создаём сервис

Выполните в терминале:

ng g s services/task --skip-tests

В результате появится файл src/app/services/task.service.ts со следующим содержимым:

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

@Injectable({
  providedIn: 'root'
})
export class TaskService {
  constructor() { }
}

Добавляем методы в сервис

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

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

@Injectable({
  providedIn: 'root'
})
export class TaskService {
  private tasks: string[] = [];

  constructor() { }

  getTasks(): string[] {
    return this.tasks;
  }

  addTask(task: string) {
    this.tasks.push(task);
  }

  removeTask(index: number) {
    this.tasks.splice(index, 1);
  }
}

Теперь сервис умеет возвращать список задач, добавлять и удалять задачи по индексу.

Используем сервис в компоненте

В каком-нибудь компоненте (например, task-list.component.ts), внедрите сервис через конструктор:

import { Component } from '@angular/core';
import { TaskService } from '../services/task.service';

@Component({
  selector: 'app-task-list',
  template: `
    <ul>
      <li *ngFor="let task of getTasks(); let i = index">
        {{ task }}
        <button (click)="removeTask(i)">Удалить</button>
      </li>
    </ul>
    <input [(ngModel)]="newTask" placeholder="Новая задача">
    <button (click)="addTask()">Добавить</button>
  `
})
export class TaskListComponent {
  newTask = '';

  constructor(private taskService: TaskService) {}

  getTasks() {
    return this.taskService.getTasks();
  }

  addTask() {
    if (this.newTask.trim()) {
      this.taskService.addTask(this.newTask);
      this.newTask = '';
    }
  }

  removeTask(index: number) {
    this.taskService.removeTask(index);
  }
}

Внимание: Не забудьте подключить FormsModule в вашем модуле, чтобы работало двустороннее связывание через [(ngModel)].

5. Особенности и нюансы генерации сервисов через CLI

Именование сервисов

CLI всегда добавляет к имени файла суффикс .service.ts. Если вы создаёте сервис с именем user, файл будет называться user.service.ts а класс — UserService.

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

Рекомендуется группировать сервисы в отдельную папку (services/), особенно если их много. Это улучшает навигацию по проекту.

providedIn: 'root'

Сервис, созданный через CLI, по умолчанию становится синглтоном — один экземпляр на всё приложение. Если вы хотите, чтобы сервис был доступен только в определённом модуле, можно изменить параметр на providedIn: SomeModule или добавить сервис в секцию providers нужного модуля.

Автоматизация и масштабирование

CLI — это не только про скорость, но и про стандартизацию. Если в команде 5 разработчиков, CLI поможет всем создавать сервисы одинаково, без сюрпризов и "творческих" трактовок структуры файлов.

6. Типичные ошибки при создании сервисов через CLI

Ошибка №1: Неправильное имя сервиса.
CLI автоматически добавляет суффикс service. Если вы введёте ng g s user.service, получится файл user.service.service.ts, а это уже перебор даже для любителей многословности.

Ошибка №2: Не та папка.
Если запускать команду не из корня проекта, а из поддиректории, путь может оказаться неожиданным. Всегда проверяйте, где вы стоите перед запуском команды — или указывайте путь явно.

Ошибка №3: Забыли --skip-tests, а тесты не нужны.
CLI создаёт тестовый файл по умолчанию. Если вы не планируете его использовать, лучше сразу добавить флаг --skip-tests, чтобы не захламлять проект.

Ошибка №4: Ручное редактирование сгенерированного boilerplate-кода.
Не удаляйте аннотацию @Injectable или параметр providedIn: 'root', если не понимаете, зачем это делаете. Без этого Angular не сможет корректно внедрять сервис.

Ошибка №5: Несогласованность структуры.
Если часть сервисов лежит в src/app/, а часть — в src/app/services/, проект быстро превращается в лабиринт. Лучше выбрать одну стратегию и придерживаться её.

Комментарии
ЧТОБЫ ПОСМОТРЕТЬ ВСЕ КОММЕНТАРИИ ИЛИ ОСТАВИТЬ КОММЕНТАРИЙ,
ПЕРЕЙДИТЕ В ПОЛНУЮ ВЕРСИЮ