00
:
00
:
00
:
00
Corso SEO AI - Usa SEOEMAIL al checkout per il 30% di sconto

Struttura del Progetto

Panoramica della Struttura

Quando si crea un nuovo progetto con ng new, Angular CLI genera una struttura di cartelle ben organizzata. Comprendere ogni file e cartella è fondamentale per lavorare efficacemente.

mia-app/
├── node_modules/
├── src/
│   ├── app/
│   │   ├── app.component.ts
│   │   ├── app.component.html
│   │   ├── app.component.scss
│   │   ├── app.component.spec.ts
│   │   ├── app.config.ts
│   │   └── app.routes.ts
│   ├── assets/
│   ├── environments/
│   │   ├── environment.ts
│   │   └── environment.prod.ts
│   ├── index.html
│   ├── main.ts
│   └── styles.scss
├── angular.json
├── package.json
├── tsconfig.json
├── tsconfig.app.json
├── tsconfig.spec.json
└── README.md

File di Root

main.ts

Il file main.ts è il punto di ingresso dell’applicazione. Qui viene effettuato il bootstrap dell’applicazione.

// Approccio standalone (Angular 17+)
import { bootstrapApplication } from '@angular/platform-browser';
import { appConfig } from './app/app.config';
import { AppComponent } from './app/app.component';

bootstrapApplication(AppComponent, appConfig)
  .catch((err) => console.error(err));

Con l’approccio basato su NgModules (versioni precedenti):

// Approccio NgModule (legacy)
import { platformBrowserDynamic } from '@angular/platform-browser-dynamic';
import { AppModule } from './app/app.module';

platformBrowserDynamic()
  .bootstrapModule(AppModule)
  .catch((err) => console.error(err));

index.html

Il file HTML principale che ospita l’applicazione Angular:

<!DOCTYPE html>
<html lang="it">
<head>
  <meta charset="utf-8">
  <title>MiaApp</title>
  <base href="/">
  <meta name="viewport" content="width=device-width, initial-scale=1">
  <link rel="icon" type="image/x-icon" href="favicon.ico">
</head>
<body>
  <app-root></app-root>
</body>
</html>

Il tag <app-root> è il selettore del componente root dell’applicazione. Angular sostituisce questo tag con il template del componente principale.

styles.scss

Il file di stili globali dell’applicazione. Gli stili definiti qui si applicano a tutti i componenti:

// styles.scss - Stili globali
@import 'variables';

* {
  margin: 0;
  padding: 0;
  box-sizing: border-box;
}

body {
  font-family: 'Segoe UI', Tahoma, sans-serif;
  line-height: 1.6;
  color: #333;
}

La Cartella app/

app.config.ts

Il file di configurazione principale dell’applicazione (approccio standalone):

import { ApplicationConfig, provideZoneChangeDetection } from '@angular/core';
import { provideRouter } from '@angular/router';
import { provideHttpClient, withInterceptors } from '@angular/common/http';
import { provideAnimationsAsync } from '@angular/platform-browser/animations/async';
import { routes } from './app.routes';
import { authInterceptor } from './interceptors/auth.interceptor';

export const appConfig: ApplicationConfig = {
  providers: [
    provideZoneChangeDetection({ eventCoalescing: true }),
    provideRouter(routes),
    provideHttpClient(withInterceptors([authInterceptor])),
    provideAnimationsAsync()
  ]
};

app.routes.ts

Il file di definizione delle rotte dell’applicazione:

import { Routes } from '@angular/router';

export const routes: Routes = [
  { path: '', redirectTo: 'home', pathMatch: 'full' },
  {
    path: 'home',
    loadComponent: () =>
      import('./pages/home/home.component').then(m => m.HomeComponent)
  },
  {
    path: 'prodotti',
    loadComponent: () =>
      import('./pages/prodotti/prodotti.component').then(m => m.ProdottiComponent)
  },
  { path: '**', redirectTo: 'home' }
];

app.component.ts

Il componente root dell’applicazione:

import { Component } from '@angular/core';
import { RouterOutlet } from '@angular/router';
import { HeaderComponent } from './components/header/header.component';
import { FooterComponent } from './components/footer/footer.component';

@Component({
  selector: 'app-root',
  standalone: true,
  imports: [RouterOutlet, HeaderComponent, FooterComponent],
  template: `
    <app-header />
    <main>
      <router-outlet />
    </main>
    <app-footer />
  `,
  styleUrl: './app.component.scss'
})
export class AppComponent {
  titolo = 'mia-app';
}

Approccio NgModule (Legacy)

Per i progetti che utilizzano ancora NgModules, la struttura include app.module.ts:

// app.module.ts
import { NgModule } from '@angular/core';
import { BrowserModule } from '@angular/platform-browser';
import { HttpClientModule } from '@angular/common/http';
import { AppRoutingModule } from './app-routing.module';
import { AppComponent } from './app.component';

