Usare il modello di progetto per Angular con ASP.NET CoreUse the Angular project template with ASP.NET Core

Il modello di progetto aggiornato per Angular fornisce un ottimo punto di partenza per le app ASP.NET Core che usano Angular e l'interfaccia della riga di comando di Angular per implementare un'interfaccia utente avanzata sul lato client.The updated Angular project template provides a convenient starting point for ASP.NET Core apps using Angular and the Angular CLI to implement a rich, client-side user interface (UI).

Il modello è equivalente alla creazione di un progetto ASP.NET Core che opera come un back-end API e un progetto per l'interfaccia della riga di comando di Angular che opera come un'interfaccia utente.The template is equivalent to creating an ASP.NET Core project to act as an API backend and an Angular CLI project to act as a UI. Il modello offre la praticità di ospitare entrambi i tipi di progetto in un singolo progetto di app.The template offers the convenience of hosting both project types in a single app project. Di conseguenza, il progetto di app può essere compilato e pubblicato come una singola unità.Consequently, the app project can be built and published as a single unit.

Creare una nuova appCreate a new app

Se ASP.NET Core 2.1 è installato, non è necessario installare il modello di progetto Angular.If you have ASP.NET Core 2.1 installed, there's no need to install the Angular project template.

Creare un nuovo progetto da un prompt dei comandi usando il comando dotnet new angular in una directory vuota.Create a new project from a command prompt using the command dotnet new angular in an empty directory. Ad esempio, i comandi seguenti creano l'app in una directory my-new-app e passano a tale directory:For example, the following commands create the app in a my-new-app directory and switch to that directory:

dotnet new angular -o my-new-app
cd my-new-app

Eseguire l'app da Visual Studio o dall'interfaccia della riga di comando di .NET Core:Run the app from either Visual Studio or the .NET Core CLI:

Aprire il file con estensione csproj generato ed eseguire l'app come di consueto da tale posizione.Open the generated .csproj file, and run the app as normal from there.

Alla prima esecuzione, il processo di compilazione ripristina le dipendenze di npm. Tale operazione può richiedere alcuni minuti.The build process restores npm dependencies on the first run, which can take several minutes. Le compilazioni successive sono molto più veloci.Subsequent builds are much faster.

Il modello di progetto crea un'app ASP.NET Core e un'app Angular.The project template creates an ASP.NET Core app and an Angular app. L'app ASP.NET Core è destinata all'uso per l'accesso ai dati, l'autorizzazione e altri elementi sul lato server.The ASP.NET Core app is intended to be used for data access, authorization, and other server-side concerns. L'app Angular, disponibile nella sottodirectory ClientApp, è destinata all'uso per tutti gli aspetti relativi all'interfaccia utente.The Angular app, residing in the ClientApp subdirectory, is intended to be used for all UI concerns.

Aggiungere pagine, immagini, stili, moduli e così via.Add pages, images, styles, modules, etc.

La directory ClientApp contiene un'app standard per l'interfaccia della riga di comando di Angular.The ClientApp directory contains a standard Angular CLI app. Per altre informazioni, vedere la documentazione ufficiale di Angular.See the official Angular documentation for more information.

Vi sono piccole differenze tra l'app Angular creata tramite questo modello e quella creata tramite l'interfaccia della riga di comando di Angular stessa (mediante ng new). Le funzionalità dell'app restano comunque invariate.There are slight differences between the Angular app created by this template and the one created by Angular CLI itself (via ng new); however, the app's capabilities are unchanged. L'app creata tramite il modello contiene un layout basato su bootstrap e un esempio di routing di base.The app created by the template contains a Bootstrap-based layout and a basic routing example.

Eseguire i comandi ngRun ng commands

In un prompt dei comandi passare alla sottodirectory ClientApp:In a command prompt, switch to the ClientApp subdirectory:

cd ClientApp

Se si dispone dello strumento ng installato globalmente, è possibile eseguire i relativi comandi.If you have the ng tool installed globally, you can run any of its commands. Ad esempio, è possibile eseguire ng lint, ng test o qualsiasi altro comando dell'interfaccia della riga di comando di Angular.For example, you can run ng lint, ng test, or any of the other Angular CLI commands. Non è tuttavia necessario eseguire ng serve, poiché l'app ASP.NET Core si occupa della gestione sia delle parti sul lato server che di quelle sul lato client dell'app.There's no need to run ng serve though, because your ASP.NET Core app deals with serving both server-side and client-side parts of your app. Internamente, usa ng serve in fase di sviluppo.Internally, it uses ng serve in development.

Se lo strumento ng non è installato, eseguire npm run ng.If you don't have the ng tool installed, run npm run ng instead. Ad esempio, è possibile eseguire npm run ng lint o npm run ng test.For example, you can run npm run ng lint or npm run ng test.

Installa nuovi pacchetti npmInstall npm packages

Per installare i pacchetti npm di terze parti, usare un prompt dei comandi nella sottodirectory ClientApp.To install third-party npm packages, use a command prompt in the ClientApp subdirectory. Ad esempio:For example:

cd ClientApp
npm install --save <package_name>

