客户端库和前端工作流

了解如何使用客户端库或客户端库来部署和管理Adobe Experience Manager(AEM)Sites实施的CSS和Javascript。 本教程还将介绍如何将ui.frontend模块(即解耦的webpack项目)集成到端到端构建过程中。

前提条件

查看设置本地开发环境所需的工具和说明。

另外,还建议查看组件基础知识教程,以了解客户端库和AEM的基础知识。

入门项目

注意

如果您成功完成了上一章,则可以重复使用该项目并跳过签出起始项目的步骤。

查看本教程构建的基行代码:

  1. 查看GitHub中的tutorial/client-side-libraries-start分支

    $ cd aem-guides-wknd
    $ git checkout tutorial/client-side-libraries-start
    
  2. 使用您的Maven技能将代码库部署到本地AEM实例:

    $ mvn clean install -PautoInstallSinglePackage
    
    注意

    如果使用AEM 6.5或6.4,请将classic配置文件附加到任何Maven命令。

    $ mvn clean install -PautoInstallSinglePackage -Pclassic
    

您始终可以在GitHub上查看完成的代码,或通过切换到分支tutorial/client-side-libraries-solution在本地签出代码。

目标

  1. 了解如何通过可编辑的模板将客户端库包含在页面中。
  2. 了解如何使用UI.Frontend模块和Web Pack开发服务器进行专用前端开发。
  3. 了解将编译的CSS和JavaScript交付到Sites实施的端到端工作流。

将构建的内容

在本章中,您将为WKND站点和文章页面模板添加一些基线样式,以便使实施更接近于UI设计模型。 您将使用高级前端工作流将WebPack项目集成到AEM客户端库中。

已完成的样式

应用基线样式的文章页面

背景

客户端库提供了一种机制来组织和管理AEM Sites实施所需的CSS和JavaScript文件。 客户端库或客户端库的基本目标包括:

  1. 将CSS/JS存储在小型离散文件中,以便更轻松地开发和维护
  2. 以有组织的方式管理对第三方框架的依赖
  3. 通过将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添加到页面。

客户端库组织

接下来,我们将探索由AEM项目原型生成的clientlibs的组织。

高级客户库组织

概要图客户端库组织和页面包含

注意

以下客户端库组织由AEM项目原型生成,但仅表示一个起点。 项目如何最终管理CSS和Javascript并将其交付到站点实施,可能会因资源、技能和要求而有显着差异。

  1. 使用VSCode或其他IDE打开​ui.apps​模块。

  2. 展开路径/apps/wknd/clientlibs以查看由原型生成的clientlib。

    ui.apps中的Clientlibs

    我们将在下面详细检查这些clientlib。

  3. 下表汇总了客户端库。 有关包括客户端库的更多详细信息,请参阅此处

    名称 描述 注释
    clientlib-base WKND Site正常运行所需的CSS和JavaScript的基本级别 嵌入核心组件客户端库
    clientlib-grid 生成使布局模式正常工作所必需的CSS。 可以在此处配置移动设备/平板电脑断点
    clientlib-site 包含WKND网站的特定站点主题 ui.frontend模块生成
    clientlib-dependencies 嵌入任何第三方依赖项 ui.frontend模块生成
  4. 请注意,从源代码管理中忽略clientlib-siteclientlib-dependencies。 这是特意设计的,因为这些将在构建时由ui.frontend模块生成。

更新基本样式

接下来,更新在​ui.frontend​模块中定义的基本样式。 ui.frontend模块中的文件将生成包含Site主题和任何第三方依赖项的clientlib-siteclientlib-dependecies库。

在支持语言(如SassTypeScript)方面,客户端库存在一些限制。 有许多开源工具,如NPMwebpack,可加速和优化前端开发。 ui.frontend​模块的目标是能够使用这些工具管理大多数前端源文件。

  1. 打开​ui.frontend​模块并导航到src/main/webpack/site

  2. 打开文件main.scss

    main.scss — 入口点

    main.scss 是模块中所有Sass文件的入口 ui.frontend 点。它将包含_variables.scss文件,其中包含一系列品牌变量,这些变量将用于项目中不同的Sass文件。 还包含_base.scss文件,它为HTML元素定义了一些基本样式。 正则表达式包含src/main/webpack/components下各个组件样式的所有样式。 另一个正则表达式包含src/main/webpack/site/styles下的所有文件。

    1. Inspect文件main.ts。 它包括main.scss和用于收集项目中任何.js.ts文件的正则表达式。 此入口点将由Webpack配置文件用作整个ui.frontend模块的入口点。
  3. Inspect src/main/webpack/site/styles下的文件:

    样式文件

    模板中全局元素(如页眉、页脚和主内容容器)的这些文件样式。 这些文件中的CSS规则针对不同的HTML元素headermainfooter。 这些HTML元素由上一章页面和模板中的策略定义。

  4. 展开src/main/webpack下的components文件夹,并检查文件。

    组件Sass文件

    每个文件都映射到核心组件,如折叠面板组件。 每个核心组件都使用块元素修饰符或BEM符号构建,以便更轻松地使用样式规则定位特定CSS类。 /components下的文件已由AEM Project Archetype删除,其中每个组件的BEM规则不同。

  5. 下载WKND基本样式​wknd-base-styles-src.zip​和​unzip​文件。

    WKND基样式

    为了加快本教程的进度,我们提供了多个Sass文件,这些文件将根据核心组件和文章页面模板的结构来实施WKND品牌。

  6. 使用上一步中的文件覆盖ui.frontend/src的内容。 zip文件的内容应会覆盖以下文件夹:

    /src/main/webpack
             /base
             /components
             /resources
    

    更改了文件

    Inspect已更改的文件,以查看WKND样式实施的详细信息。

