在将可编辑区域添加到远程SPA中之前,必须先通过AEM SPA Editor JavaScript SDK和其他一些配置将其引导。
如果您尚未执行此操作,请从Github.com下载WKND应用程序的源代码,然后将包含对本教程中所执行的SPA所做更改的分支切换为。
$ mkdir -p ~/Code/wknd-app
$ cd ~/Code/wknd-app
$ git clone --branch feature/spa-editor https://github.com/adobe/aem-guides-wknd-graphql.git
$ cd aem-guides-wknd-graphql
首先,将AEM SPA npm依赖项添加到React项目。
$ cd ~/Code/wknd-app/aem-guides-wknd-graphql/react-app
$ npm install --save \
@adobe/aem-spa-page-model-manager \
@adobe/aem-spa-component-mapping \
@adobe/aem-react-editable-components \
@adobe/aem-core-components-react-base \
@adobe/aem-core-components-react-spa
@adobe/aem-spa-page-model-manager
提供了用于从AEM检索内容的API。@adobe/aem-spa-component-mapping
提供了将AEM内容映射到SPA组件的API。 @adobe/aem-react-editable-components
提供了用于构建自定义SPA组件的API,并提供了常用实施,如 AEMPage
React组件。@adobe/aem-core-components-react-base
提供了一套现成的React组件,这些组件与AEM WCM核心组件无缝集成,且与SPA编辑器无关。这些组件主要包括以下内容组件:
@adobe/aem-core-components-react-spa
提供了一套现成的React组件,这些组件与AEM WCM核心组件无缝集成,但需要SPA编辑器。这些组件主要包含包含@adobe/aem-core-components-react-base
中的内容组件的组件,例如:
必须向远程SPA显示多个环境变量,以便其知道如何与AEM交互。
在IDE的~/Code/wknd-app/aem-guides-wknd-graphql/react-app
处打开远程SPA项目
打开文件.env.development
添加文件,并特别注意键:
REACT_APP_HOST_URI=http://localhost:4502
REACT_APP_AUTHORIZATION=admin:admin
请记住,React中的自定义环境变量必须带有前缀 REACT_APP_
。
REACT_APP_AEM_URI
:远程SPA连接到的AEM服务的方案和主机。
REACT_APP_AEM_AUTH
:SPA对AEM进行身份验证并检索内容时使用的凭据。
使用应用程序可用的AEM SPA npm依赖项,在调用ReactDOM.render(...)
之前,初始化项目index.js
中的AEM ModelManager
。
ModelManager负责连接到AEM以检索可编辑的内容。
在IDE中打开远程SPA项目
打开文件src/index.js
添加import ModelManager
并在ReactDOM.render(..)
调用之前对其进行初始化,
...
import { ModelManager } from "@adobe/aem-spa-page-model-manager";
// Initialize the ModelManager before invoking ReactDOM.render(...).
ModelManager.initializeAsync();
ReactDOM.render(...);
src/index.js
文件应该如下所示:
从SPA的AEM中采购可编辑内容时,最好在SPA🔗中设置一个内部代理,该代理配置为将相应请求路由到AEM。 这是使用http-proxy-middleware npm模块完成的,该模块已由基本WKND GraphQL应用程序安装。
在IDE中打开远程SPA项目
在src/proxy/setupProxy.spa-editor.auth.basic.js
创建文件
将以下代码添加到该文件:
const { createProxyMiddleware } = require('http-proxy-middleware');
const {REACT_APP_HOST_URI, REACT_APP_AUTHORIZATION } = process.env;
/*
Set up a proxy with AEM for local development
In a production environment this proxy should be set up at the webserver level or absolute URLs should be used.
*/
module.exports = function(app) {
/**
* Filter to check if the request should be re-routed to AEM. The paths to be re-routed at:
* - Starts with /content (AEM content)
* - Starts with /graphql (AEM graphQL endpoint)
* - Ends with .model.json (AEM Content Services)
*
* @param {*} path the path being requested of the SPA
* @param {*} req the request object
* @returns true if the SPA request should be re-routed to AEM
*/
const toAEM = function(path, req) {
return path.startsWith('/content') ||
path.startsWith('/graphq') ||
path.endsWith('.model.json')
}
/**
* Re-writes URLs being proxied to AEM such that they can resolve to real AEM resources
* - The "root" case of `/.model.json` are rewritten to the SPA's home page in AEM
* - .model.json requests for /adventure:xxx routes are rewritten to their corresponding adventure page under /content/wknd-app/us/en/home/adventure/
*
* @param {*} path the path being requested of the SPA
* @param {*} req the request object
* @returns returns a re-written path, or nothing to use the @param path
*/
const pathRewriteToAEM = function (path, req) {
if (path === '/.model.json') {
return '/content/wknd-app/us/en/home.model.json';
} else if (path.startsWith('/adventure:') && path.endsWith('.model.json')) {
return '/content/wknd-app/us/en/home/adventure/' + path.split('/').pop();
}
}
/**
* Register the proxy middleware using the toAEM filter and pathRewriteToAEM rewriter
*/
app.use(
createProxyMiddleware(
toAEM, // Only route the configured requests to AEM
{
target: REACT_APP_HOST_URI,
changeOrigin: true,
// Pass in credentials when developing against an Author environment
auth: REACT_APP_AUTHORIZATION,
pathRewrite: pathRewriteToAEM // Rewrite SPA paths being sent to AEM
}
)
);
/**
* Enable CORS on requests from the SPA to AEM
*
* If this rule is not in place, CORS errors will occur when running the SPA on http://localhost:3000
*/
app.use((req, res, next) => {
res.header("Access-Control-Allow-Origin", REACT_APP_HOST_URI);
next();
});
};
setupProxy.spa-editor.auth.basic.js
文件应该如下所示:
此代理配置执行两项主要操作:
http://localhost:3000
和AEM http://localhost:4502
发出的特定于代理的请求
toAEM(path, req)
中所定义。pathRewriteToAEM(path, req)
中的定义,将SPA路径重写到与之相对的AEM页面res.header("Access-Control-Allow-Origin", REACT_APP_HOST_URI);
定义的AEM内容
打开文件src/setupProxy.js
注释掉行const proxy = require('./proxy/setupProxy.auth.basic')
添加一行,指向新的代理配置文件:
// Proxy configuration for SPA Editor (and GraphQL) using Basic Auth
const proxy = require('./proxy/setupProxy.spa-editor.auth.basic')
setupProxy.js
文件应该如下所示:
请注意,对src/setupProxy.js
或其引用的文件所做的任何更改都需要重新启动SPA。
静态SPA资源(如WKND徽标和加载图形)需要更新其src URL以强制从远程SPA主机加载。 如果为左侧相对,则在SPA Editor中加载SPA以进行创作时,这些URL默认使用AEM主机,而不是SPA,从而导致404个请求,如下图所示。
要解决此问题,请使由远程SPA托管的静态资源使用包含远程SPA源的绝对路径。
在IDE中打开SPA项目
打开SPA环境变量文件src/.env.development
并为SPA公共URI添加一个变量:
...
# The base URI the SPA is accessed from
REACT_APP_PUBLIC_URI=http://localhost:3000
将AEM作为Cloud Service部署时,您需要对相应文件执行相同的 .env
部署。
打开文件src/App.js
从SPA环境变量导入SPA公共URI
const { REACT_APP_PUBLIC_URI } = process.env;
function App() { ... }
为WKND徽标<img src=.../>
添加前缀REACT_APP_PUBLIC_URI
以强制对SPA进行分辨率。
<img src={REACT_APP_PUBLIC_URI + '/' + logo} className="logo" alt="WKND Logo"/>
在src/components/Loading.js
中加载图像时,请执行相同的操作
const { REACT_APP_PUBLIC_URI } = process.env;
class Loading extends Component {
render() {
return (<div className="loading">
<img src={REACT_APP_PUBLIC_URI + '/' + loadingIcon} alt="Loading..." />
</div>);
}
}
… 和src/components/AdventureDetails.js
中返回按钮的两个实例
const { REACT_APP_PUBLIC_URI } = process.env;
function AdventureDetail(props) {
...
render() {
<img className="Backbutton-icon" src={REACT_APP_PUBLIC_URI + '/' + backIcon} alt="Return" />
}
}
App.js
、Loading.js
和AdventureDetails.js
文件应当如下所示:
要支持SPA编辑器的布局模式用于SPA中的可编辑区域,我们必须将AEM响应式网格CSS集成到SPA中。 别担心 — 此网格系统将仅对可编辑的容器进行,您可以使用所选的网格系统来驱动其余SPA的布局。
将AEM响应式网格SCSS文件添加到SPA。
在IDE中打开SPA项目
下载以下两个文件并将其复制到src/styles
中
_grid.scss
。打开src/App.scss
并导入./styles/grid-init.scss
...
@import './styles/grid-init';
...
_grid.scss
和_grid-init.scss
文件应当如下所示:
现在,SPA中包含为添加到AEM容器的组件支持AEM布局模式所需的CSS。
现在,SPA正在自动与AEM集成,让我们运行SPA并查看其外观!
在命令行中,导航到SPA项目的根
使用普通命令启动SPA(如果尚未运行npm install
)
$ cd ~/Code/wknd-app/aem-guides-wknd-graphql/react-app
$ npm install
$ npm run start
浏览http://localhost:3000上的SPA。 一切都应该好看!
在http://localhost:3000上运行SPA时,让我们使用AEM SPA编辑器将其打开。 SPA中尚无任何内容可编辑,这仅会在AEM中验证SPA。
登录到AEM作者
导航至站点> WKND应用程序>使用> en
选择WKND应用程序主页并点按编辑,此时将显示SPA。
使用右上方的模式切换器切换到预览
单击周围的SPA
您已引导远程SPA以兼容AEM SPA编辑器! 您现在知道如何:
现在,我们已实现与AEM SPA Editor兼容性的基准,接下来可以开始引入可编辑的区域。 我们将首先研究如何在SPA中放置固定可编辑的组件。