Pubblicare e distribuirePublish and deploy

In fase di sviluppo, l'app viene eseguita in una modalità ottimizzata per gli sviluppatori.In development, the app runs in a mode optimized for developer convenience. Ad esempio, i bundle JavaScript includono il mapping di origine, in modo da poter visualizzare il codice TypeScript originale durante il debug.For example, JavaScript bundles include source maps (so that when debugging, you can see your original TypeScript code). L'app controlla le modifiche dei file TypeScript, HTML e CSS su disco, quindi esegue automaticamente la ricompilazione e il ricaricamento quando rileva modifiche dei file.The app watches for TypeScript, HTML, and CSS file changes on disk and automatically recompiles and reloads when it sees those files change.

Nell'ambiente di produzione usare una versione dell'app ottimizzata per le prestazioni.In production, serve a version of your app that's optimized for performance. Questo comportamento è configurato per l'esecuzione automatica.This is configured to happen automatically. Quando si esegue la pubblicazione, la configurazione della build genera una compilazione minimizzata AOT (Ahead Of Time) del codice sul lato client.When you publish, the build configuration emits a minified, ahead-of-time (AoT) compiled build of your client-side code. A differenza della build di sviluppo, la compilazione di produzione non richiede l'installazione di node. js nel server (a meno che non sia stato abilitato il rendering lato server (SSR)).Unlike the development build, the production build doesn't require Node.js to be installed on the server (unless you have enabled server-side rendering (SSR)).

È possibile usare i metodi standard di hosting e distribuzione di ASP.NET Core.You can use standard ASP.NET Core hosting and deployment methods.

Eseguire "ng serve" in modo indipendenteRun "ng serve" independently

Il progetto è configurato in modo da avviare in background la propria istanza del server dell'interfaccia della riga di comando di Angular all'avvio dell'app ASP.NET Core in modalità di sviluppo.The project is configured to start its own instance of the Angular CLI server in the background when the ASP.NET Core app starts in development mode. Ciò risulta utile in quanto evita di dover eseguire manualmente un server distinto.This is convenient because you don't have to run a separate server manually.

Questa configurazione predefinita presenta tuttavia uno svantaggio.There's a drawback to this default setup. Ogni volta che si modifica il codice C# ed è necessario riavviare l'app ASP.NET Core, il server dell'interfaccia della riga di comando di Angular viene riavviato.Each time you modify your C# code and your ASP.NET Core app needs to restart, the Angular CLI server restarts. Per avviare il backup sono necessari circa 10 secondi.Around 10 seconds is required to start back up. Se si apportano frequentemente modifiche al codice C# e non si vuole attendere il riavvio dell'interfaccia della riga di comando di Angular, eseguire il server dell'interfaccia della riga di comando di Angular esternamente, in modo indipendente dal processo ASP.NET Core.If you're making frequent C# code edits and don't want to wait for Angular CLI to restart, run the Angular CLI server externally, independently of the ASP.NET Core process. A tale scopo:To do so:

  1. In un prompt dei comandi passare alla sottodirectory ClientApp e avviare il server di sviluppo dell'interfaccia della riga di comando di Angular:In a command prompt, switch to the ClientApp subdirectory, and launch the Angular CLI development server:

    cd ClientApp
    npm start
    

    Importante

    Usare npm start per avviare il server di sviluppo dell'interfaccia della riga di comando di Angular, anziché ng serve, in modo che la configurazione in package.json venga rispettata.Use npm start to launch the Angular CLI development server, not ng serve, so that the configuration in package.json is respected. Per passare parametri aggiuntivi al server dell'interfaccia della riga di comando di Angular, aggiungerli alla riga appropriata scripts nel file package.json.To pass additional parameters to the Angular CLI server, add them to the relevant scripts line in your package.json file.

  2. Modificare l'app ASP.NET Core in modo da usare l'istanza dell'interfaccia della riga di comando di Angular esterna anziché avviarne una autonomamente.Modify your ASP.NET Core app to use the external Angular CLI instance instead of launching one of its own. Nella classe Startup sostituire la chiamata spa.UseAngularCliServer con quanto segue:In your Startup class, replace the spa.UseAngularCliServer invocation with the following:

    spa.UseProxyToSpaDevelopmentServer("http://localhost:4200");
    

All'avvio dell'app ASP.NET Core, questa non avvierà un server dell'interfaccia della riga di comando di Angular.When you start your ASP.NET Core app, it won't launch an Angular CLI server. Verrà invece usata l'istanza che è stata avviata manualmente.The instance you started manually is used instead. Ciò consente di velocizzare l'avvio e il riavvio.This enables it to start and restart faster. Non è più necessario attendere che l'app client venga ricompilata ogni volta dall'interfaccia della riga di comando di Angular.It's no longer waiting for Angular CLI to rebuild your client app each time.

Passare dati dal codice .NET nel codice TypeScriptPass data from .NET code into TypeScript code