Inspect ui.frontend集成

内置到​ui.frontend​模块aem-clientlib-generator的关键集成块会从Webpack/npm项目中获取已编译的CSS和JS工件,并将它们转换为AEM客户端库。

ui.frontend架构集成

AEM项目原型会自动设置此集成。 接下来,探索其工作方式。

  1. 打开命令行终端,然后使用npm install命令安装​ui.frontend​模块:

    $ cd ~/code/aem-guides-wknd/ui.frontend
    $ npm install
    
    注意

    npm install 只需在新克隆或生成项目后运行一次。

  2. 在同一终端中,使用npm run dev命令构建和部署​ui.frontend​模块:

    $ npm run dev
    
    注意

    您可能会收到类似“中的错误”的错误。/src/main/webpack/site/main.scss”。
    这通常是因为运行npm install后您的环境发生了更改。
    运行npm rebuild node-sass以修复问题。 如果安装在本地开发计算机上的npm版本与aem-guides-wknd/pom.xml文件中的Maven frontend-maven-plugin使用的版本不同,则会发生这种情况。 您可以通过修改pom文件中的版本以匹配本地版本来永久修复此问题,反之亦然。

  3. 命令npm run dev应构建并编译Webpack项目的源代码,并最终在​ui.apps​模块中填充​clientlib-site​和​clientlib-dependencies

    注意

    还有一个npm run prod配置文件,该配置文件将缩小JS和CSS。 每当通过Maven触发Web包内部版本时,这便是标准编译。 有关ui.frontend模块的更多详细信息,请访问此处

  4. Inspect ui.frontend/dist/clientlib-site/site.css下的文件site.css。 这是基于Sass源文件的编译CSS。

    分布式网站css

  5. Inspect文件ui.frontend/clientlib.config.js。 这是npm插件aem-clientlib-generator的配置文件,用于将/dist的内容转换为客户端库并将其移动到ui.apps模块。

  6. Inspect ui.apps​模块ui.apps/src/main/content/jcr_root/apps/wknd/clientlibs/clientlib-site/css/site.css中的文件site.css。 这应该是​ui.frontend​模块中site.css文件的相同副本。 现在,它位于​ui.apps​模块中,可以将其部署到AEM。

    ui.apps clientlib-site

    注意

    由于在构建期间使用​npm​或​maven​编译了​clientlib-site,因此可以从​ui.apps​模块的源代码控制中安全地忽略该值。 Inspect .gitignore文件,位于​ui.apps​下。

  7. 使用开发人员工具或Maven技能将clientlib-site库与AEM的本地实例同步。

    同步Clientlib站点

  8. 在AEM中打开LA Skatepark文章:http://localhost:4502/editor.html/content/wknd/us/en/magazine/guide-la-skateparks.html

    更新了文章的基本样式

    此时您应会看到文章的更新样式。 您可能需要进行硬刷新才能清除浏览器缓存的任何CSS文件。

    它开始越来越接近模型了!

    注意

    当从项目mvn clean install -PautoInstallSinglePackage的根触发Maven内部版本时,将自动执行上面为构建并部署ui.frontend代码到AEM所执行的步骤。

注意

对于所有项目,可能不需要使用​ui.frontend​模块。 ui.frontend​模块增加了额外的复杂性,如果不需要/希望使用这些高级前端工具(Sass、webpack、npm…),则可能不需要它。

页面和模板包含

