Angular IDPStrong Junior
🔥 0

Модуль 2 · урок 1 з 15

CLI і структура проєкту

Перш ніж писати компоненти, треба розуміти, що саме створює ng new і навіщо кожен файл. Це нудна частина, яку всі проскакують — і потім бояться чіпати конфіги. Пройдемо її один раз, щоб більше не боятись.

Створити проєкт

# CLI можна не ставити глобально — npx візьме останню версію
npx @angular/cli@latest new studio-ops --style=scss --ssr=false

# що спитає майстер:
#   Which stylesheet format? → SCSS   (лід просить SCSS або BEM)
#   Enable SSR/SSG? → No              (нам потрібен звичайний SPA)
#   Zoneless? → Yes                   (сучасний режим, деталі в модулі 3)

Далі три команди, які ти запускатимеш щодня:

ng serve            # підняти дев-сервер на localhost:4200 з гарячою перезбіркою
ng build             # зібрати продакшн-бандл у dist/
ng test              # прогнати юніт-тести (модуль 8)
ng lint              # перевірити ESLint (нам це знадобиться в уроці про any)

Що всередині

studio-ops/
├─ src/
│  ├─ app/
│  │  ├─ app.ts             — кореневий компонент застосунку
│  │  ├─ app.html           — його шаблон
│  │  ├─ app.scss           — його стилі
│  │  ├─ app.config.ts      — провайдери на весь застосунок
│  │  └─ app.routes.ts      — маршрути
│  ├─ main.ts               — точка входу: піднімає застосунок
│  ├─ index.html            — єдина HTML-сторінка (це ж SPA)
│  └─ styles.scss           — глобальні стилі: сюди йдуть токени з модуля 1
├─ angular.json             — конфіг збірки: шляхи, бюджети, ассети
├─ tsconfig.json            — налаштування TypeScript, зокрема strict
└─ package.json             — залежності й скрипти

main.ts — три рядки, з яких усе починається

import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { App } from './app/app';

bootstrapApplication(App, appConfig);

Раніше тут був NgModule з platformBrowserDynamic().bootstrapModule(AppModule). Сучасний спосіб коротший: беремо кореневий компонент і конфіг із провайдерами. Модулі нікуди не зникли, але в новому коді їх майже не пишуть — і саме тому в уроці про DI ми говоритимемо про providers, а не про NgModule.

app.config.ts — місце, де вмикають можливості

import { ApplicationConfig, provideZonelessChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient } from '@angular/common/http';
import { routes } from './app.routes';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZonelessChangeDetection(),  // як застосунок помічає зміни (модуль 3)
    provideRouter(routes),             // маршрутизація (урок 6)
    provideHttpClient(),               // HTTP-клієнт (модуль 4)
  ],
};

Запам'ятай цей шаблон: усе, що вмикається «на весь застосунок», прописується тут функцією з префіксом provide…. Коли в модулі 4 знадобиться інтерсептор, а в модулі 6 — анімації, ти повернешся саме сюди.

Генерація файлів

Руками файли не створюють — CLI зробить це з правильними іменами й у правильному стилі:

ng generate component features/tasks/task-list
ng g c features/tasks/task-list           # те саме, коротко

ng g service core/api/task-api            # сервіс
ng g pipe shared/pipes/due-in             # пайп
ng g directive shared/directives/overdue  # директива
ng g guard core/guards/role               # guard
ng g interface core/models/task           # інтерфейс

ng g c features/tasks/task-list --dry-run # показати, що буде, але не створювати
Структура папок, яку впізнає будь-який лід

core/ — те, що існує в одному екземплярі на застосунок: сервіси даних, guards, інтерсептори, моделі. shared/ — те, що перевикористовується: пайпи, директиви, дрібні компоненти без бізнес-логіки. features/ — папка на кожен екран або розділ, усередині компоненти саме цієї фічі.

Це не догма, але це стандарт, який усі читають однаково. Якщо на робочому проєкті інакше — роби як там, але вміти пояснити цю схему варто.

angular.json: три речі, які справді доводиться правити

{
  "projects": {
    "studio-ops": {
      "architect": {
        "build": {
          "options": {
            "styles": ["src/styles.scss"],        // глобальні стилі
            "assets": [{ "glob": "**/*", "input": "public" }],
            "stylePreprocessorOptions": {
              "includePaths": ["src/styles"]       // щоб @use 'tokens' працював без ../../
            }
          },
          "configurations": {
            "production": {
              "budgets": [                          // збірка впаде, якщо бандл розпухне
                { "type": "initial", "maximumError": "1mb" }
              ]
            }
          }
        }
      }
    }
  }
}

Бюджети — приємна дрібниця, про яку варто знати: якщо хтось випадково затягне важку бібліотеку, збірка впаде з поясненням, а не просто стане повільною.

tsconfig.json: те, заради чого цей модуль існує

{
  "compilerOptions": {
    "strict": true,                         // вмикає одразу групу перевірок
    "noImplicitOverride": true,
    "noPropertyAccessFromIndexSignature": true,
    "noImplicitReturns": true,
    "noFallthroughCasesInSwitch": true
  },
  "angularCompilerOptions": {
    "strictTemplates": true,                // перевірка типів ще й у шаблонах
    "strictInjectionParameters": true
  }
}

Ці прапорці стоять у нових проєктах за замовчуванням — головне їх не вимкнути, коли щось «не компілюється». Що саме кожен із них ловить, розберемо в уроці про strict.

Що варто зробити одразу
  • Перенести токени з модуля 1 у src/styles/ і підключити в styles.scss.
  • Створити папки core, shared, features.
  • Перевірити, що strict і strictTemplates увімкнені.
  • Зробити перший коміт: chore: bootstrap angular project.
Чого не робити
  • Не вимикати strict, щоб «поки що працювало».
  • Не тягнути UI-бібліотеку на старті — модуль 1 просив свої компоненти.
  • Не створювати файли руками замість ng g.
  • Не класти все в одну папку app/ без структури.