Client libraries - bartoszWesolowski/aem-tips GitHub Wiki

Client libraries

  • Mechanism to organize and manage CSS and JS files in AEM based projects
  • Allows to manage dependencies in an easy manner
  • Kept in few files which allows to minimize number of requests, all js files that belongs to clientlib are merged into one file (same for CSS files) - name of the file generated like this will be <nodenane>.js and <nodename>.css

Client library definition

Client library is a node with the following definition:

<?xml version="1.0" encoding="UTF-8"?>
<jcr:root xmlns:cq="http://www.day.com/jcr/cq/1.0" xmlns:jcr="http://www.jcp.org/jcr/1.0"
    jcr:primaryType="cq:ClientLibraryFolder"
    allowProxy="{Boolean}true"
    categories="[aem-examples.base]"
    dependencies="[cq.authoring.editor]"
    embed="[aem-examples.grid]"
    channels="[touch]"/>
  • jcr:primaryType must be set to cq:ClientLibraryFolder
  • allowProxy - set to true allows to store clientlibs under /apps but deliver the clienlibs over path prefixed with /etc.clientlibs to avoid exposing any resource under /apps
  • categories - an array of tags that client lib can be referred by
  • dependencies - all client libs that are required by this client lib. The script that includes this client lib will also generate a link to all dependencies
  • embed - tags of client libraries that will be embedded into this client library (at runtime code generated for this library will also include code of embedded libraries). Embedding code is useful for providing access to libraries that are stored in secured areas of the repository.
  • channels - used to associate client library with a device group

Difference between embed and dependencies

  • when depnendency is used it will cause a page to generate another request to other client library
  • when embed is used then the another client lib is added to the js generated and no additional request is made

There are js and css files under the node. Another part of the client lib is a js.txt (and css.txt) file. Those files define which js/css files merge into the output clientlib.

js.txt/css.txt file structure The structure of js.txt file:

#base=.
file.js
file2.js

#base=mobile
file-mobile.js

where base is the relative path to the folder where files are stored.

To include an image/gif (or any other resource) in the clientlib there must be a ** resources ** folder with the images (without that folder those resources will not be accessible on publish).

Locating a Client Library

Previously clientlibs were located under /etc/clientlibs (which is still supported). Currently it is recommended to keep clientlibs under /apps (to locate scripts near to components that use them).

Overriding Libraries in /lib

Client library folders located below /apps take precedence over same-named folders that are similarly located in /libs . For example, /apps/cq/ui/widgets takes precedence over /libs/cq/ui/widgets. When these libraries belong to the same category, the library below /apps is used.

Preprocessors

AEM allows for pluggable preprocessors and ships with support for YUI Compressor for CSS and JavaScript and Google Closure Compiler (GCC) for JavaScript with YUI set as AEM's default preprocessor.

  • can be configured in OSGI
  • can be used for minification
  • clientlib can define which processor to use

To set up processor options client lib definition can be extended with cssProcessor and jsProcessor properties

Format

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

YUI Compressor for CSS Minification and GCC for JS

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

Typescript to Preprocess and Then GCC to Minify and Obfuscate

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

Additional GCC Options

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

OSGi config

To configure preprocessors use Adobe Granite HTML Library Manager service ( com.adobe.granite.ui.clientlibs.impl.HtmlLibraryManagerImpl) OSGi config

Debbuging

  • append debugClientLibs=true parameter to the url - this will show names of the files that are being embedded
  • http://localhost:4502/libs/granite/ui/content/dumplibs.rebuild.html to rebuild and clear cache of clientlibs
  • http://localhost:4502/libs/granite/ui/content/dumplibs.test.html to debug what would be the output of client lib included in different way Dumplibs test
  • http://localhost:4502/libs/granite/ui/content/dumplibs.html to display a table that with information about all clientlibs
  • http://localhost:4502/libs/granite/ui/content/dumplibs.tree.html to display a tree of dependencies of clientlib Clientlibs dependency tree

Include client Library on page

HTL

To include client lib with a HTL use the template data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html

<html data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html">
    <head>
        <!-- HTML meta-data -->
        <sly data-sly-call="${clientlib.css @ categories='myCategory'}"/>
    </head>
    <body>
        <!-- page content -->
        <sly data-sly-call="${clientlib.js @ categories='myCategory'}"/>
    </body>
</html>

To include both js and css code at once use

<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html"
     data-sly-call="${clientlib.all @ categories=['myCategory1', 'myCategory2']}"/>

JSP

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

For example to include both jss and css for particular category:

<ui:includeClientLib categories="apps.aem-learning"/>

Which will generate HTML code similar to:

<link rel="stylesheet" href=”/etc/clientlibs/aem-developer.css" type="text/css"></link>
<script type="text/javascript" src="/etc/clientlibs/aem-developer.js"></script>

To include only js/css use:

<ui:includeClientLib css="apps.aem-learning"/>
<ui:includeClientLib js="apps.aem-learning"/>

Configuring custom client libs for page template

In the most cases clientlibs are included on a page directly on a page renderer (call to the clientlibs tag/template) or set up on template policy. The first case is straight forward - page renderer must call the clientlib template. The second one is more generic which allows to manage which clientlibs are added to particular template.

In case there are some clientlibs that are large and are not used globally it is a good idea to add them as a property of a template that will need them. To do that go to templates page /libs/wcm/core/content/sites/templates.html/conf, select template that should include custom clientlibs, click on page information button in top left corner page info icon and open page policy. In properties select which clientlibs should be included on this particular template. Those values are then process by /apps/core/wcm/components/page/v2/page/footer.html and /apps/core/wcm/components/page/v2/page/headlibs.html.

template policy

Documentation

⚠️ **GitHub.com Fallback** ⚠️