接下来,让我们查看如何在AEM页面中引用clientlib。 Web开发中的常见最佳实践是,在结束</body>标记之前,将CSS包含在HTML标头<head>和JavaScript中。

  1. 在​ui.apps​模块中,导航到ui.apps/src/main/content/jcr_root/apps/wknd/components/page

    结构页面组件

    这是page组件,用于呈现WKND实施中的所有页面。

  2. 打开文件customheaderlibs.html。 请注意${clientlib.css @ categories='wknd.base'}行。 这表示类别为wknd.base的clientlib的CSS将通过此文件包含在内,实际上在所有页面的标题中包含​clientlib-base

  3. 更新customheaderlibs.html以包含对我们之前在​ui.frontend​模块中指定的Google字体样式的引用。

    <link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Asar&display=swap" rel="stylesheet">
    <sly data-sly-use.clientLib="/libs/granite/sightly/templates/clientlib.html"
     data-sly-call="${clientlib.css @ categories='wknd.base'}"/>
    
    <!--/* Include Context Hub */-->
    <sly data-sly-resource="${'contexthub' @ resourceType='granite/contexthub/components/contexthub'}"/>
    
  4. Inspect文件customfooterlibs.html。 此文件(如customheaderlibs.html)将被实施项目覆盖。 此处,行${clientlib.js @ categories='wknd.base'}表示​clientlib-base​中的JavaScript将包含在所有页面的底部。

  5. 使用开发人员工具或使用您的Maven技能将page组件导出到AEM服务器。

  6. 浏览位于http://localhost:4502/editor.html/conf/wknd/settings/wcm/templates/article-page/structure.html的文章页面模板

  7. 单击​页面信息​图标,然后在菜单中选择​页面策略​以打开​页面策略​对话框。

    文章页面模板菜单页面策略

    页面信息>页面策略

  8. 请注意,此处列出了wknd.dependencieswknd.site的类别。 默认情况下,通过“页面策略”配置的clientlib将进行拆分,以在页面标题中包含CSS,在正文末尾包含JavaScript。 如果需要,您可以明确地将clientlib JavaScript加载到页面标头中。 wknd.dependencies的情况如下。

    文章页面模板菜单页面策略

    注意

    也可以使用customheaderlibs.htmlcustomfooterlibs.html脚本直接从页面组件中引用wknd.sitewknd.dependencies,如我们之前在wknd.base clientlib中看到的。 通过使用模板,您可以根据需要选择每个模板使用的客户端库,这在一定程度上提供了灵活性。 例如,如果您有一个非常重的JavaScript库,该库将仅用于选定模板。

  9. 导航到使用​文章页面模板​创建的​LA滑板场​页面:http://localhost:4502/editor.html/content/wknd/us/en/magazine/guide-la-skateparks.html。 字体应该有所不同。

  10. 单击​页面信息​图标,然后在菜单中选择​查看已发布的项目 ,以在AEM编辑器外打开文章页面。

    查看已发布的项目

  11. 查看http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html?wcmmode=disabled的页面源,您应该能够在<head>中看到以下clientlib引用:

    <head>
    ...
    <link href="//fonts.googleapis.com/css?family=Source+Sans+Pro:400,600|Asar&display=swap" rel="stylesheet"/>
    <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-base.min.css" type="text/css">
    <script type="text/javascript" src="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.min.js"></script>
    <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-dependencies.min.css" type="text/css">
    <link rel="stylesheet" href="/etc.clientlibs/wknd/clientlibs/clientlib-site.min.css" type="text/css">
    ...
    </head>
    

    请注意,clientlibs使用代理/etc.clientlibs端点。 您还应会在页面底部看到以下clientlib包含项:

    ...
    <script type="text/javascript" src="/etc.clientlibs/wknd/clientlibs/clientlib-site.min.js"></script>
    <script type="text/javascript" src="/etc.clientlibs/wknd/clientlibs/clientlib-base.min.js"></script>
    ...
    </body>
    
    注意

    如果在6.5/6.4中跟踪,则客户端库将不会自动缩小。 请参阅HTML库管理器中的文档以启用缩小(推荐)

    警告

    在发布端,客户端库是​​从​**/apps**​提供的,这一点至关重要,因为出于安全原因,应使用Dispatcher筛选器部分限制此路径。 客户端库的allowProxy属性可确保CSS和JS是从​**/etc.clientlibs**​提供的。

Webpack DevServer — 静态标记

在前几个练习中,我们能够更新​ui.frontend​模块中的多个Sass文件,并通过构建过程最终看到这些更改反映在AEM中。 接下来,我们将看到利用webpack-dev-server的技术,以针对​static HTML快速开发我们的前端样式。

