Angular от Google: как появился и как начать первый проект

Angular от Google: как появился и как начать первый проект Полезное

Angular появился в Google в сентябре 2016 года как полностью переписанный на TypeScript наследник AngularJS — фреймворка на JavaScript, который вырос из проекта 2009 года и вышел публично в 2010-м. От предшественника осталось имя: Angular — это фреймворк для веб-приложений с компонентами и компиляцией шаблонов, а учебные материалы по AngularJS к нему не подходят.

Ниже — короткая история появления, что нужно знать до старта и пошаговый первый проект: установка Node.js и Angular CLI, ng new, структура файлов и свой компонент. Все команды и вывод проверены на Angular CLI 22.2.0 и Node.js 24 (24 сентября 2026 года).

Как появился Angular: от AngularJS до Angular 22

В 2009 году Мишко Хевери и Адам Абронс начали проект, который превратился в AngularJS. Хевери работал в Google, и фреймворк стал развиваться там как open source. Идея была смелой для того времени: описывать поведение страницы прямо в HTML-разметке, а синхронизацию данных и интерфейса отдать фреймворку (двусторонняя привязка).

Когда приложения выросли, у AngularJS проявились пределы производительности и архитектуры. Команда Google не стала латать старый код, а написала фреймворк заново: на TypeScript, с компонентами вместо контроллеров и с компиляцией шаблонов. Так появился Angular 2, после которого цифру из названия убрали.

Год Событие
2009 Начало проекта, который станет AngularJS
2010 Первый публичный релиз AngularJS
2016, сентябрь Angular 2.0: полная переработка на TypeScript
2017, март Angular 4: версию 3 пропустили, чтобы выровнять номера пакетов
2020, февраль Angular 9: компилятор и рантайм Ivy по умолчанию
2021, 31 декабря Окончание поддержки AngularJS
2023, май Angular 16: сигналы (в режиме developer preview)
2023, ноябрь Angular 17: встроенный синтаксис @if/@for, сайт angular.dev, standalone-проекты по умолчанию
2025, ноябрь Angular 21: новые проекты без zone.js, Vitest как тест-раннер по умолчанию
2026, июнь Angular 22 (на сентябрь 2026 актуальна 22.2)

Для новичка из этой истории важен практический вывод. Мажорная версия выходит примерно раз в полгода, поэтому статьи и видео быстро стареют. Если в примере есть NgModule в каждом файле, standalone: true или *ngIf, это код предыдущих поколений: он еще встречается в рабочих проектах, но новый проект CLI генерирует иначе.

Что нужно знать перед стартом

Angular требует больше подготовки, чем «подключить скрипт на страницу». Минимальный набор такой:

Что знать Зачем в Angular Достаточный минимум
HTML и CSS Шаблоны и стили компонентов Теги, атрибуты, селекторы
JavaScript Логика компонентов Функции, объекты, классы, модули import/export, стрелочные функции
TypeScript Основной язык Angular Типы, интерфейсы, классы, модификаторы доступа
Терминал и npm Установка, запуск, сборка Переход по папкам, npm install, запуск команд

TypeScript — надмножество JavaScript с типами. Отдельный курс по нему до Angular не обязателен: достаточно уверенного JavaScript и базовых типов, остальное осваивается по ходу.

Шаг 1. Установить Node.js и Angular CLI

Angular CLI — утилита командной строки ng: создает проект, генерирует компоненты, запускает dev-сервер, сборку и тесты. Работает она на Node.js, поэтому сначала нужен Node.js (npm ставится вместе с ним).

Angular CLI 22.2 требует Node.js версии 22.22.3+, 24.15.0+ или 26+. Надежный выбор — актуальная LTS-ветка, на сентябрь 2026 это Node.js 24. Проверьте версии и установите CLI глобально:

node -v
npm -v
npm install -g @angular/cli
ng version

В выводе ng version должны быть строки с версиями CLI и Node.js, в нашем прогоне так:

Angular CLI       : 22.2.0
Node.js           : 24.21.0
Package Manager   : npm 11.19.0

Если Node.js старше требуемого, CLI не запустится и прямо назовет минимальные версии (вывод на Node.js 20):

Node.js version v20.20.2 detected.
The Angular CLI requires a minimum Node.js version of v22.22.3 or v24.15.0 or v26.0.0.

Шаг 2. Создать проект командой ng new

ng new hello-angular --defaults
cd hello-angular
ng serve