@NgModule({
  declarations: [AppComponent],
  imports: [
    BrowserModule,
    HttpClientModule,
    AppRoutingModule
  ],
  providers: [],
  bootstrap: [AppComponent]
})
export class AppModule {}

Cartella Environments

La cartella environments/ contiene i file di configurazione per ambienti diversi.

// environments/environment.ts (sviluppo)
export const environment = {
  production: false,
  apiUrl: 'http://localhost:3000/api',
  debugMode: true,
  sentryDsn: ''
};
// environments/environment.prod.ts (produzione)
export const environment = {
  production: true,
  apiUrl: 'https://api.miaapp.it/api',
  debugMode: false,
  sentryDsn: 'https://xxx@sentry.io/123'
};

L’uso nei servizi:

import { Injectable } from '@angular/core';
import { HttpClient } from '@angular/common/http';
import { environment } from '../../environments/environment';

@Injectable({ providedIn: 'root' })
export class ApiService {
  private baseUrl = environment.apiUrl;

  constructor(private http: HttpClient) {}

  getProdotti() {
    return this.http.get(`${this.baseUrl}/prodotti`);
  }
}

La sostituzione dei file viene configurata in angular.json:

"configurations": {
  "production": {
    "fileReplacements": [
      {
        "replace": "src/environments/environment.ts",
        "with": "src/environments/environment.prod.ts"
      }
    ]
  }
}

Cartella Assets

La cartella assets/ contiene file statici come immagini, font, file JSON e altro che vengono copiati nella build finale senza modifiche.

src/assets/
├── images/
│   ├── logo.svg
│   └── hero-banner.jpg
├── fonts/
│   └── custom-font.woff2
├── i18n/
│   ├── it.json
│   └── en.json
└── data/
    └── config.json

Per includere file o cartelle aggiuntive nella build, configurali in angular.json:

"assets": [
  "src/favicon.ico",
  "src/assets",
  {
    "glob": "**/*",
    "input": "node_modules/libreria/assets",
    "output": "/assets/libreria"
  }
]

Struttura Consigliata per Progetti Grandi

Per applicazioni enterprise, una struttura ben organizzata è fondamentale:

src/app/
├── core/                    # Servizi singleton, guard, interceptor
│   ├── guards/
│   │   └── auth.guard.ts
│   ├── interceptors/
│   │   └── auth.interceptor.ts
│   ├── services/
│   │   ├── auth.service.ts
│   │   └── notification.service.ts
│   └── models/
│       ├── utente.model.ts
│       └── prodotto.model.ts
├── shared/                  # Componenti, direttive, pipe riutilizzabili
│   ├── components/
│   │   ├── bottone/
│   │   ├── card/
│   │   └── modale/
│   ├── directives/
│   │   └── evidenzia.directive.ts
│   └── pipes/
│       └── tronca.pipe.ts
├── features/                # Moduli feature (pagine/sezioni)
│   ├── home/
│   │   ├── home.component.ts
│   │   ├── home.component.html
│   │   └── home.component.scss
│   ├── prodotti/
│   │   ├── lista-prodotti/
│   │   ├── dettaglio-prodotto/
│   │   └── services/
│   │       └── prodotti.service.ts
│   └── admin/
│       ├── dashboard/
│       └── gestione-utenti/
├── layouts/                 # Layout dell'applicazione
│   ├── main-layout/
│   └── admin-layout/
├── app.component.ts
├── app.config.ts
└── app.routes.ts

Principi di organizzazione

// core/models/utente.model.ts
export interface Utente {
  id: number;
  nome: string;
  cognome: string;
  email: string;
  ruolo: 'admin' | 'utente' | 'moderatore';
}

// core/services/auth.service.ts
@Injectable({ providedIn: 'root' })
export class AuthService {
  // Servizio singleton disponibile ovunque
}

// shared/components/bottone/bottone.component.ts
@Component({
  selector: 'app-bottone',
  standalone: true,
  template: `
    <button [class]="variante" [disabled]="disabilitato">
      <ng-content />
    </button>
  `
})
export class BottoneComponent {
  @Input() variante: 'primario' | 'secondario' = 'primario';
  @Input() disabilitato = false;
}

Best Practices

  • Separa il codice in core, shared e features per una chiara organizzazione
  • I servizi singleton vanno nel modulo core con providedIn: 'root'
  • I componenti riutilizzabili vanno nella cartella shared
  • Ogni feature dovrebbe essere auto-contenuta con i propri componenti e servizi
  • Usa il lazy loading per le feature route per ridurre il bundle iniziale
  • Mantieni i file di configurazione degli ambienti separati e non committare mai segreti
  • Segui una naming convention consistente: nome-componente.component.ts, nome-servizio.service.ts
  • Utilizza barrel exports (index.ts) per semplificare gli import nelle cartelle condivise