集成SPA integrate-spa
了解如何将Angular编写的单页应用程序(SPA)的源代码与Adobe Experience Manager (AEM)项目集成。 了解如何使用现代前端工具(如webpack开发服务器)快速开发SPA以支持AEM JSON模型API。
目标
- 了解SPA项目如何与AEM和客户端库集成。
- 了解如何使用本地开发服务器进行专用前端开发。
- 探索如何使用 代理 和静态 模拟 用于针对AEM JSON模型API开发的文件
您将构建的内容
本章将添加一个简单的 Header
组件添加到SPA。 在构建此静态文件的过程中 Header
组件使用了几种AEM SPA开发方法。
扩展SPA以添加静态 Header
组件
前提条件
查看所需的工具和设置说明 本地开发环境.
获取代码
-
通过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
-
使用Maven将代码库部署到本地AEM实例:
code language-shell $ mvn clean install -PautoInstallSinglePackage
如果使用 AEM 6.x 添加
classic
个人资料:code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
您始终可以在上查看完成的代码 GitHub 或通过切换到分支在本地签出代码 Angular/integrate-spa-solution
.
集成方法 integration-approach
在AEM项目中创建了两个模块: ui.apps
和 ui.frontend
.
此 ui.frontend
模块是一个 webpack 包含所有SPA源代码的项目。 大多数SPA开发和测试都在webpack项目中完成。 触发生产内部版本后,将使用webpack构建和编译SPA。 编译后的工件(CSS和Javascript)将复制到 ui.apps
模块,然后部署到AEM运行时。
SPA集成的高级描述。
有关前端内部版本的其他信息可以是 在此处找到.
Inspect与SPA集成 inspect-spa-integration
接下来,检查 ui.frontend
模块,用于了解由自动生成的SPA AEM项目原型.
-
在您选择的IDE中,打开WKND SPA的AEM项目。 本教程将使用 Visual Studio Code IDE.
-
展开并检查
ui.frontend
文件夹。 打开文件ui.frontend/package.json
-
在
dependencies
您应该看到多个与@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",
此
ui.frontend
模块是一个 angular应用程序 使用生成的 angularCLI工具 包括路由。 -
还有三个前缀为的依赖项
@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",
上述模块构成了 AEM SPA编辑器JS SDK 并提供功能,以便能够将SPA组件映射到AEM组件。
-
在
package.json
多个文件scripts
定义了: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" }
这些脚本基于通用 angularCLI命令 但进行了一些细微修改,以适应更大的AEM项目。
start
— 使用本地Web服务器在本地运行Angular应用程序。 它已更新,以代理本地AEM实例的内容。build
— 编译Angular应用程序以进行生产分发。 添加了&& clientlib
负责将编译后的SPA复制到ui.apps
在生成期间作为客户端库使用的模块。 npm模块 aem-clientlib-generator 用于为此提供便利。有关可用脚本的更多详细信息可找到 此处.
-
Inspect文件
ui.frontend/clientlib.config.js
. 此配置文件由以下用户使用 aem-clientlib-generator 以确定如何生成客户端库。 -
Inspect文件
ui.frontend/pom.xml
. 此文件将ui.frontend
将文件夹移入 Maven模块. 此pom.xml
已更新文件以使用 frontend-maven-plugin 到 测试 和 生成 在Maven构建期间使用SPA。 -
Inspect文件
app.component.ts
在ui.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
是SPA的入口点。ModelManager
由AEM SPA编辑器JS SDK提供。 它负责调用和注入pageModel
(JSON内容)放入应用程序。
添加标头组件 header-component
接下来,将新组件添加到SPA并将更改部署到本地AEM实例以查看集成。
-
打开新的终端窗口并导航到
ui.frontend
文件夹:code language-shell $ cd aem-guides-wknd-spa/ui.frontend
-
安装 ANGULARCLI 全局用于生成AngularAngular组件,以及通过 ng 命令。
code language-shell $ npm install -g @angular/cli
note caution CAUTION 的版本 @angular/cli 此项目使用的是 9.1.7. 建议使AngularCLI版本保持同步。 -
新建
Header
通过运行AngularCLI组件ng generate component
命令来自ui.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)
这将为位于的新Angular标题组件创建一个骨架
ui.frontend/src/app/components/header
. -
打开
aem-guides-wknd-spa
在您选择的IDE中的项目。 导航到ui.frontend/src/app/components/header
文件夹。 -
打开文件
header.component.html
并将内容替换为以下内容:code language-html <!--/* header.component.html */--> <header className="header"> <div className="header-container"> <h1>WKND</h1> </div> </header>
请注意,这会显示静态内容,因此此Angular组件不需要对默认生成的内容进行任何调整
header.component.ts
. -
打开文件 app.component.html 在
ui.frontend/src/app/app.component.html
. 添加app-header
:code language-html <app-header></app-header> <router-outlet></router-outlet>
这将包括
header
所有页面内容上方的组件。 -
打开新终端并导航到
ui.frontend
文件夹并运行npm 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.
-
导航至
ui.apps
文件夹。 下ui.apps/src/main/content/jcr_root/apps/wknd-spa-angular/clientlibs/clientlib-angular
您应该会看到编译的SPA文件是从ui.frontend/build
文件夹。 -
返回终端并导航到
ui.apps
文件夹。 执行以下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] ------------------------------------------------------------------------
这将部署
ui.apps
打包到AEM的本地正在运行的实例。 -
打开浏览器选项卡并导航至 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. 您现在应会看到
Header
将在SPA中显示的组件。
步骤 7-9 从项目的根触发Maven构建时,会自动执行 mvn clean install -PautoInstallSinglePackage
)。 现在,您应该了解SPA和AEM客户端库之间集成的基础知识。 请注意,您仍然可以编辑和添加 Text
而AEM中的组件 Header
组件不可编辑。
Webpack开发服务器 — JSON API代理 proxy-json
如前面的练习所示,执行构建并将客户端库同步到AEM的本地实例需要几分钟时间。 虽然对于最终测试来说,这是可以接受的,但是对于大多数SPA开发来说,这是不理想的。
A webpack开发服务器 可用于快速开发SPA。 SPA由AEM生成的JSON模型驱动。 在本练习中,来自正在运行的AEM实例的JSON内容为 已代理 到由配置的开发服务器 angular项目.
-
返回到IDE并打开文件 proxy.conf.json 在
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" } ]
此 angular应用程序 提供了一种代理API请求的简单机制。 中指定的模式
context
是通过localhost:4502
,本地AEM快速入门。 -
打开文件 index.html 在
ui.frontend/src/index.html
. 这是开发服务器使用的根HTML文件。请注意,有一个条目
base href="/"
. 此 基本标记 对于应用程序解析相对URL而言至关重要。code language-html <base href="/">
-
打开终端窗口并导航到
ui.frontend
文件夹。 运行命令npm 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
-
打开新的浏览器选项卡(如果尚未打开)并导航到 http://localhost:4200/content/wknd-spa-angular/us/en/home.html.
您应会看到与AEM相同的内容,但未启用任何创作功能。
-
返回到IDE并创建一个名为的新文件夹
img
在ui.frontend/src/assets
. -
下载以下WKND徽标并将其添加到
img
文件夹: -
打开 header.component.html 在
ui.frontend/src/app/components/header/header.component.html
并包含徽标: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>
将更改保存到 header.component.html.
-
返回到浏览器。 您应该会立即看到对应用程序所做的更改得到反映。
您可以继续在中进行内容更新 AEM 并看到它们在 webpack开发服务器,因为我们正在代理内容。 请注意,内容更改仅在 webpack开发服务器.
-
停止本地Web服务器
ctrl+c
在终端机里。
Webpack开发服务器 — Mock JSON API mock-json
快速开发的另一种方法是使用静态JSON文件充当JSON模型。 通过“模拟”JSON,我们删除了对本地AEM实例的依赖关系。 它还允许前端开发人员更新JSON模型,以测试功能并驱动对JSON API的更改,这些更改稍后将由后端开发人员实施。
模拟JSON的初始设置可以 需要本地AEM实例.
-
在浏览器中,导航到 http://localhost:4502/content/wknd-spa-angular/us/en.model.json.
这是由AEM导出的驱动应用程序的JSON。 复制JSON输出。
-
返回到IDE导航到
ui.frontend/src
并添加名为的新文件夹 嘲笑 和 json 匹配以下文件夹结构:code language-plain |-- ui.frontend |-- src |-- mocks |-- json
-
创建新文件,名为 en.model.json 下
ui.frontend/public/mocks/json
. 粘贴来自的JSON输出 步骤1 此处。 -
创建新文件 proxy.mock.conf.json 下
ui.frontend
. 使用以下内容填充文件:code language-json [ { "context": [ "/content/**/*.model.json" ], "pathRewrite": { "^/content/wknd-spa-angular/us" : "/mocks/json"} , "target": "http://localhost:4200", "logLevel": "debug" } ]
此代理配置将重写以开头的请求
/content/wknd-spa-angular/us
替换为/mocks/json
和提供了相应的静态JSON文件,例如:code language-plain /content/wknd-spa-angular/us/en.model.json -> /mocks/json/en.model.json
-
打开文件 angular.json. 添加新 开发 已更新的配置 资产 数组以引用 嘲笑 已创建文件夹。
code language-json "dev": { "assets": [ "src/mocks", "src/assets", "src/favicon.ico", "src/logo192.png", "src/logo512.png", "src/manifest.json" ] },
创建专用 开发 配置确保 嘲笑 文件夹仅在开发期间使用,绝不会部署到生产版本中的AEM。
-
在 angular.json 文件,下次更新 browserTarget 配置以使用新的 开发 配置:
code language-diff ... "serve": { "builder": "@angular-devkit/build-angular:dev-server", "options": { + "browserTarget": "angular-app:build:dev" - "browserTarget": "angular-app:build" }, ...
-
打开文件
ui.frontend/package.json
并添加新的 开始:模拟 命令引用 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" }
通过添加新命令,可以轻松地在代理配置之间进行切换。
-
如果当前正在运行,请停止 webpack开发服务器. 启动 webpack开发服务器 使用 开始:模拟 脚本:
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
导航到 http://localhost:4200/content/wknd-spa-angular/us/en/home.html 您应该会看到相同的SPA,但内容正在从 模拟 JSON文件。
-
对 en.model.json 文件创建时间较早。 更新的内容应立即反映在 webpack开发服务器.
能够处理JSON模型并查看对实时SPA的影响可以帮助开发人员了解JSON模型API。 它还允许前端和后端开发并行进行。
使用Sass添加样式
接下来,将一些更新的样式添加到项目中。 此项目将添加 萨斯 支持一些有用的功能,如变量。
-
打开终端窗口并停止 webpack开发服务器 (如果已启动)。 从内部
ui.frontend
文件夹输入以下命令以更新要处理的Angular应用程序 .scss 文件。code language-shell $ cd ui.frontend $ ng config schematics.@schematics/angular:component.styleext scss
这将更新
angular.json
文件底部有一个新条目:code language-json "schematics": { "@schematics/angular:component": { "styleext": "scss" } }
-
安装
normalize-scss
要标准化各个浏览器的样式,请执行以下操作:code language-shell $ npm install normalize-scss --save
-
返回到IDE及其下方
ui.frontend/src
创建新文件夹,名为styles
. -
在下方创建新文件
ui.frontend/src/styles
已命名_variables.scss
并使用以下变量填充该变量: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;
-
重新命名文件的扩展名 styles.css 在
ui.frontend/src/styles.css
到 styles.scss. 将内容替换为以下内容: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; }
-
更新 angular.json 并将所有引用重新命名为 style.css 替换为 styles.scss. 应该有3个引用。
code language-diff "styles": [ - "src/styles.css" + "src/styles.scss" ],
更新标题样式
接下来,将一些特定于品牌的样式添加到 页眉 组件使用Sass。
-
启动 webpack开发服务器 要查看样式实时更新,请执行以下操作:
code language-shell $ npm run start:mock
-
下
ui.frontend/src/app/components/header
重新命名 header.component.css 到 header.component.scss. 使用以下内容填充文件: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; }
-
更新 header.component.ts 以引用 header.component.scss:
code language-diff ... @Component({ selector: 'app-header', templateUrl: './header.component.html', - styleUrls: ['./header.component.css'] + styleUrls: ['./header.component.scss'] }) ...
-
返回到浏览器并 webpack开发服务器:
现在,您应该会看到已更新的样式已添加到 页眉 组件。
将SPA更新部署到AEM
对所做的更改 页眉 当前仅通过 webpack开发服务器. 将更新后的SPA部署到AEM以查看更改内容。
-
停止 webpack开发服务器.
-
导航到项目的根目录
/aem-guides-wknd-spa
并使用Maven将该项目部署到AEM:code language-shell $ cd .. $ mvn clean install -PautoInstallSinglePackage
-
导航到 http://localhost:4502/editor.html/content/wknd-spa-angular/us/en/home.html. 您应会看到已更新的 页眉 应用了徽标和样式后:
现在,更新后的SPA位于AEM中,创作可以继续进行。
恭喜! congratulations
恭喜,您已更新SPA并探索了与AEM的集成! 现在,您知道了使用针对AEM JSON模型API开发SPA的两种不同方法 webpack开发服务器.
您始终可以在上查看完成的代码 GitHub 或通过切换到分支在本地签出代码 Angular/integrate-spa-solution
.
后续步骤 next-steps
将SPA组件映射到AEM组件 — 了解如何使用AEM SPA编辑器JS SDK将Angular组件映射到Adobe Experience Manager (AEM)组件。 组件映射允许作者在SPA SPA编辑器中对AEM组件进行动态更新,这与传统AEM创作类似。