使用客户端库

现代网站严重依赖由复杂的JavaScript和CSS代码驱动的客户端处理。 组织和优化此代码的服务可能是一个复杂的问题。

为帮助解决此问题,AEM提供​客户端库文件夹,允许您将客户端代码存储在存储库中,将其组织到类别中,并定义何时以及如何将每个类别代码提供给客户端。 然后,客户端库系统负责在最终网页中生成正确的链接以加载正确的代码。

客户端库在AEM中的工作方式

在页面的HTML中包含客户端库(即JS或CSS文件)的标准方法是,在该页面的JSP中包含<script><link>标记,其中包含该文件的路径。 例如,

...
<head>
   ...
   <script type="text/javascript" src="/etc/clientlibs/granite/jquery/source/1.8.1/jquery-1.8.1.js?lang=zh-Hans"></script>
   ...
</head>
...

虽然此方法在AEM中有效,但在页面及其组成组件变得复杂时,可能会导致问题。 在这种情况下,同一JS库的多个副本可能会包含在最终HTML输出中。 要避免这种情况并允许客户端库的逻辑组织,AEM使用​客户端库文件夹

客户端库文件夹是类型cq:ClientLibraryFolder的存储库节点。 它在CND记号中的定义是

[cq:ClientLibraryFolder] > sling:Folder
  - dependencies (string) multiple
  - categories (string) multiple
  - embed (string) multiple
  - channels (string) multiple

默认情况下,cq:ClientLibraryFolder节点可以放置在存储库的/apps/libs/etc子树中的任意位置(这些默认值以及其他设置可以通过系统控制台的​Adobe花岗岩HTML库管理器​面板进行控制)。

每个cq:ClientLibraryFolder都会填入一组JS和/或CSS文件,以及一些支持文件(见下文)。 cq:ClientLibraryFolder的属性配置如下:

  • categories:标识今秋JS和/或CSS文件集所属的 cq:ClientLibraryFolder 类别。categories属性具有多值,允许库文件夹属于多个类别的一部分(请参见下面,了解这有何用)。

  • dependencies:这是此库文件夹所依赖的其他客户端库类别的列表。例如,给定两个cq:ClientLibraryFolder节点FG,如果F中的文件需要G中的另一个文件才能正常工作,则Gcategories中的至少一个应位于Fdependencies中。

  • embed:用于嵌入来自其他库的代码。如果节点F嵌入节点G和H,则生成的HTML将是节点G和H中的内容集中。

  • allowProxy:如果客户端库位于下 /apps方,则此属性允许通过代理servlet访问它。请参阅下面的查找客户端库文件夹和使用代理客户端库Servlet

引用客户端库

由于HTL是开发AEM站点的首选技术,因此应使用HTL在AEM中包含客户端库。 但是,也可以使用JSP进行此操作。

使用HTL

在HTL中,客户端库通过AEM提供的帮助模板加载,可通过 data-sly-use访问该模板。 此文件中有三个模板,可通过 data-sly-call调用它们:

  • css —— 仅加载引用的客户端库的CSS文件。
  • js —— 仅加载引用的客户端库的JavaScript文件。
  • all -加载引用的客户端库的所有文件(CSS和JavaScript)。

每个帮助程序模板都需要一个categories选项来引用所需的客户端库。 该选项可以是字符串值的数组,也可以是包含逗号分隔值列表的字符串。

有关更多详细信息和用法示例,请参阅文档HTML模板语言入门

使用JSP

向JSP代码中添加ui:includeClientLib标记,以在生成的HTML页面中添加指向客户端库的链接。 要引用库,请使用ui:includeClientLib节点的categories属性的值。

<%@taglib prefix="ui" uri="https://www.adobe.com/taglibs/granite/ui/1.0" %>
<ui:includeClientLib categories="<%= categories %>" />

例如,/etc/clientlibs/foundation/jquery节点的类型为cq:ClientLibraryFolder,其类别属性为cq.jquery。 JSP文件中的以下代码引用库:

<ui:includeClientLib categories="cq.jquery"/>

生成的HTML页包含以下代码:

<script type="text/javascript" src="/etc/clientlibs/foundation/jquery.js?lang=zh-Hans"></script>

有关包括筛选JS、CSS或主题库的属性在内的完整信息,请参阅ui:includeClientLib

注意

<cq:includeClientLib>过去常用于包含客户端库,自AEM 5.6起已弃用它。应 <ui:includeClientLib> 如上所述使用它。

创建客户端库文件夹

创建一个cq:ClientLibraryFolder节点以定义JavaScript和层叠样式表库,并使它们可用于HTML页面。 使用节点的categories属性标识它所属的库类别。

该节点包含一个或多个在运行时合并为单个JS和/或CSS文件的源文件。 生成的文件的名称是扩展名为.js.css的节点名称。 例如,名为cq.jquery的库节点生成名为cq.jquery.jscq.jquery.css的生成文件。

客户端库文件夹包含以下项目:

  • 要合并的JS和/或CSS源文件。

  • 支持CSS样式的资源,如图像文件。

    注意: 您可以使用子文件夹来组织源文件。

  • 一个js.txt文件和/或一个css.txt文件,用于标识要合并到生成的JS和/或CSS文件中的源文件。

clientlibarch

有关构件的客户端库特定要求的信息,请参阅使用和扩展构件

Web客户端必须具有访问cq:ClientLibraryFolder节点的权限。 您还可以从存储库的安全区域中显示库(请参阅下面的“从其他库嵌入代码”)。

覆盖/lib中的库

位于/apps下的客户端库文件夹优先于位于/libs中的同名文件夹。 例如,/apps/cq/ui/widgets优先于/libs/cq/ui/widgets。 当这些库属于同一类别时,将使用/apps下的库。

查找客户端库文件夹并使用代理客户端库Servlet

在以前的版本中,客户端库文件夹位于存储库中/etc/clientlibs的下方。 这仍受支持,但建议现在在/apps下放置客户端库。 这是在其他脚本附近找到客户端库,通常位于/apps/libs下。

注意

客户端库文件夹下的静态资源必须位于名为​resources​的文件夹中。 如果文件夹​resources​下没有静态资源(如图像),则无法在发布实例上引用它。 以下是一个示例:http://localhost:4503/etc.clientlibs/geometrixx/components/clientlibs/resources/example.gif

注意

为了更好地从内容和配置中隔离代码,建议在/apps下找到客户端库,并通过/etc.clientlibs利用allowProxy属性来公开它们。

为了使/apps下的客户端库可访问,使用代理服务器。 ACL仍然强制在客户端库文件夹上,但如果allowProxy属性设置为true,则servlet允许通过/etc.clientlibs/读取内容。

静态资源只能通过代理访问,如果它位于客户端库文件夹下的资源下。

例如:

  • /apps/myproject/clientlibs/foo中有一个clientlib
  • /apps/myprojects/clientlibs/foo/resources/icon.png中有静态图像

然后,将foo上的allowProxy属性设置为true。

  • 然后,您可以请求/etc.clientlibs/myprojects/clientlibs/foo.js
  • 然后,可通过/etc.clientlibs/myprojects/clientlibs/foo/resources/icon.png引用图像
注意

使用代理客户端库时,AEM Dispatcher配置可能需要更新以确保允许具有扩展客户端库的URI。

注意

Adobe建议在/apps下找到客户端库,并使用代理servlet使其可用。 但是,请记住,最佳做法仍然要求公共站点不要包含直接通过/apps/libs路径提供服务的任何内容。