如果大多数样式和前端代码将由专门的前端开发人员执行,而该开发人员可能无法轻松访问AEM环境,则此技术会非常方便。 此技术还允许FED直接对HTML进行修改,然后将修改转交给AEM开发人员以作为组件实施。

  1. 复制位于http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html?wcmmode=disabled的LA滑板场文章页面的页面源。

  2. 重新打开IDE。 将从AEM复制的标记粘贴到​ui.frontend​模块中src/main/webpack/static下方的index.html中。

  3. 编辑复制的标记并删除对​clientlib-site​和​clientlib-dependencies​的任何引用:

    <!-- 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开发服务器将自动生成这些工件。

  4. 通过在​ui.frontend​模块中运行以下命令,从新终端启动Webpack开发服务器:

    $ 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
    
  5. 这应会在http://localhost:8080/处打开一个新的浏览器窗口,其中包含静态标记。

  6. 编辑文件src/main/webpack/site/_variables.scss。 将$text-color规则替换为:

    - $text-color:              $black;
    + $text-color:              $pink;
    

    保存更改。

  7. 您应会自动在http://localhost:8080上的浏览器中看到自动反映的更改。

    本地WebPack开发服务器更改

  8. 查看/aem-guides-wknd.ui.frontend/webpack.dev.js文件。 其中包含用于启动Webpack-dev-server的Webpack配置。 请注意,它将代理本地运行的AEM实例中的路径/content/etc.clientlibs。 这就是图像和其他clientlib(不由​ui.frontend​代码管理)的可用方式。

    注意

    静态标记的图像src指向本地AEM实例上的实时图像组件。 如果图像的路径发生更改、AEM未启动或浏览器未登录到本地AEM实例,则图像将显示为已损坏。 如果切换到外部资源,则还可以使用静态引用替换图像。

  9. 通过键入CTRL+C,可以从命令行中​停止 Webpack服务器。

Webpack DevServer - Watch和aemsync

另一种技术是让Node.js监视ui.frontend模块中对src文件进行的任何文件更改。 每当文件发生更改时,它都会快速编译客户端库,并使用aemsync npm模块将更改同步到正在运行的AEM服务器。

  1. 通过在​ui.frontend​模块中运行以下命令,从新终端以​watch​模式启动Webpack开发服务器:

    $ cd ~/code/aem-guides-wknd/ui.frontend/
    $ npm run watch
    
  2. 此操作将编译src文件,并将更改与位于http://localhost:4502的AEM同步

    + 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
    
  3. 导航到AEM和LA Skateparks文章:http://localhost:4502/content/wknd/us/en/magazine/guide-la-skateparks.html?wcmmode=disabled

    部署到AEM的更改

    更改应部署到AEM。 出现轻微延迟,您必须手动刷新浏览器才能查看更新。 但是,如果您要使用新组件和对话框创作,直接在AEM中查看更改会很有用。

  4. 将更改还原为_variables.scss并保存更改。 稍有延迟后,应再次将更改与AEM的本地实例同步。

  5. 停止Webpack开发服务器,并从项目的根中执行完整的Maven内部版本:

    $ cd aem-guides-wknd
    $ mvn clean install -PautoInstallSinglePackage
    

    同样,会编译ui.frontend模块,将其转换为clientlibraries,并通过ui.apps模块部署到AEM。 但这次Maven为我们做了一切。

恭喜!

恭喜,文章页面现在具有一些与WKND品牌匹配的一致样式,并且您已经熟悉​ui.frontend​模块!

后续步骤

了解如何使用Experience Manager的样式系统实施单个样式并重复使用核心组件。 使用样式系统进 行开发,包括使用样式系统通过特定于品牌的CSS和模板编辑器的高级策略配置来扩展核心组件。

GitHub上查看完成的代码,或在Git浏览器tutorial/client-side-libraries-solution上的本地查看并部署代码。

  1. 克隆github.com/adobe/aem-wknd-guides存储库。
  2. 查看tutorial/client-side-libraries-solution分支。

其他工具和资源

aemfed

aemfedis是一款开源命令行工具,可用于加快前端开发。它由aemsyncBrowsersyncSling Log Tracer提供支持。

在高级别​aemfed,设计用于侦听​ui.apps​模块中的文件更改,并自动将它们直接同步到正在运行的AEM实例。 根据这些更改,本地浏览器将自动刷新,从而加快前端开发。 此外,它还与Sling Log Tracer一起构建,可自动在终端中直接显示任何服务器端错误。

如果您在​ui.apps​模块中执行大量工作、修改HTL脚本并创建自定义组件,则​aemfed​可以成为非常强大的使用工具。 完整文档可在此处找到。

调试客户端库

使用​类别​和​嵌入​的不同方法来包含多个客户端库,可能会麻烦进行故障诊断。 AEM会提供一些可帮助解决此问题的工具。 最重要的工具之一是​重建客户端库,这将强制AEM重新编译任何LESS文件并生成CSS。

  • 转储库 — 列出在AEM实例中注册的所有客户端库。 <host>/libs/granite/ui/content/dumplibs.html

  • 测试输出 — 允许用户根据类别查看clientlib包含的预期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

重建客户端库

在此页面上