Durante il rendering lato server, potrebbe essere necessario passare dati per ogni richiesta dall'app ASP.NET Core nell'app Angular.During SSR, you might want to pass per-request data from your ASP.NET Core app into your Angular app. Ad esempio, è possibile passare informazioni sui cookie o dati letti da un database.For example, you could pass cookie information or something read from a database. A tale scopo, modificare la classe Startup.To do this, edit your Startup class. Nel callback per UseSpaPrerendering, impostare un valore per options.SupplyData come il seguente:In the callback for UseSpaPrerendering, set a value for options.SupplyData such as the following:

options.SupplyData = (context, data) =>
{
    // Creates a new value called isHttpsRequest that's passed to TypeScript code
    data["isHttpsRequest"] = context.Request.IsHttps;
};

Il callback SupplyData consente di passare dati arbitrari serializzabili con JSON per ogni richiesta, ad esempio stringhe, valori booleani o numeri.The SupplyData callback lets you pass arbitrary, per-request, JSON-serializable data (for example, strings, booleans, or numbers). Il codice main.server.ts riceve questi dati come params.data.Your main.server.ts code receives this as params.data. Ad esempio, l'esempio di codice precedente passa un valore booleano come params.data.isHttpsRequest nel callback createServerRenderer.For example, the preceding code sample passes a boolean value as params.data.isHttpsRequest into the createServerRenderer callback. È possibile passare questo valore ad altre parti dell'app in qualsiasi modo supportato da Angular.You can pass this to other parts of your app in any way supported by Angular. Ad esempio, si osservi come main.server.ts passa il valore BASE_URL a qualsiasi componente il cui costruttore viene dichiarato per la relativa ricezione.For example, see how main.server.ts passes the BASE_URL value to any component whose constructor is declared to receive it.

Svantaggi del rendering lato serverDrawbacks of SSR

Non tutte le app traggono vantaggio dal rendering lato server.Not all apps benefit from SSR. Il vantaggio principale è rappresentato dalle prestazioni percepite.The primary benefit is perceived performance. I visitatori che raggiungono l'app tramite una connessione di rete lenta o da dispositivi mobili lenti vedono l'interfaccia utente iniziale rapidamente, anche se occorre un certo tempo per recuperare o analizzare i bundle JavaScript.Visitors reaching your app over a slow network connection or on slow mobile devices see the initial UI quickly, even if it takes a while to fetch or parse the JavaScript bundles. Tuttavia, molte applicazioni a pagina singola sono usate principalmente in reti aziendali interne, su computer veloci in cui l'app viene visualizzata quasi istantaneamente.However, many SPAs are mainly used over fast, internal company networks on fast computers where the app appears almost instantly.

Allo stesso tempo, l'abilitazione del rendering lato server presenta alcuni svantaggi significativi.At the same time, there are significant drawbacks to enabling SSR. Aumenta la complessità del processo di sviluppo.It adds complexity to your development process. Il codice deve essere eseguito in due diversi ambienti: lato client e lato server (in un ambiente Node.js richiamato da ASP.NET Core).Your code must run in two different environments: client-side and server-side (in a Node.js environment invoked from ASP.NET Core). Di seguito sono illustrati alcuni aspetti da tenere presente:Here are some things to bear in mind:

  • Il rendering lato server richiede un'installazione di Node.js nei server di produzione.SSR requires a Node.js installation on your production servers. Ciò avviene automaticamente per alcuni scenari di distribuzione, ad esempio Servizio app di Azure, ma non per altri, come Azure Service Fabric.This is automatically the case for some deployment scenarios, such as Azure App Services, but not for others, such as Azure Service Fabric.

  • L'abilitazione del flag di compilazione BuildServerSideRenderer determina la pubblicazione della directory node_modules.Enabling the BuildServerSideRenderer build flag causes your node_modules directory to publish. Questa cartella contiene oltre 20.000 file, che aumentano il tempo di distribuzione.This folder contains 20,000+ files, which increases deployment time.

  • Per eseguire il codice in un ambiente Node.js, non è possibile basarsi sull'esistenza di API JavaScript specifiche del browser, come window o localStorage.To run your code in a Node.js environment, it can't rely on the existence of browser-specific JavaScript APIs such as window or localStorage. Se il codice (o una libreria di terze parti a cui si fa riferimento) tenta di usare queste API, verrà visualizzato un errore durante il rendering lato server.If your code (or some third-party library you reference) tries to use these APIs, you'll get an error during SSR. Ad esempio, non usare jQuery perché fa riferimento ad API specifiche del browser in numerose posizioni.For example, don't use jQuery because it references browser-specific APIs in many places. Per evitare errori, è necessario non usare il rendering lato server o evitare API o librerie specifiche del browser.To prevent errors, you must either avoid SSR or avoid browser-specific APIs or libraries. È possibile eseguire il wrapping di tutte le chiamate a tali API nei controlli per assicurarsi che non vengano richiamate durante il rendering lato server.You can wrap any calls to such APIs in checks to ensure they aren't invoked during SSR. Nel codice JavaScript o TypeScript, ad esempio, usare un controllo simile al seguente:For example, use a check such as the following in JavaScript or TypeScript code:

    if (typeof window !== 'undefined') {
        // Call browser-specific APIs here
    }
    

Risorse aggiuntiveAdditional resources