Флаг --defaults принимает настройки по умолчанию: CSS для стилей, без серверного рендеринга. Без него CLI задаст несколько вопросов (формат стилей, нужен ли SSR, для каких AI-инструментов создать конфигурацию) — на старте можно отвечать по умолчанию. После создания CLI сам выполнит npm install, это занимает минуту-две.

ng serve запускает dev-сервер и печатает адрес http://localhost:4200/. Откройте его в браузере: появится стартовая страница с заголовком «Hello, hello-angular». Сервер следит за файлами и пересобирает приложение при каждом сохранении.

Структура проекта: что сгенерировал CLI

Файлов много, но на старте работать приходится с несколькими:

Файл или папка Для чего
src/index.html Единственная HTML-страница, в ней тег <app-root>
src/main.ts Точка входа: bootstrapApplication(App, appConfig) запускает корневой компонент
src/app/app.ts Корневой компонент App (класс + декоратор @Component)
src/app/app.html, app.css Шаблон и стили корневого компонента
src/app/app.config.ts Провайдеры приложения: роутер, обработчик ошибок и т.п.
src/app/app.routes.ts Таблица маршрутов, сначала пустая
src/styles.css Глобальные стили
public/ Статика: favicon, картинки
angular.json Настройки сборки, dev-сервера и тестов
package.json Зависимости и скрипты start, build, test

Цепочка запуска такая: браузер загружает index.html -> скрипт из main.ts запускает компонент App -> Angular находит в странице тег <app-root> (это selector компонента) и рендерит в него шаблон app.html.

Шаг 3. Первый компонент

Компонент — это класс TypeScript с декоратором @Component, который связывает класс с шаблоном и CSS. Удобная аналогия: компонент — это свой HTML-тег со своей логикой. Создадим его генератором:

ng generate component greeting

CLI создаст папку src/app/greeting/ с четырьмя файлами: greeting.ts, greeting.html, greeting.css и тестом greeting.spec.ts. Заменим содержимое класса и шаблона.

// src/app/greeting/greeting.ts
import { Component, input, signal, computed } from '@angular/core';

@Component({
  selector: 'app-greeting',
  templateUrl: './greeting.html',
  styleUrl: './greeting.css',
})
export class Greeting {
  // Входной параметр: <app-greeting name="Otus" />
  readonly name = input('мир');

  // Состояние компонента - сигнал
  protected readonly clicks = signal(0);

  // Производное значение пересчитывается само
  protected readonly label = computed(() =>
    this.clicks() === 0 ? 'Еще не нажимали' : `Нажатий: ${this.clicks()}`
  );

  protected increment(): void {
    this.clicks.update((n) => n + 1);
  }
}
<!-- src/app/greeting/greeting.html -->
<h2>Привет, {{ name() }}!</h2>
<button type="button" (click)="increment()">Нажми меня</button>
<p>{{ label() }}</p>
@if (clicks() >= 3) {
  <p class="hint">Три нажатия - компонент работает.</p>
}

Теперь подключим компонент в корневой: импортируем класс и перечислим его в imports, а в шаблоне используем тег. Сгенерированный app.ts импортирует еще RouterOutlet для тега <router-outlet />; маршрутов пока нет и стартовый шаблон заменяется целиком, поэтому здесь RouterOutlet убран вместе с этим тегом.

// src/app/app.ts
import { Component, signal } from '@angular/core';
import { Greeting } from './greeting/greeting';

@Component({
  selector: 'app-root',
  imports: [Greeting],
  templateUrl: './app.html',
  styleUrl: './app.css',
})
export class App {
  protected readonly title = signal('hello-angular');
}
<!-- src/app/app.html: заменяем стартовую страницу целиком -->
<h1>Hello, {{ title() }}</h1>
<app-greeting name="Otus" />

Ожидаемый результат в браузере: заголовок «Hello, hello-angular», под ним «Привет, Otus!», кнопка и строка «Еще не нажимали». После первого нажатия строка сменится на «Нажатий: 1», после третьего появится подсказка «Три нажатия — компонент работает.».

Что здесь происходит:

  • selector: 'app-greeting' — имя тега, по которому Angular находит место для компонента;
  • input('мир') — входной параметр со значением по умолчанию; атрибут name="Otus" передает строку;
  • signal(0) — реактивное значение: читается вызовом clicks(), меняется через set или update, и Angular обновляет только зависящие от него места шаблона;
  • computed — значение, вычисляемое из других сигналов, пересчитывается при их изменении;
  • {{ ... }} — интерполяция, (click) — привязка к событию, @if — встроенный условный блок шаблона.

Сигналы и @if — современный стиль Angular. В проектах, начатых до 2023 года, то же самое пишут через обычные поля класса и директиву *ngIf — оба варианта работают, но новый код лучше писать в текущем стиле.

