Integrare un’applicazione a pagina singola
- Si applica a:
- Experience Manager as a Cloud Service
Creato per:
- Principiante
- Sviluppatore
- Editor universale per la modifica visiva di contenuti headless.
- Editor frammenti di contenuto per la modifica di contenuti headless basata su modulo.
Scopri come il codice sorgente di un’applicazione a pagina singola 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’applicazione a pagina singola rispetto all’API del modello JSON di AEM.
Obiettivo
- Scopri in che modo il progetto SPA viene integrato con 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'applicazione a pagina singola. Durante la creazione di questo componente Header
statico vengono utilizzati diversi approcci allo sviluppo di applicazioni a pagina singola di AEM.
L'applicazione a pagina singola è stata estesa 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:
$ git clone git@github.com:adobe/aem-guides-wknd-spa.git $ cd aem-guides-wknd-spa $ git checkout Angular/integrate-spa-start
-
Implementa la base di codice in un’istanza AEM locale utilizzando Maven:
$ mvn clean install -PautoInstallSinglePackage
Se utilizzi AEM 6.x, aggiungi il profilo
classic
:$ 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
Due moduli sono stati creati come parte del progetto AEM: ui.apps
e ui.frontend
.
Il modulo ui.frontend
è un progetto webpack che contiene tutto il codice sorgente dell'applicazione a pagina singola. La maggior parte dello sviluppo e del test delle applicazioni a pagina singola viene eseguita nel progetto webpack. Quando viene attivata una build di produzione, l’applicazione a pagina singola viene generata e compilata utilizzando Webpack. Gli artefatti compilati (CSS e JavaScript) vengono copiati nel modulo ui.apps
che viene quindi distribuito nel runtime di AEM.
Rappresentazione di alto livello dell'integrazione SPA.
Ulteriori informazioni sulla build front-end sono disponibili qui.
Controllare l’integrazione con le applicazioni a pagina singola
Esaminare quindi il modulo ui.frontend
per comprendere l'applicazione a pagina singola generata automaticamente dall'archetipo progetto AEM.
-
Nell’IDE che preferisci, apri il progetto AEM per l’applicazione a pagina singola 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
:"@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
:"@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 AEM SPA Editor JS SDK e forniscono la funzionalità che consente di mappare i componenti SPA ai componenti AEM.
-
Nel file
package.json
sono definiti diversiscripts
:"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 di 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'applicazione a pagina singola compilata 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.
-
Controllare il file
ui.frontend/clientlib.config.js
. Questo file di configurazione viene utilizzato da aem-clientlib-generator per determinare come generare la libreria client. -
Controllare 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'applicazione a pagina singola durante una compilazione Maven. -
Esaminare il file
app.component.ts
inui.frontend/src/app/app.component.ts
: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'applicazione a pagina singola.ModelManager
è fornito da AEM SPA Editor JS SDK. È responsabile della chiamata e dell'inserimento dipageModel
(contenuto JSON) nell'applicazione.
Aggiungere un componente Intestazione
Quindi, aggiungi un nuovo componente all’applicazione a pagina singola 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
:$ 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.
$ npm install -g @angular/cli
CAUTION
La versione di @angular/cli utilizzata dal progetto è 9.1.7. Si consiglia di mantenere sincronizzate le versioni di Angular CLI. -
Creare un nuovo componente
Header
eseguendo il comando Angular CLIng generate component
dalla cartellaui.frontend
.$ 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 Angular Header 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:<!--/* 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 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
:<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
:$ 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:$ 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'applicazione a pagina singola.
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 nozioni di base sull’integrazione tra le librerie lato client di applicazioni a pagina singola e AEM. È comunque possibile modificare e aggiungere Text
componenti in AEM, tuttavia il componente Header
non è modificabile.
Server di sviluppo Webpack: proxy dell’API JSON
Come mostrato negli esercizi precedenti, l’esecuzione di una build e la sincronizzazione della libreria client con un’istanza locale di AEM richiedono alcuni minuti. Questo è accettabile per il test finale, ma non è ideale per la maggior parte dello sviluppo di applicazioni a pagina singola.
È possibile utilizzare un server di sviluppo webpack per sviluppare rapidamente l'applicazione a pagina singola. L’applicazione a pagina singola è guidata da un modello JSON generato da 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
.[ { "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 inoltrare le richieste API. I pattern specificati in
context
sono inviati tramite proxy tramitelocalhost:4502
, l'avvio rapido locale di 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.<base href="/">
-
Aprire una finestra del terminale e passare alla cartella
ui.frontend
. Eseguire il comandonpm start
:$ 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 di AEM, ma senza alcuna funzionalità di authoring abilitata.
-
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:<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, poiché il contenuto è in fase di 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
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 da 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:|-- 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:[ { "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:/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.
"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 ad AEM in una build di produzione.
-
Nel file angular.json, aggiorna la configurazione browserTarget per utilizzare la nuova configurazione dev:
... "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."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:
$ 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 la stessa applicazione a pagina singola, 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 possibilità di manipolare il modello JSON e vedere gli effetti su un’applicazione a pagina singola live 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.$ 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:"schematics": { "@schematics/angular:component": { "styleext": "scss" } }
-
Installa
normalize-scss
per normalizzare gli stili nei vari browser:$ 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://_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:/* 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.
"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:
$ 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:@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:
... @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 aggiornamenti SPA in AEM
Le modifiche apportate all'Intestazione sono attualmente visibili solo tramite il server di sviluppo Webpack. Distribuisci l’applicazione a pagina singola aggiornata in AEM per visualizzare le modifiche.
-
Arresta il server di sviluppo webpack.
-
Passare alla directory principale del progetto
/aem-guides-wknd-spa
e distribuire il progetto in AEM utilizzando Maven:$ 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’applicazione a pagina singola aggiornata è in AEM, l’authoring può continuare.
Congratulazioni.
Congratulazioni, hai aggiornato l’applicazione a pagina singola ed esplorato l’integrazione con AEM. Ora conosci due diversi approcci per lo sviluppo dell'applicazione a pagina singola rispetto all'API del modello JSON di 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
Mappatura dei componenti SPA sui componenti AEM - Scopri come mappare i componenti Angular sui componenti Adobe Experience Manager (AEM) con AEM SPA Editor JS SDK. La mappatura dei componenti consente agli autori di apportare aggiornamenti dinamici ai componenti delle applicazioni a pagina singola nell’editor delle applicazioni a pagina singola di AEM, in modo simile all’authoring tradizionale AEM.