客户端库和前端工作流 client-side-libraries
了解如何使用客户端库或 clientlibs 为 Adobe Experience Manager (AEM) Sites 实施部署和管理 CSS 和 JavaScript。本教程还介绍了如何将 ui.frontend 模块,即一个解耦的 webpack 项目,集成到端到端构建过程中。
先决条件 prerequisites
查看设置本地开发环境所需的工具和说明。
还建议查看组件基础知识教程,了解客户端库和 AEM 的基础知识。
入门项目
签出作为本教程构建基础的基线代码:
-
从 GitHub 签出
tutorial/client-side-libraries-start
分支code language-shell $ cd aem-guides-wknd $ git checkout tutorial/client-side-libraries-start
-
运用您的 Maven 技能将代码库部署到本地 AEM 实例:
code language-shell $ mvn clean install -PautoInstallSinglePackage
note note NOTE 如果使用 AEM 6.5 或 6.4,请将 classic
配置文件附加到任何 Maven 命令。code language-shell $ mvn clean install -PautoInstallSinglePackage -Pclassic
您可以随时在 GitHub 上查看完成的代码,或者切换到分支 tutorial/client-side-libraries-solution
将代码签出到本地。
目标
- 了解如何通过可编辑模板将客户端库包含到页面上。
- 了解如何使用
ui.frontend
模块和 webpack 开发服务器进行专门的前端开发。 - 了解将已编译的 CSS 和 JavaScript 交付到 Sites 实施的端到端工作流。
您要构建什么 what-build
在本章中,您将为 WKND 网站和文章页面模板添加一些基准样式,使实施更接近 UI 设计模型。您可以使用高级前端工作流将 webpack 项目集成到 AEM 客户端库中。
应用了基准样式的文章页面
背景 background
客户端库提供了一种组织和管理 AEM Sites 实施所需的 CSS 和 JavaScript 文件的机制。客户端库或 clientlibs 的基本目标是:
- 将 CSS/JS 存储在小的单独文件中,以方便开发和维护
- 有组织、有条理地管理对第三方框架的依赖项
- 将 CSS/JS 连接成一个或两个请求,最大限度地减少客户端请求的数量。
有关使用客户端库的更多信息请参见此处。
客户端库确实存在一些限制。最需要注意的是对 Sass、LESS 和 TypeScript 等流行的前端语言的支持有限。在本教程中,我们来看一看 ui.frontend 模块如何帮助解决这个问题。
将入门代码库部署到本地 AEM 实例,然后导航到 http://localhost:4502/editor.html/content/wknd/us/en/magazine/guide-la-skateparks.html。这个页面没有样式。现在我们来为 WKND 品牌实施客户端库,以将 CSS 和 JavaScript 添加到页面中。
客户端库组织 organization
接下来,我们来看一下 AEM 项目原型生成的客户端库的组织。
客户端库组织和页面包含的高级示意图
-
使用 VSCode 或其他 IDE 打开 ui.apps 模块。
-
展开路径
/apps/wknd/clientlibs
,查看原型生成的客户端库。下一节将更详细地说明这些客户端库。
-
下表总结了客户端库。有关包含客户端库的更多详细信息请参见此处。
table 0-row-3 1-row-3 2-row-3 3-row-3 4-row-3 名称 描述 注释 clientlib-base
WKND 网站运行所需的 CSS 和 JavaScript 基础级别 嵌入核心组件客户端库 clientlib-grid
生成布局模式所需的 CSS,使其能工作。 移动设备/平板电脑的断点可以在此处配置 clientlib-site
包含 WKND 网站的网站特有主题 由 ui.frontend
模块生成clientlib-dependencies
嵌入任何第三方依赖项 由 ui.frontend
模块生成 -
注意
clientlib-site
和clientlib-dependencies
在源控制中被忽略。这是特意设计的,因为它们在构建时由ui.frontend
模块生成。
更新基础样式 base-styles
接下来,更新在 ui.frontend 模块中定义的基础样式。ui.frontend
模块中的文件会生成其中包含网站主题和任何第三方依赖项的 clientlib-site
和 clientlib-dependecies
库。
客户端库不支持更高级的语言,例如 Sass 或 TypeScript。有几种开源工具,例如 NPM 和 webpack,可以加速和优化前端开发。ui.frontend 模块的目标是能够使用这些工具管理大多数前端源文件。
-
打开 ui.frontend 模块,然后导航至
src/main/webpack/site
。 -
打开文件
main.scss
main.scss
是ui.frontend
模块中 Sass 文件的入口点。它包含_variables.scss
文件,其中包含一系列可在项目中所有不同 Sass 文件中使用的品牌变量。_base.scss
文件也包含在内,定义了 HTML 元素的一些基本样式。正则表达式包含src/main/webpack/components
中各个组件的样式。另一个正则表达式包含src/main/webpack/site/styles
中的文件。 -
查看文件
main.ts
。它包含main.scss
以及用于收集项目中任何.js
或.ts
文件的正则表达式。webpack 配置文件使用此入口点作为整个ui.frontend
模块的入口点。 -
查看
src/main/webpack/site/styles
下面的文件:这些文件样式用于模板中的全局元素,例如页眉、页脚和主要内容容器。这些文件中的 CSS 规则针对不同的 HTML 元素
header
、main
和footer
。这些 HTML 元素由上一章页面和模板中的策略定义。 -
展开
src/main/webpack
中的components
文件夹,查看文件。每个文件都映射到一个核心组件,例如折叠组件。每个核心组件都通过块元素修饰符或 BEM 符号构建,以便更轻松地确定使用某个特定的 CSS 类应用样式规则。
/components
下面的文件已被 AEM 项目原型去除,每个组件都有不同的 BEM 规则。 -
下载 WKND 基础样式 wknd-base-styles-src-v3.zip,然后将文件 解压缩。
为了加速教程,提供了几个在核心组件和文章页面模板结构基础上实施 WKND 品牌的 Sass 文件。
-
用上一步中的文件覆盖
ui.frontend/src
的内容。zip 的内容应覆盖以下文件夹:code language-plain /src/main/webpack /components /resources /site /static
在更改的文件中查看 WKND 样式实施的详细信息。
查看 ui.frontend 集成 ui-frontend-integration
作为 ui.frontend 模块中内置的一个关键集成件,aem-clientlib-generator 从 webpack/npm 项目中获取已编译的 CSS 和 JS 工件,将它们转换为 AEM 客户端库。
AEM 项目原型会自动设置这个集成。接下来看一下它如何工作。
-
打开命令行终端,使用
npm install
命令安装 ui.frontend 模块:code language-shell $ cd ~/code/aem-guides-wknd/ui.frontend $ npm install
note note NOTE npm install
只需要运行一次,例如在新克隆或生成项目之后。 -
打开
ui.frontend/package.json
,在 scripts start 命令中添加--env writeToDisk=true
。code language-json { "scripts": { "start": "webpack-dev-server --open --config ./webpack.dev.js --env writeToDisk=true", } }
-
运行以下命令,在 watch 模式中启动 webpack 开发服务器:
code language-shell $ npm run watch
-
该命令会编译
ui.frontend
模块中的源文件,并将更改与 http://localhost:4502 的 AEM 同步code language-shell + jcr_root/apps/wknd/clientlibs/clientlib-site/js/site.js + jcr_root/apps/wknd/clientlibs/clientlib-site/js + jcr_root/apps/wknd/clientlibs/clientlib-site + jcr_root/apps/wknd/clientlibs/clientlib-dependencies/css.txt + jcr_root/apps/wknd/clientlibs/clientlib-dependencies/js.txt + jcr_root/apps/wknd/clientlibs/clientlib-dependencies http://admin:admin@localhost:4502 > OK + jcr_root/apps/wknd/clientlibs/clientlib-site/css + jcr_root/apps/wknd/clientlibs/clientlib-site/js/site.js http://admin:admin@localhost:4502 > OK
-
命令
npm run watch
最终会填充 ui.apps 模块中的 clientlib-site 和 clientlib-dependencies,然后该模块自动与 AEM 同步。note note NOTE 还有一个 npm run prod
配置文件,用于压缩 JS 和 CSS。每当通过 Maven 触发 webpack 构建时,这都是标准编译。有关 ui.frontend 模块的更多详细信息请参阅此处。 -
查看
ui.frontend/dist/clientlib-site/site.css
下面的文件site.css
。这是基于 Sass 源文件进行编译的 CSS。 -
查看文件
ui.frontend/clientlib.config.js
。这是 npm 插件的配置文件 aem-clientlib-generator,它将/dist
的内容转换为客户端库,并将其移到ui.apps
模块。 -
查看 ui.apps 模块中的
site.css
文件,位于ui.apps/src/main/content/jcr_root/apps/wknd/clientlibs/clientlib-site/css/site.css
。这应该是 ui.frontend 模块中site.css
文件的完全相同的副本。现在它在 ui.apps 模块中,可以被部署到 AEM。note note NOTE 由于 clientlib-site 是在构建时使用 npm 或 maven 编译的,因此可以从 ui.apps 模块中的源控制中安全地忽略它。查看 ui.apps 下方的 .gitignore
文件。 -
在 AEM 中打开洛杉矶滑板运动场文章,位于:http://localhost:4502/editor.html/content/wknd/us/en/magazine/guide-la-skateparks.html。
您现在会看到文章的更新样式。您可能需要进行硬刷新来清除浏览器缓存的所有 CSS 文件。
它渐渐看起来更接近模型了!
note note NOTE 当从项目 mvn clean install -PautoInstallSinglePackage
的根目录触发 Maven 构建后,会自动执行上述构建 ui.frontend 代码并将其部署到 AEM 的步骤。
更改样式
接下来,在 ui.frontend
模块中做一个小改动,看看 npm run watch
如何自动将样式部署到本地 AEM 实例。
-
从
ui.frontend
模块打开文件:ui.frontend/src/main/webpack/site/_variables.scss
。 -
更新
$brand-primary
颜色变量:code language-scsss //== variables.css //== Brand Colors $brand-primary: $pink;
保存更改。
-
返回到浏览器,刷新 AEM 页面以查看更新:
-
将更改恢复为
$brand-primary
颜色,使用命令CTRL+C
停止 webpack 构建。
页面和模板包含 page-inclusion
接下来,我们来看一下如何在 AEM 页面中引用客户端库。Web 开发中的一个常见最佳做法是将 CSS 包含在 HTML 头部 <head>
,将 JavaScript 包含在关闭 </body>
标记之前。
-
浏览文章页面模板,位于 http://localhost:4502/editor.html/conf/wknd/settings/wcm/templates/article-page/structure.html
-
点击 页面信息 图标,然后在菜单中选择 页面策略,打开 页面策略 对话框。
页面信息 > 页面策略
-
请注意此处列出了
wknd.dependencies
和wknd.site
的类别。默认情况下,通过页面策略配置的客户端库被拆分,分别在页面头部包含 CSS,在正文末尾包含 JavaScript。您可以明确列出要加载在页面头部中的客户端库 JavaScript。wknd.dependencies
就是这种情况。note note NOTE 还可以使用 customheaderlibs.html
或customfooterlibs.html
脚本直接从页面组件引用wknd.site
或wknd.dependencies
。使用模板提供了灵活性,您可以选择每个模板使用哪些客户端库。例如,如果您有一个大型 JavaScript 库,只把它用在一个特定的模板上。 -
导航至使用 文章页面模板 创建的 洛杉矶滑板运动场 页面:http://localhost:4502/editor.html/content/wknd/us/en/magazine/guide-la-skateparks.html。
-
点击 页面信息 图标,然后在菜单中选择 以发布的形式查看,在 AEM 编辑器以外打开文章页面。
-
查看 http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html?wcmmode=disabled 的页面源代码,您应该能在
<head>
中看到以下客户端库引用:code language-html <head> ... <script src="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.lc-d41d8cd98f00b204e9800998ecf8427e-lc.min.js"></script> <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.lc-d41d8cd98f00b204e9800998ecf8427e-lc.min.css" type="text/css"> <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-site.lc-78fb9cea4c3a2cc17edce2c2b32631e2-lc.min.css" type="text/css"> ... </head>
请注意,客户端库使用代理
/etc.clientlibs
端点。您还应该看到页面底部包含的以下客户端库:code language-html ... <script src="/etc.clientlibs/wknd/clientlibs/clientlib-site.lc-7157cf8cb32ed66d50e4e49cdc50780a-lc.min.js"></script> <script src="/etc.clientlibs/wknd/clientlibs/clientlib-base.lc-53e6f96eb92561a1bdcc1cb196e9d9ca-lc.min.js"></script> ... </body>
note note NOTE 对于 AEM 6.5/6.4,客户端库不会自动压缩。请参阅 HTML 库管理器的文档,以启用压缩(推荐)。 note warning WARNING 在发布端非常重要的一点是,客户端库 不能 从 /apps 提供,因为出于安全原因,必须使用 Dispatcher 过滤器分区限制这个路径。客户端库的 allowProxy 属性确保了 CSS 和 JS 从 /etc.clientlibs 提供。
后续步骤 next-steps
了解如何使用 Experience Manager 的样式系统实施单独的样式以及重复使用核心组件。使用样式系统进行开发涵盖了使用样式系统通过品牌特有的 CSS 和模板编辑器的高级策略配置来扩展核心组件。
在 GitHub 上查看完成的代码,或者在本地 Git 分支 tutorial/client-side-libraries-solution
上查看和部署代码。
- 克隆 github.com/adobe/aem-wknd-guides 存储库。
- 签出
tutorial/client-side-libraries-solution
分支。
其他工具和资源 additional-resources
Webpack DevServer - 静态标记 webpack-dev-static
在前面的几个练习中,ui.frontend 模块中的几个 Sass 文件更新后,通过构建过程最终看到这些更改反映在 AEM 中。接下来,我们来看一种使用 webpack-dev-server 针对 静态 HTML 快速开发前端样式的技巧。
如果执行大多数样式和前端代码的专门的前端开发人员可能无法轻易访问 AEM 环境,那么这种技巧就非常方便。这个技巧还允许前端开发人员直接对 HTML 进行修改,然后将其交给 AEM 开发人员实施为组件。
-
复制“洛杉矶滑板运动场”文章页面的页面源代码,位于:http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html?wcmmode=disabled。
-
重新打开您的 IDE。从 AEM 复制标记,将其粘贴到
src/main/webpack/static
下方 ui.frontend 模块中的index.html
中。 -
编辑复制的标记,移除对 clientlib-site 和 clientlib-dependencies 的任何引用:
code language-html <!-- remove --> <script type="text/javascript" src="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.js"></script> <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.css" type="text/css"> <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-site.css" type="text/css"> ... <script type="text/javascript" src="/etc.clientlibs/wknd/clientlibs/clientlib-site.js"></script>
移除这些引用,因为 webpack 开发服务器会自动生成这些工件。
-
在 ui.frontend 模块中,在一个新的终端中运行以下命令以启动 webpack 开发服务器:
code language-shell $ cd ~/code/aem-guides-wknd/ui.frontend/ $ npm start > aem-maven-archetype@1.0.0 start code/aem-guides-wknd/ui.frontend > webpack-dev-server --open --config ./webpack.dev.js
-
现在会打开一个带有静态标记的新的浏览器窗口,位于:http://localhost:8080/。
-
编辑
src/main/webpack/site/_variables.scss
文件。将$text-color
规则替换成以下方式:code language-diff - $text-color: $black; + $text-color: $pink;
保存更改。
-
您会看到这些更改自动反映在浏览器中:http://localhost:8080。
-
查看
/aem-guides-wknd.ui.frontend/webpack.dev.js
文件。它包含用于启动 webpack-dev-server 的 webpack 配置。它代理来自本地运行的 AEM 实例的路径/content
和/etc.clientlibs
。图像和其他客户端库(不由 ui.frontend 代码管理)是通过这种方式提供的。note caution CAUTION 静态标记的图像源指向本地 AEM 实例上的一个实时图像组件。如果图像的路径发生变化、AEM 未启动或浏览器未登录本地 AEM 实例,图像就会被破坏。如果交给外部资源,也可以用静态引用替换图像。 -
您可以在命令行中输入
CTRL+C
,以 停止 webpack 服务器。
调试客户端库 debugging-clientlibs
如果使用不同的 类别 和 嵌入 方法来包含多个客户端库,修正错误可能就会很麻烦。AEM 提供了几种工具帮助纠错。最重要的工具之一是 重建客户端库,它会强制 AEM 重新编译任何 LESS 文件并生成 CSS。
-
转储库 - 列出在 AEM 实例中注册的客户端库。
<host>/libs/granite/ui/content/dumplibs.html
-
测试输出 - 允许用户根据类别查看客户端库包含的预期 HTML 输出。
<host>/libs/granite/ui/content/dumplibs.test.html
-
库依赖项验证 - 突出显示任何无法找到的依赖项或嵌入类别。
<host>/libs/granite/ui/content/dumplibs.validate.html
-
重建客户端库 - 允许用户强制 AEM 重建客户端库或使客户端库的缓存无效。此工具在使用 LESS 开发的情况下很有效,因为它可以强制 AEM 重新编译所生成的 CSS。一般来说,先使缓存无效,然后执行页面刷新的方法比重建库更有效。
<host>/libs/granite/ui/content/dumplibs.rebuild.html