Integrare un SPA integrate-spa
Comprendere come il codice sorgente per un’applicazione a pagina singola (SPA) scritto in Angular può essere integrato con un progetto Adobe Experience Manager (AEM). Scopri come utilizzare strumenti front-end moderni, come un server di sviluppo Webpack, per sviluppare rapidamente l’SPA contro l’API modello JSON dell’AEM.
Obiettivo
- Comprendere come il progetto SPA viene integrato con l’AEM con le librerie lato client.
- Scopri come utilizzare un server di sviluppo locale per lo sviluppo front-end dedicato.
- Esplora l'utilizzo di un file proxy e di un file fittizio statico per lo sviluppo con l'API del modello JSON AEM
Cosa verrà creato
Questo capitolo aggiungerà un semplice componente Header
all'SPA. Nel processo di creazione di questo componente Header
statico vengono utilizzati diversi approcci allo sviluppo dell'SPA AEM.
L'SPA è stato esteso per aggiungere un componente Header
statico
Prerequisiti
Esaminare gli strumenti e le istruzioni necessari per configurare un ambiente di sviluppo locale.
Ottieni il codice
-
Scarica il punto di partenza per questa esercitazione tramite Git:
code language-shell $ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/integrate-spa-start
-
Distribuisci la base di codice in un’istanza AEM locale utilizzando Maven:
code language-shell $ mvn clean install -PautoInstallSinglePackage
Se utilizzi AEM 6.x, aggiungi il profilo
classic
:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
Puoi sempre visualizzare il codice finito su GitHub o estrarre il codice localmente passando al ramo Angular/integrate-spa-solution
.
Approccio all’integrazione integration-approach
Nel progetto AEM sono stati creati due moduli: ui.apps
e ui.frontend
.
Il modulo ui.frontend
è un progetto webpack che contiene tutto il codice sorgente SPA. La maggior parte dello sviluppo e dei test dell’SPA viene effettuata nel progetto webpack. Quando viene attivata una build di produzione, l’SPA viene generato e compilato utilizzando Webpack. Gli artefatti compilati (CSS e JavaScript) vengono copiati nel modulo ui.apps
che viene quindi distribuito nel runtime AEM.
Rappresentazione di alto livello dell'integrazione SPA.
Ulteriori informazioni sulla build front-end sono disponibili qui.
Integrazione di Inspect con l’SPA inspect-spa-integration
Esaminare quindi il modulo ui.frontend
per comprendere l'SPA generato automaticamente dall'archetipo progetto AEM.
-
Nell’IDE che preferisci, apri il progetto AEM per l’SPA WKND. Questa esercitazione utilizzerà l'IDE codice di Visual Studio.
-
Espandere ed esaminare la cartella
ui.frontend
. Apri il fileui.frontend/package.json
-
Sotto
dependencies
dovresti vedere diversi relativi a@angular
:code language-json "@angular/animations": "~9.1.11", "@angular/common": "~9.1.11", "@angular/compiler": "~9.1.11", "@angular/core": "~9.1.11", "@angular/forms": "~9.1.10", "@angular/platform-browser": "~9.1.10", "@angular/platform-browser-dynamic": "~9.1.10", "@angular/router": "~9.1.10",
Il modulo
ui.frontend
è un'applicazione Angular generata utilizzando lo strumento Angular CLI che include il routing. -
Ci sono anche tre dipendenze con prefisso
@adobe
:code language-json "@adobe/cq-angular-editable-components": "^2.0.2", "@adobe/cq-spa-component-mapping": "^1.0.3", "@adobe/cq-spa-page-model-manager": "^1.1.3",
I moduli di cui sopra costituiscono l'SDK JS per l'editor SPA dell'AEM e forniscono la funzionalità che consente di mappare i componenti SPA ai componenti AEM.
-
Nel file
package.json
sono definiti diversiscripts
:code language-json "scripts": { "start": "ng serve --open --proxy-config ./proxy.conf.json", "build": "ng lint && ng build && clientlib", "build:production": "ng lint && ng build --prod && clientlib", "test": "ng test", "sync": "aemsync -d -w ../ui.apps/src/main/content" }
Questi script si basano su comandi CLI Angular comuni, ma sono stati leggermente modificati per funzionare con il progetto AEM più grande.
start
- esegue l'app Angular localmente utilizzando un server Web locale. È stato aggiornato per fungere da proxy del contenuto dell’istanza AEM locale.build
- compila l'app Angular per la distribuzione di produzione. L'aggiunta di&& clientlib
è responsabile della copia dell'SPA compilato nel moduloui.apps
come libreria lato client durante una compilazione. Per facilitare questa operazione, viene utilizzato il modulo npm aem-clientlib-generator.Ulteriori dettagli sugli script disponibili sono disponibili qui.
-
Inspect il file
ui.frontend/clientlib.config.js
. Questo file di configurazione viene utilizzato da aem-clientlib-generator per determinare come generare la libreria client. -
Inspect il file
ui.frontend/pom.xml
. Questo file trasforma la cartellaui.frontend
in un modulo Maven. Il filepom.xml
è stato aggiornato per utilizzare frontend-maven-plugin per test e build l'SPA durante una build Maven. -
Inspect il file
app.component.ts
inui.frontend/src/app/app.component.ts
:code language-js import { Constants } from '@adobe/cq-angular-editable-components'; import { ModelManager } from '@adobe/cq-spa-page-model-manager'; import { Component } from '@angular/core'; @Component({ selector: '#spa-root', // tslint:disable-line styleUrls: ['./app.component.css'], templateUrl: './app.component.html' }) export class AppComponent { ... constructor() { ModelManager.initialize().then(this.updateData); } private updateData = pageModel => { this.path = pageModel[Constants.PATH_PROP]; this.items = pageModel[Constants.ITEMS_PROP]; this.itemsOrder = pageModel[Constants.ITEMS_ORDER_PROP]; } }
app.component.js
è il punto di ingresso dell'SPA.ModelManager
è fornito dall'SDK JS dell'editor SPA dell'AEM. È responsabile della chiamata e dell'inserimento dipageModel
(contenuto JSON) nell'applicazione.
Aggiungere un componente Intestazione header-component
Quindi, aggiungi un nuovo componente all’SPA e implementa le modifiche in un’istanza AEM locale per visualizzare l’integrazione.
-
Aprire una nuova finestra del terminale e passare alla cartella
ui.frontend
:code language-shell $ cd aem-guides-wknd-spa/ui.frontend
-
Installa Angular CLI a livello globale Utilizzato per generare componenti Angular e per generare e gestire l'applicazione Angular tramite il comando ng.
code language-shell $ npm install -g @angular/cli
note caution CAUTION La versione di @angular/cli utilizzata dal progetto è 9.1.7. Si consiglia di mantenere sincronizzate le versioni CLI Angular. -
Creare un nuovo componente
Header
eseguendo il comando Angular CLIng generate component
dalla cartellaui.frontend
.code language-shell $ ng generate component components/header CREATE src/app/components/header/header.component.css (0 bytes) CREATE src/app/components/header/header.component.html (21 bytes) CREATE src/app/components/header/header.component.spec.ts (628 bytes) CREATE src/app/components/header/header.component.ts (269 bytes) UPDATE src/app/app.module.ts (1809 bytes)
Verrà creata un'ossatura per il nuovo componente Intestazione Angular in
ui.frontend/src/app/components/header
. -
Aprire il progetto
aem-guides-wknd-spa
nell'IDE desiderato. Passare alla cartellaui.frontend/src/app/components/header
. -
Aprire il file
header.component.html
e sostituire il contenuto con quanto segue:code language-html <!--/* header.component.html */--> <header className="header"> <div className="header-container"> <h1>WKND</h1> </div> </header>
In questo modo viene visualizzato il contenuto statico, pertanto questo componente di Angular non richiede alcuna modifica al valore predefinito generato
header.component.ts
. -
Apri il file app.component.html in
ui.frontend/src/app/app.component.html
. Aggiungiapp-header
:code language-html <app-header></app-header> <router-outlet></router-outlet>
Questo includerà il componente
header
prima di tutto il contenuto della pagina. -
Aprire un nuovo terminale, passare alla cartella
ui.frontend
ed eseguire il comandonpm run build
:code language-shell $ cd ui.frontend $ npm run build Linting "angular-app"... All files pass linting. Generating ES5 bundles for differential loading... ES5 bundle generation complete.
-
Passare alla cartella
ui.apps
. Sottoui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-angular
dovresti vedere che i file SPA compilati sono stati copiati dalla cartellaui.frontend/build
. -
Tornare al terminale e spostarsi nella cartella
ui.apps
. Esegui il seguente comando Maven:code language-shell $ cd ../ui.apps $ mvn clean install -PautoInstallPackage ... [INFO] ------------------------------------------------------------------------ [INFO] BUILD SUCCESS [INFO] ------------------------------------------------------------------------ [INFO] Total time: 9.629 s [INFO] Finished at: 2020-05-04T17:48:07-07:00 [INFO] ------------------------------------------------------------------------
Il pacchetto
ui.apps
verrà distribuito a un'istanza in esecuzione locale di AEM. -
Apri una scheda del browser e passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. Il contenuto del componente
Header
dovrebbe essere visualizzato nell'SPA.
I passaggi 7-9 vengono eseguiti automaticamente quando si attiva una build Maven dalla radice del progetto (ovvero mvn clean install -PautoInstallSinglePackage
). Ora dovresti comprendere le basi dell’integrazione tra l’SPA e le librerie lato client dell’AEM. È comunque possibile modificare e aggiungere Text
componenti in AEM, tuttavia il componente Header
non è modificabile.
Server di sviluppo Webpack: proxy dell’API JSON proxy-json
Come visto negli esercizi precedenti, l’esecuzione di una build e la sincronizzazione della libreria client con un’istanza locale dell’AEM richiedono alcuni minuti. Questo è accettabile per i test finali, ma non è ideale per la maggior parte dello sviluppo dell'SPA.
È possibile utilizzare un server di sviluppo webpack per sviluppare rapidamente l'SPA. L’SPA è guidato da un modello JSON generato dall’AEM. In questo esercizio il contenuto JSON di un'istanza in esecuzione di AEM è inviato tramite proxy al server di sviluppo configurato dal progetto Angular.
-
Torna all'IDE e apri il file proxy.conf.json in
ui.frontend/proxy.conf.json
.code language-json [ { "context": [ "/content/**/*.(jpg|jpeg|png|model.json)", "/etc.clientlibs/**/*" ], "target": "http://localhost:4502", "auth": "admin:admin", "logLevel": "debug" } ]
L'app Angular fornisce un semplice meccanismo per proxy le richieste API. I modelli specificati in
context
sono proxy tramitelocalhost:4502
, l'avvio rapido locale dell'AEM. -
Apri il file index.html in
ui.frontend/src/index.html
. Si tratta del file HTML radice utilizzato dal server di sviluppo.Si noti che è presente una voce per
base href="/"
. Il tag di base è fondamentale per la risoluzione degli URL relativi da parte dell'app.code language-html <base href="/">
-
Aprire una finestra del terminale e passare alla cartella
ui.frontend
. Eseguire il comandonpm start
:code language-shell $ cd ui.frontend $ npm start > wknd-spa-angular@0.1.0 start /Users/dgordon/Documents/code/aem-guides-wknd-spa/ui.frontend > ng serve --open --proxy-config ./proxy.conf.json 10% building 3/3 modules 0 active[HPM] Proxy created: [ '/content/**/*.(jpg|jpeg|png|model.json)', '/etc.clientlibs/**/*' ] -> http://localhost:4502 [HPM] Subscribed to http-proxy events: [ 'error', 'close' ] ℹ 「wds」: Project is running at http://localhost:4200/webpack-dev-server/ ℹ 「wds」: webpack output is served from / ℹ 「wds」: 404s will fallback to //index.html
-
Apri una nuova scheda del browser (se non è già aperta) e passa a http://localhost:4200/content/wknd-spa-angular/us/en/home.html.
Dovresti visualizzare gli stessi contenuti dell’AEM, ma senza le funzionalità di authoring abilitate.
-
Tornare all'IDE e creare una nuova cartella denominata
img
inui.frontend/src/assets
. -
Scaricare e aggiungere il logo WKND seguente alla cartella
img
: -
Apri header.component.html in
ui.frontend/src/app/components/header/header.component.html
e includi il logo:code language-html <header class="header"> <div class="header-container"> <div class="logo"> <img class="logo-img" src="assets/img/wknd-logo-dk.png" alt="WKND SPA" /> </div> </div> </header>
Salva le modifiche apportate a header.component.html.
-
Torna al browser. Dovresti vedere immediatamente le modifiche apportate all’app.
È possibile continuare a eseguire aggiornamenti del contenuto in AEM e visualizzarli nel server di sviluppo Webpack, dal momento che il contenuto viene inviato tramite proxy. Le modifiche apportate al contenuto sono visibili solo nel server di sviluppo webpack.
-
Arrestare il server Web locale con
ctrl+c
nel terminale.
Server di sviluppo Webpack - Mock dell’API JSON mock-json
Un altro approccio allo sviluppo rapido consiste nell’utilizzare un file JSON statico come modello JSON. "Deridendo" il JSON, rimuoviamo la dipendenza da un’istanza AEM locale. Consente inoltre a uno sviluppatore front-end di aggiornare il modello JSON per testare la funzionalità e apportare modifiche all’API JSON che verrebbero successivamente implementate da uno sviluppatore back-end.
La configurazione iniziale del JSON fittizio richiede un'istanza AEM locale.
-
Nel browser passa a http://localhost:4502/content/wknd-spa-angular/us/en.model.json.
Questo è il JSON esportato dall’AEM che sta guidando l’applicazione. Copia l’output JSON.
-
Torna all'IDE passa a
ui.frontend/src
e aggiungi nuove cartelle denominate mocks e json per corrispondere alla seguente struttura di cartelle:code language-plain |-- ui.frontend |-- src |-- mocks |-- json
-
Crea un nuovo file denominato en.model.json sotto
ui.frontend/public/mocks/json
. Incolla qui l'output JSON dal passaggio 1. -
Crea un nuovo file proxy.mock.conf.json sotto
ui.frontend
. Compila il file con quanto segue:code language-json [ { "context": [ "/content/**/*.model.json" ], "pathRewrite": { "^/content/wknd-spa-angular/us" : "/mocks/json"} , "target": "http://localhost:4200", "logLevel": "debug" } ]
Questa configurazione proxy riscriverà le richieste che iniziano con
/content/wknd-spa-angular/us
con/mocks/json
e distribuirà il file JSON statico corrispondente, ad esempio:code language-plain /content/wknd-spa-angular/us/en.model.json -> /mocks/json/en.model.json
-
Apri il file angular.json. Aggiungi una nuova configurazione dev con un array assets aggiornato per fare riferimento alla cartella mocks creata.
code language-json "dev": { "assets": [ "src/mocks", "src/assets", "src/favicon.ico", "src/logo192.png", "src/logo512.png", "src/manifest.json" ] },
La creazione di una configurazione dev dedicata garantisce che la cartella mocks venga utilizzata solo durante lo sviluppo e non venga mai distribuita all'AEM in una build di produzione.
-
Nel file angular.json, aggiorna la configurazione browserTarget per utilizzare la nuova configurazione dev:
code language-diff ... "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { + "browserTarget": "angular-app:build:dev" - "browserTarget": "angular-app:build" }, ...
-
Apri il file
ui.frontend/package.json
e aggiungi un nuovo comando start:mock per fare riferimento al file proxy.mock.conf.json.code language-diff "scripts": { "start": "ng serve --open --proxy-config ./proxy.conf.json", + "start:mock": "ng serve --open --proxy-config ./proxy.mock.conf.json", "build": "ng lint && ng build && clientlib", "build:production": "ng lint && ng build --prod && clientlib", "test": "ng test", "sync": "aemsync -d -w ../ui.apps/src/main/content" }
L’aggiunta di un nuovo comando consente di passare facilmente da una configurazione proxy all’altra.
-
Se è in esecuzione, arrestare il server di sviluppo webpack. Avvia il server di sviluppo webpack utilizzando lo script start:mock:
code language-shell $ npm run start:mock > wknd-spa-angular@0.1.0 start:mock /Users/dgordon/Documents/code/aem-guides-wknd-spa/ui.frontend > ng serve --open --proxy-config ./proxy.mock.conf.json
Passa a http://localhost:4200/content/wknd-spa-angular/us/en/home.html per visualizzare lo stesso SPA, ma il contenuto viene ora estratto dal file JSON fittizio.
-
Apporta una piccola modifica al file en.model.json creato in precedenza. Il contenuto aggiornato deve essere immediatamente riflesso nel server di sviluppo Webpack.
La capacità di manipolare il modello JSON e di vedere gli effetti su un SPA in tempo reale può aiutare uno sviluppatore a comprendere l’API del modello JSON. Consente inoltre lo sviluppo sia front-end che back-end in parallelo.
Aggiungi stili con Sass
Successivamente, al progetto viene aggiunto uno stile aggiornato. Questo progetto aggiungerà il supporto di Sass per alcune funzionalità utili come le variabili.
-
Aprire una finestra del terminale e arrestare il server di sviluppo webpack, se avviato. Dall'interno della cartella
ui.frontend
immettere il comando seguente per aggiornare l'app Angular per elaborare .scss file.code language-shell $ cd ui.frontend $ ng config schematics.@schematics/angular:component.styleext scss
Il file
angular.json
verrà aggiornato con una nuova voce nella parte inferiore del file:code language-json "schematics": { "@schematics/angular:component": { "styleext": "scss" } }
-
Installa
normalize-scss
per normalizzare gli stili nei vari browser:code language-shell $ npm install normalize-scss --save
-
Tornare all'IDE e sotto
ui.frontend/src
creare una nuova cartella denominatastyles
. -
Creare un nuovo file sotto
ui.frontend/src/styles
denominato_variables.scss
e popolarlo con le seguenti variabili:code language-scss //_variables.scss //== Colors // //## Gray and brand colors for use across theme. $black: #202020; $gray: #696969; $gray-light: #EBEBEB; $gray-lighter: #F7F7F7; $white: #FFFFFF; $yellow: #FFEA00; $blue: #0045FF; //== Typography // //## Font, line-height, and color for body text, headings, and more. $font-family-sans-serif: "Helvetica Neue", Helvetica, Arial, sans-serif; $font-family-serif: Georgia, "Times New Roman", Times, serif; $font-family-base: $font-family-sans-serif; $font-size-base: 18px; $line-height-base: 1.5; $line-height-computed: floor(($font-size-base * $line-height-base)); // Functional Colors $brand-primary: $yellow; $body-bg: $white; $text-color: $black; $text-color-inverse: $gray-light; $link-color: $blue; //Layout $max-width: 1024px; $header-height: 75px; // Spacing $gutter-padding: 12px;
-
Rinomina l'estensione del file styles.css in
ui.frontend/src/styles.css
in styles.scss. Sostituire il contenuto con quanto segue:code language-scss /* styles.scss * / /* Normalize */ @import '~normalize-scss/sass/normalize'; @import './styles/variables'; body { background-color: $body-bg; font-family: $font-family-base; margin: 0; padding: 0; font-size: $font-size-base; text-align: left; color: $text-color; line-height: $line-height-base; } body.page { max-width: $max-width; margin: 0 auto; padding: $gutter-padding; padding-top: $header-height; }
-
Aggiorna angular.json e rinomina tutti i riferimenti a style.css con styles.scss. Dovrebbero essere presenti 3 riferimenti.
code language-diff "styles": [ - "src/styles.css" + "src/styles.scss" ],
Aggiorna stili intestazione
Aggiungi quindi alcuni stili specifici del brand al componente Intestazione utilizzando Sass.
-
Avvia il server di sviluppo webpack per visualizzare gli stili aggiornati in tempo reale:
code language-shell $ npm run start:mock
-
In
ui.frontend/src/app/components/header
rinominare header.component.css in header.component.scss. Compila il file con quanto segue:code language-scss @import "~src/styles/variables"; .header { width: 100%; position: fixed; top: 0; left:0; z-index: 99; background-color: $brand-primary; box-shadow: 0px 0px 10px 0px rgba(0, 0, 0, 0.24); } .header-container { display: flex; max-width: $max-width; margin: 0 auto; padding-left: $gutter-padding; padding-right: $gutter-padding; } .logo { z-index: 100; display: flex; padding-top: $gutter-padding; padding-bottom: $gutter-padding; } .logo-img { width: 100px; }
-
Aggiorna header.component.ts per fare riferimento a header.component.scss:
code language-diff ... @Component({ selector: 'app-header', templateUrl: './header.component.html', - styleUrls: ['./header.component.css'] + styleUrls: ['./header.component.scss'] }) ...
-
Torna al browser e al server di sviluppo webpack:
Gli stili aggiornati dovrebbero essere aggiunti al componente Intestazione.
Distribuire gli aggiornamenti SPA all’AEM
Le modifiche apportate all'Intestazione sono attualmente visibili solo tramite il server di sviluppo Webpack. Distribuire l’SPA aggiornato nell’AEM per visualizzare le modifiche.
-
Arresta il server di sviluppo webpack.
-
Passare alla radice del progetto
/aem-guides-wknd-spa
e distribuire il progetto a AEM utilizzando Maven:code language-shell $ cd .. $ mvn clean install -PautoInstallSinglePackage
-
Passa a http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. Dovresti visualizzare l'Intestazione aggiornata con logo e stili applicati:
Ora che l’SPA aggiornato è in AEM, la creazione può continuare.
Congratulazioni. congratulations
Congratulazioni, hai aggiornato l’SPA ed esplorato l’integrazione con l’AEM! Ora conosci due diversi approcci per lo sviluppo dell'SPA rispetto all'API del modello JSON dell'AEM utilizzando un server di sviluppo Webpack.
Puoi sempre visualizzare il codice finito su GitHub o estrarre il codice localmente passando al ramo Angular/integrate-spa-solution
.
Passaggi successivi next-steps
Mappare i componenti SPA ai componenti AEM - Scopri come mappare i componenti Angular ai componenti Adobe Experience Manager (AEM) con l'SDK JS dell'editor SPA dell'AEM. La mappatura dei componenti consente agli autori di apportare aggiornamenti dinamici ai componenti SPA nell’Editor SPA dell’AEM, in modo simile all’authoring AEM tradizionale.