Типичная ошибка: компонент не подключен в imports

Если добавить тег <app-greeting> в шаблон, но забыть imports: [Greeting] в app.ts, сборка (ng build или ng serve) упадет:

✘ [ERROR] NG8001: 'app-greeting' is not a known element:
1. If 'app-greeting' is an Angular component, then verify that it is included in the '@Component.imports' of this component.

Исправление — то, что подсказывает сам текст ошибки: импортировать класс Greeting в app.ts и добавить его в массив imports декоратора. Каждый компонент перечисляет в imports все компоненты и директивы, которые использует его шаблон.

Проверка компонента тестом

CLI создал проект с тест-раннером Vitest. Тест ниже проверяет то же, что вы видели в браузере: имя, счетчик и появление подсказки.

// src/app/greeting/greeting.spec.ts
import { TestBed } from '@angular/core/testing';
import { Greeting } from './greeting';

describe('Greeting', () => {
  it('показывает имя и считает нажатия', async () => {
    const fixture = TestBed.createComponent(Greeting);
    fixture.componentRef.setInput('name', 'Otus');
    await fixture.whenStable();

    const el: HTMLElement = fixture.nativeElement;
    expect(el.querySelector('h2')?.textContent).toBe('Привет, Otus!');
    expect(el.querySelector('p')?.textContent).toBe('Еще не нажимали');

    const button = el.querySelector('button')!;
    button.click();
    button.click();
    button.click();
    await fixture.whenStable();

    expect(el.querySelector('p')?.textContent).toBe('Нажатий: 3');
    expect(el.querySelector('.hint')).not.toBeNull();
  });
});
ng test --watch=false
 ✓ |hello-angular| src/app/app.spec.ts (2 tests)
 ✓ |hello-angular| src/app/greeting/greeting.spec.ts (1 test)
 Test Files  2 passed (2)
      Tests  3 passed (3)

Порядок строк с файлами тестов может меняться от запуска к запуску: Vitest выполняет их параллельно. Обратите внимание: стандартный app.spec.ts проверяет, что заголовок содержит «Hello, hello-angular». Если заменить <h1> в app.html на свой текст, этот тест упадет с AssertionError — поправьте ожидание в тесте вместе с шаблоном.

Если не получилось

Симптом Причина Что сделать
ng: command not found CLI не установлен глобально или npm-папка не в PATH Запускать через npx ng ... внутри проекта или переустановить CLI
The Angular CLI requires a minimum Node.js version Устаревший Node.js Поставить актуальную LTS-версию Node.js
NG8001: '...' is not a known element Компонент не добавлен в imports Импортировать класс и добавить в imports
Port 4200 is already in use Порт занят другим процессом ng serve --port 4300
Страница пустая, в консоли браузера ошибка Ошибка в коде компонента Открыть DevTools (F12) -> Console, прочитать первую ошибку

Выводы

  • Angular (с 2016 года, TypeScript) и AngularJS (с 2010 года, JavaScript) — разные фреймворки; поддержка AngularJS закончилась 31 декабря 2021 года.
  • Мажорные версии Angular выходят примерно раз в полгода; на сентябрь 2026 актуальна ветка 22, и учебник стоит сверять с версией.
  • Для старта нужны HTML, CSS, уверенный JavaScript, основы TypeScript и Node.js актуальной LTS-версии.
  • Первый проект — это npm install -g @angular/cli, ng new, ng serve и ng generate component; компонент подключается через imports родителя.
  • Современный код Angular — standalone-компоненты, сигналы и встроенные блоки @if/@for.

Где применяется / связь с практикой

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

Освойте тему на практике

Пройти этот путь системно, с проектами и ревью кода, можно на курсе «Angular-разработчик». Чтобы сначала посмотреть на формат обучения, подойдут бесплатные открытые уроки Otus.

FAQ

Можно ли писать на Angular без TypeScript?
Практически нет: CLI, документация и компилятор шаблонов рассчитаны на TypeScript. Старые варианты с Dart или чистым JavaScript больше не поддерживаются.

Нужно ли учить AngularJS перед Angular?
Нет. AngularJS — отдельный фреймворк, поддержка которого завершена 31 декабря 2021 года; знать о нем стоит, только если предстоит поддерживать или мигрировать старый проект.

Как обновить существующий проект до новой версии Angular?
Командой ng update @angular/core @angular/cli по одной мажорной версии за раз; она обновляет пакеты и запускает миграции кода.

OTUS Журнал
Бесплатные открытые уроки (поп-ап)