创建客户端库文件夹

  1. 在Web浏览器中打开CRXDE Lite(http://localhost:4502/crx/de)。

  2. 选择要查找客户端库文件夹的文件夹,然后单击​创建>创建节点

  3. 输入库文件的名称,在“类型”列表中选择cq:ClientLibraryFolder。 单击​确定,然后单击​保存全部

  4. 要指定库所属的类别或类别,请选择cq:ClientLibraryFolder节点,添加以下属性,然后单击​全部保存:

    • 名称:类别
    • 类型:字符串
    • 值:类别名称
    • 多:选择
  5. 通过任何方式将源文件添加到库文件夹。 例如,使用WebDav客户端复制文件,或创建文件并手动创作内容。

    注意:如 果需要,可以在子文件夹中组织源文件。

  6. 选择客户端库文件夹,然后单击​创建>创建文件

  7. 在“文件名”框中,键入以下文件名之一,然后单击“确定”:

    • js.txt: 使用此文件名生成JavaScript文件。
    • css.txt: 使用此文件名生成层叠样式表。
  8. 打开文件并键入以下文本以标识源文件路径的根:

    #base=[root]

    [root]替换为包含源文件的文件夹(相对于TXT文件)的路径。 例如,当源文件与TXT文件位于同一文件夹中时,请使用以下文本:

    #base=.

    以下代码将根设置为cq:ClientLibraryFolder节点下名为mobile的文件夹:

    #base=mobile

  9. #base=[root]下面的行中,键入源文件相对于根的路径。 将每个文件名放在单独的行上。

  10. 单击​保存全部

链接到依赖项

当客户端库文件夹中的代码引用其他库时,将其他库标识为依赖关系。 在JSP中,引用客户端库文件夹的ui:includeClientLib标记会导致HTML代码包含指向生成的库文件以及依赖项的链接。

依赖关系必须是另一个cq:ClientLibraryFolder。 要标识依赖关系,请向cq:ClientLibraryFolder节点添加一个属性,其中包含以下属性:

  • 名称:依 赖项
  • 类型:字 符串[]
  • 值: 当前库文件夹所依赖的cq:ClientLibraryFolder节点的类别属性值。

例如,/ etc/clientlibs/myclientlibs/publicmaincq.jquery库具有依赖关系。 引用主客户端库的JSP生成包含以下代码的HTML:

<script src="/etc/clientlibs/foundation/cq.jquery.js?lang=zh-Hans" type="text/javascript">
<script src="/etc/clientlibs/mylibs/publicmain.js?lang=zh-Hans" type="text/javascript">

从其他库嵌入代码

可以将客户端库中的代码嵌入到另一个客户端库中。 在运行时,嵌入库生成的JS和CSS文件包括嵌入库的代码。

嵌入代码对于提供对存储在存储库的安全区域中的库的访问非常有用。

特定于应用程序的客户端库文件夹

最好将所有与应用程序相关的文件保留在/app下的其应用程序文件夹中。 拒绝网站访客访问/app文件夹也是最佳做法。 为了同时满足这两种最佳实践,请在/etc文件夹下创建一个客户端库文件夹,它嵌入位于/app下的客户端库。

使用类别属性标识要嵌入的客户端库文件夹。 要嵌入库,请使用以下属性属性向嵌入cq:ClientLibraryFolder节点添加属性:

  • 名称:嵌
  • 类型:字 符串[]
  • 值: 要嵌入的节点的类别属 cq:ClientLibraryFolder 性的值。

使用嵌入最小化请求

在某些情况下,您可能会发现,发布实例为典型页面生成的最终HTML包含相对大量的<script>元素,尤其是当站点使用Client Context信息进行分析或定位时。 例如,在未优化的项目中,您可能会在页面的HTML中找到以下系列<script>元素:

<script type="text/javascript" src="/etc/clientlibs/granite/jquery.js?lang=zh-Hans"></script>
<script type="text/javascript" src="/etc/clientlibs/granite/utils.js?lang=zh-Hans"></script>
<script type="text/javascript" src="/etc/clientlibs/granite/jquery/granite.js?lang=zh-Hans"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/jquery.js?lang=zh-Hans"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/shared.js?lang=zh-Hans"></script>
<script type="text/javascript" src="/etc/clientlibs/foundation/personalization/kernel.js?lang=zh-Hans"></script>

在这种情况下,将所有所需的客户端库代码合并到单个文件中,以减少页面加载时来回请求的数量,这是非常有用的。 为此,您可以使用cq:ClientLibraryFolder节点的embed属性,将所需的库embed导入应用程序特定的客户端库。

以下客户端库类别包含在AEM中。 您应仅嵌入特定站点运行所需的内容。 但是,您应保持此处列出的顺序:

  1. browsermap.standard
  2. browsermap
  3. jquery-ui
  4. cq.jquery.ui
  5. personalization
  6. personalization.core
  7. personalization.core.kernel
  8. personalization.clientcontext.kernel
  9. personalization.stores.kernel
  10. personalization.kernel
  11. personalization.clientcontext
  12. personalization.stores
  13. cq.collab.comments
  14. cq.collab.feedlink
  15. cq.collab.ratings
  16. cq.collab.toggle
  17. cq.collab.forum
  18. cq.cleditor

CSS文件中的路径

嵌入CSS文件时,生成的CSS代码使用相对于嵌入库的资源的路径。 例如,可公开访问的库/etc/client/libraries/myclientlibs/publicmain嵌入了/apps/myapp/clientlib客户端库:

screen_shot_2012-05-29at20122pm

main.css文件包含以下样式:

body {
  padding: 0;
  margin: 0;
  background: url(images/bg-full.jpg) no-repeat center top;
  width: 100%;
}

publicmain节点生成的CSS文件包含以下样式,使用原始图像的URL:

body {
  padding: 0;
  margin: 0;
  background: url(../../../apps/myapp/clientlib/styles/images/bg-full.jpg) no-repeat center top;
  width: 100%;
}

为特定移动组使用库

使用客户端库文件夹的channels属性来标识使用该库的移动组。 当为不同的设备功能设计相同类别的库时,channels属性很有用。

要将客户端库文件夹与设备组关联,请向cq:ClientLibraryFolder节点添加以下属性:

  • 名称: 渠道
  • 类型:字 符串[]
  • 值: 移动组的名称。要将库文件夹从组中排除,请在名称前加感叹号(“!”)。

例如,下表列表了cq.widgets类别的每个客户端库文件夹的channels属性的值:

客户端库文件夹 渠道属性的值
/libs/cq/analytics/widgets !touch
/libs/cq/analytics/widgets/themes/default !touch
/libs/cq/cloudserviceconfigs/widgets !touch
/libs/cq/searchpromote/widgets !touch
/libs/cq/searchpromote/widgets/themes/default [无值]
/libs/cq/touch/widgets touch
/libs/cq/touch/widgets/themes/default touch
/libs/cq/ui/widgets !touch
/libs/cq/ui/widgets/themes/default !touch

使用预处理器

AEM支持可插拔的预处理器,并附带对YUI Compressor的CSS和JavaScript支持以及Google Closure Compiler(GCC)的JavaScript支持,YU设置为AEM默认预处理器。

可插拔预处理器允许灵活使用,包括:

  • 定义可处理脚本源的脚本处理器
  • 处理器可配置选项
  • 处理器可用于微型化,也可用于非微型化情况
  • clientlib可以定义要使用哪个处理器
注意

默认情况下,AEM使用YUI压缩程序。 有关一列表已知问题,请参阅YUI Compressor GitHub文档。 对于特定客户端,切换到GCC压缩程序可解决使用YUI时观察到的一些问题。

注意

不要将精简库放在客户端库中。 而是提供原始库,如果需要进行微型化,请使用预处理器的选项。

使用

您可以选择根据客户端库或系统范围配置预处理器配置。

  • 在clientlibrary节点上添加多值属性cssProcessorjsProcessor

  • 或通过​HTML库管理器 OSGi配置定义系统默认配置

clientlib节点上的预处理器配置优先于OSGI配置。

格式和示例

格式

config:= mode ":" processorName options*;
mode:= "default" | "min";
processorName := "none" | <name>;
options := ";" option;
option := name "=" value;

YUI压缩程序,用于CSS微型化,GCC,用于JS

cssProcessor: ["default:none", "min:yui"]
jsProcessor: ["default:none", "min:gcc;compilationLevel=advanced"]

Typescript to Preprocess, Then GCC to Minify and Obfuscate

jsProcessor: [
   "default:typescript",
   "min:typescript", 
   "min:gcc;obfuscate=true"
]

其他GCC选项

failOnWarning (defaults to "false")
languageIn (defaults to "ECMASCRIPT5")
languageOut (defaults to "ECMASCRIPT5")
compilationLevel (defaults to "simple") (can be "whitespace", "simple", "advanced")

有关GCC选项的更多详细信息,请参阅GCC文档

设置系统默认迷你符

在AEM中,YUI设置为默认的minifier。 要将此更改为GCC,请执行以下步骤。

  1. 转到位于http://localhost:4502/system/console/configMgr的Apache Felix Config Manager

  2. 查找并编辑​AdobeGranite HTML库管理器

  3. 启用​Minify​选项(如果尚未启用)。

  4. 将值​JS处理器默认配置​设置为min:gcc

    如果以分号分隔,则可以传递选项,例如min:gcc;obfuscate=true

  5. 单击​保存​以保存更改。

调试工具

AEM提供了多种工具用于调试和测试客户端库文件夹。

请参阅嵌入的文件

要跟踪嵌入代码的来源,或确保嵌入的客户端库生成预期结果,您可以在运行时查看嵌入的文件名称。 要查看文件名,请在网页的URL后面附加debugClientLibs=true参数。 生成的库包含@import语句,而不是嵌入代码。

在前一个从其他库嵌入代码部分的示例中,/etc/client/libraries/myclientlibs/publicmain客户端库文件夹嵌入了/apps/myapp/clientlib客户端库文件夹。 将参数追加到网页后,将在网页的源代码中生成以下链接:

<link rel="stylesheet" href="/etc/clientlibs/mycientlibs/publicmain.css?lang=zh-Hans">

打开publicmain.css文件会显示以下代码:

@import url("/apps/myapp/clientlib/styles/main.css");
  1. 在Web浏览器的地址框中,将以下文本追加到HTML的URL:

    ?debugClientLibs=true

  2. 载入页面时,视图页面源。

  3. 单击作为链接元素的href提供的链接以打开文件并视图源代码。

发现客户端库

/libs/cq/granite/components/dumplibs/dumplibs组件会生成有关系统上所有客户端库文件夹的信息页面。 /libs/granite/ui/content/dumplibs节点将组件作为资源类型。 要打开页面,请使用以下URL(根据需要更改主机和端口):

https://<host>:<port>/libs/granite/ui/content/dumplibs.test.html

信息包括库路径和类型(CSS或JS)以及库属性的值,如类别和依赖关系。 页面上的后续表显示了每个类别和渠道中的库。

请参阅生成的输出

dumplibs组件包含一个测试选择器,它显示为ui:includeClientLib标记生成的源代码。 该页面包含js、css和主题属性的不同组合的代码。

  1. 使用以下方法之一打开“测试输出”页:

    • dumplibs.html页面中,单击​单击此处以输出测试​文本中的链接。

    • 在Web浏览器中打开以下URL(根据需要使用不同的主机和端口):

      • http://<host>:<port>/libs/granite/ui/content/dumplibs.html

    默认页显示没有类别属性值的标记的输出。

  2. 要查看类别的输出,请键入客户端库的categories属性值,然后单击​提交查询

为开发和生产配置库处理

HTML库管理器服务处理cq:ClientLibraryFolder标记,并在运行时生成库。 环境、开发或生产类型决定了您应如何配置服务:

  • 提高安全性:禁用调试
  • 提高性能:删除空白并压缩库。
  • 提高可读性:包括空格,不压缩。

有关配置服务的信息,请参阅AEM HTML Library Manager

On this page

Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Summit Banner

A virtual event April 27-28.

Expand your skills and get inspired.

Register for free
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now
Adobe Maker Awards Banner

Time to shine!

Apply now for the 2021 Adobe Experience Maker Awards.

Apply now