Модуль 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/без структури.