为SPA编辑器Bootstrap远程SPA
必须先使用AEM SPA Editor JavaScript SDK和其他一些配置引导可编辑区域,然后才能将其添加到远程SPA。
安装AEM SPA编辑器JS SDK npm依赖项
首先,查看AEM针对React项目的SPA npm依赖项,并安装它们。
@adobe/aem-spa-page-model-manager:提供用于从AEM检索内容的API。@adobe/aem-spa-component-mapping:提供将AEM内容映射到SPA组件的API。@adobe/aem-react-editable-componentsv2 :提供用于生成自定义SPA组件的API并提供常用实施,如AEMPageReact组件。
$ cd ~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app
$ npm install @adobe/aem-spa-page-model-manager
$ npm install @adobe/aem-spa-component-mapping
$ npm install @adobe/aem-react-editable-components
查看SPA环境变量
必须对远程SPA公开多个环境变量,以便它了解如何与AEM交互。
-
在IDE中的
~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app处打开远程SPA项目 -
打开文件
.env.development -
在文件中,请特别注意键值,并根据需要进行更新:
code language-none REACT_APP_HOST_URI=http://localhost:4502 REACT_APP_USE_PROXY=true REACT_APP_AUTH_METHOD=basic REACT_APP_BASIC_AUTH_USER=admin REACT_APP_BASIC_AUTH_PASS=admin
请记住,React中的自定义环境变量必须添加前缀
REACT_APP_。-
REACT_APP_HOST_URI:远程SPA连接到的AEM服务的方案和主机。- 此值根据AEM环境(本地、开发、暂存或生产)和AEM服务类型(创作与发布)的状态而变化
-
REACT_APP_USE_PROXY:通过告知react开发服务器使用http-proxy-middleware模块代理AEM请求(例如/content, /graphql, .model.json),从而避免了在开发期间出现CORS问题。 -
REACT_APP_AUTH_METHOD:为AEM提供的请求提供身份验证方法,选项为“service-token”、“dev-token”、“basic”或对于no-auth用例保留为空- 需要与AEM Author一起使用
- 可能需要与AEM Publish一起使用(如果内容受保护)
- 针对AEM SDK进行开发时,可通过基本身份验证支持本地帐户。 这是本教程中使用的方法。
- 与AEM as a Cloud Service集成时,使用访问令牌
-
REACT_APP_BASIC_AUTH_USER: SPA在检索AEM内容时用于进行身份验证的AEM 用户名。 -
REACT_APP_BASIC_AUTH_PASS:检索AEM内容时,SPA用于进行身份验证的AEM 密码。
-
集成ModelManager API
利用应用程序可用的AEM SPA NPM依赖项,在调用ReactDOM.render(...)之前,在项目的index.js中初始化AEM的ModelManager。
ModelManager负责连接到AEM以检索可编辑的内容。
-
在IDE中打开远程SPA项目
-
打开文件
src/index.js -
添加导入
ModelManager并在root.render(..)调用之前对其进行初始化,code language-javascript ... import { ModelManager } from "@adobe/aem-spa-page-model-manager"; // Initialize the ModelManager before invoking root.render(..). ModelManager.initializeAsync(); const container = document.getElementById('root'); const root = createRoot(container); root.render(<App />);
src/index.js文件应如下所示:
设置内部SPA代理
创建可编辑SPA时,最好在SPA🔗中设置内部代理,该代理配置为将相应请求路由到AEM。 这是通过使用http-proxy-middleware npm模块完成的,该模块已由基本WKND GraphQL应用程序安装。
-
在IDE中打开远程SPA项目
-
在
src/proxy/setupProxy.spa-editor.auth.basic.js处打开文件 -
通过以下代码更新文件:
code language-javascript const { createProxyMiddleware } = require('http-proxy-middleware'); const {REACT_APP_HOST_URI, REACT_APP_BASIC_AUTH_USER, REACT_APP_BASIC_AUTH_PASS } = 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('/graphql') || 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_BASIC_AUTH_USER}:${REACT_APP_BASIC_AUTH_PASS}`, 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文件应如下所示:
此代理配置主要执行两项操作:
-
将向SPA (
http://localhost:3000)发出的特定请求代理到AEMhttp://localhost:4502- 它仅代理请求,其路径与指示AEM应为其提供服务的模式匹配(如
toAEM(path, req)中所定义)。 - 它将SPA路径重写为其对应的AEM页面,如
pathRewriteToAEM(path, req)中所定义
- 它仅代理请求,其路径与指示AEM应为其提供服务的模式匹配(如
-
It adds CORS headers to all requests to allow access to AEM content, as defined by
res.header("Access-Control-Allow-Origin", REACT_APP_HOST_URI);- If this is not added, CORS errors occur when loading AEM content in the SPA.
-
-
打开文件
src/setupProxy.js -
Review the line pointing to the
setupProxy.spa-editor.auth.basicproxy configuration file:code language-none ... case BASIC: // Use user/pass for local development with Local Author Env return require('./proxy/setupProxy.spa-editor.auth.basic'); ...
Note, any changes to the src/setupProxy.js or it's referenced files require a restart of the SPA.
Static SPA resource
Static SPA resources such as the WKND Logo and Loading graphics need to have their src URLs updated to force them load from the Remote SPA's host. If left relative, when the SPA is loaded in SPA Editor for authoring, these URLs default to use AEM's host rather than the SPA, resulting in 404 requests as illustrated in the image below.
To resolve this issue, make a static resource hosted by the Remote SPA use absolute paths that include the Remote SPA's origin.
-
在IDE中打开SPA项目
-
Open your SPA's environment variables file
src/.env.developmentand add a variable for the SPA's public URI:code language-none ... # The base URI the SPA is accessed from REACT_APP_PUBLIC_URI=http://localhost:3000When deploying to AEM as a Cloud Service, you need to the same for the corresponding
.envfiles. -
打开文件
src/App.js -
Import the SPA's public URI from the SPA's environment variables
code language-javascript const { REACT_APP_PUBLIC_URI } = process.env; function App() { ... } -
Prefix the WKND logo
<img src=.../>withREACT_APP_PUBLIC_URIto force resolution against the SPA.code language-html <img src={REACT_APP_PUBLIC_URI + '/' + logo} className="logo" alt="WKND Logo"/> -
Do the same for loading image in
src/components/Loading.jscode language-javascript 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>); } } -
And for the two instances of the back button in
src/components/AdventureDetails.jscode language-javascript const { REACT_APP_PUBLIC_URI } = process.env; function AdventureDetail(props) { ... render() { <img className="Backbutton-icon" src={REACT_APP_PUBLIC_URI + '/' + backIcon} alt="Return" /> } }
The App.js, Loading.js, and AdventureDetails.js files should look like:
AEM Responsive Grid
To support SPA Editor's layout mode for editable areas in the SPA, we must integrate AEM's Responsive Grid CSS into the SPA. Don't worry - this grid system is only applicable to the editable containers, and you can use your grid system of choice to drive the layout of the rest of your SPA.
Add the AEM Responsive Grid SCSS files to the SPA.
-
在IDE中打开SPA项目
-
Download and copy the following two files into
src/styles- _grid.scss
- AEM响应式网格SCSS生成器
- _网格 — 初始化.scss
- 使用SPA的特定断点(桌面和移动设备)和列(12)调用
_grid.scss。
- 使用SPA的特定断点(桌面和移动设备)和列(12)调用
- _grid.scss
-
打开
src/App.scss并导入./styles/grid-init.scsscode language-scss ... @import './styles/grid-init'; ...
_grid.scss和_grid-init.scss文件应类似于:
现在,SPA包含了为添加到AEM容器中的组件支持AEM布局模式所需的CSS。
实用程序类
将以下实用程序类复制到您的React应用程序项目中。
- RoutedLink.js到
~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app/src/components/editable/core/RoutedLink.js - EditorPlaceholder.js到
~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app/src/components/editable/core/util/EditorPlaceholder.js - withConditionalPlaceholder.js到
~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app/src/components/editable/core/util/withConditionalPlaceholder.js - withStandardBaseCssClass.js至
~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app/src/components/editable/core/util/withStandardBaseCssClass.js
启动SPA
现在,SPA已引导以与AEM集成,让我们运行SPA并查看其外观!
-
在命令行中,导航到SPA项目的根
-
使用普通命令启动SPA(如果尚未启动)
code language-shell $ cd ~/Code/aem-guides-wknd-graphql/remote-spa-tutorial/react-app $ npm install $ npm run start -
浏览http://localhost:3000上的SPA。 一切应该看起来不错!
在http://localhost:3000
在AEM SPA编辑器中打开SPA
在http://localhost:3000上运行SPA时,让我们使用AEM SPA编辑器将其打开。 在SPA中尚无法编辑任何内容,这仅验证AEM中的SPA。
-
登录AEM Author
-
导航到站点> WKND应用程序>我们> en
-
选择 WKND应用程序主页 并点按编辑,此时将显示SPA。
-
使用右上角的模式切换器切换到预览
-
在SPA周围单击
在http://localhost:3000
上运行的SPA
恭喜!
您已引导远程SPA使其与AEM SPA Editor兼容! 您现在知道如何:
- 将AEM SPA编辑器JS SDK npm依赖项添加到SPA项目
- 配置SPA的环境变量
- 将ModelManager API与SPA集成
- 为SPA设置内部代理,以便它将相应的内容请求路由到AEM
- 解决在SPA Editor上下文中解析静态SPA资源的问题
- 添加AEM的响应式网格CSS以支持AEM可编辑容器中的布局
后续步骤
现在,我们已经达到了与AEM SPA Editor兼容的基准,我们可以开始引入可编辑区域。 我们首先看一下如何在SPA中放置固定可编辑组件。