March 14, 2020
Estimated Post Reading Time ~

AEM Client Libraries

AEM Client Libraries explained by example

In this blog post, I will go through the basic func­tion­al­i­ty that the ClientLi­brary­Fold­er offers, and how you can uti­lize that with­in your page com­po­nents.
Please note that I will use the proxy clientlibs approach, this is avail­able and rec­om­mend­ed since AEM6.2
The AEM Client Library (or ClientLib) func­tion­al­i­ty will man­age all your JavaScript and CSS resources in your appli­ca­tion. It takes cares of depen­den­cy man­age­ment, merg­ing files and mini­fy­ing con­tent (remov­ing unnec­es­sary white spaces).
The fol­low­ing appli­ca­tion sce­nar­ios will be explained:
·       mul­ti­ple com­po­nents with their own JavaScript and CSS files
·       CSS resources have to go in the <head>, JavaScript resources at the end of the page
·       Resources need to be mini­fied
·       chang­ing the mini­fi­ca­tion engine
Let’s get start­ed!

Step 1: Creating components and ClientLib nodes

First we make a few com­po­nents, in this exam­ple 3 com­po­nents are used, we do this all via CRXDE-lite (http://localhost:4502/crx/de).

Next we are going to add a “clientlib” node of type “cq:ClientLibraryFolder”, inside this node the JavaScript and CSS resources are stored.

Add a prop­er­ty to every “clientlib” node called “cat­e­gories” of type String[] with the sin­gle val­ue of “myproject.components” (to get a String[] type click the “Mul­ti” but­ton).

Now add a Boolean prop­er­ty “allow­Proxy”, and set this to true. This will make the clientlibs avail­able via the url /etc.clientlibs/, so it means they are not hav­ing the /apps ref­er­ence.

Your com­po­nents-fold­er will look now like this:

Step 2: Adding JavaScript and CSS resources

Now we are going to add some sim­ple JavaScript and CSS resources in the “clientlib” nodes.
Cre­ate fol­low­ing files inside of your “clientlib” fold­er of “MyFirst­Com­po­nent”:

first.css

.firstContainer {
    margin-top:10px;
}

first.js

/*
 * This is the comment of the function
 */
function getNameFirst() {
    // return the name
    return "some value";
}

js.txt

# mentions all the JavaScript resources of the ClientLib
first.js

css.txt

# mentions all the CSS resources of the ClientLib
first.css
And repeat the same thing for the oth­er com­po­nents to achieve some­thing that looks like this:
The con­fig­u­ra­tion of the com­po­nents are now fin­ished.

Step 3: Using ClientLibs in your component

Now the set­up of the ClientLib is fin­ished we can invoke the ClientLibs in your page com­po­nents. When you are using a JSP you can use cq:includeClientlib . In case you are using the HTML Tem­plate Lan­guage (HTL), you can use the data-sly-call to invoke the ClientLib. In this arti­cle HTL will be used for the exam­ples.
We start with putting the fol­low­ing into the <head> ele­ment of our page:
<sly data-sly-use.clientlib="/libs/granite/sightly/templates/clientlib.html" />
<sly data-sly-call="${clientlib.css @ categories='myproject.components'}" />
<sly data-sly-call="${clientlib.js @ categories='myproject.components'}" />
The val­ue of the “cat­e­gories” prop­er­ties of the “clientlib” nodes are “myproject.components”, which is what we need to pro­vide above.
This results in the fol­low­ing HTML-out­put:
<link rel="stylesheet" href="etc.clientlibs/mycomponents/MyThirdComponent/clientlib.css" type="text/css">
<link rel="stylesheet" href="etc.clientlibs/mycomponents/MySecondComponent/clientlib.css" type="text/css">
<link rel="stylesheet" href="etc.clientlibs/mycomponents/MyFirstComponent/clientlib.css" type="text/css">
<script type="text/javascript" src="etc.clientlibs/mycomponents/MyThirdComponent/clientlib.js"></script>
<script type="text/javascript" src="etc.clientlibs/mycomponents/MySecondComponent/clientlib.js"></script>
<script type="text/javascript" src="etc.clientlibs/mycomponents/MyFirstComponent/clientlib.js"></script>
This has a few down­sides:
·       6 serv­er calls have to be made to fetch the resources.
·       Appli­ca­tion struc­ture is exposed.

Step 4: Merging files

To merge the sev­er­al clientlib files into one, we define a clientlibs that is embed­ding the oth­er cat­e­gories. Exam­ple here is tak­en from /app­s/w­ere­tail/­clientlib­s/­clientlib-base.
Step 5: Dependencies
Anoth­er prop­er­ty you can add to the “clientlib” node is “depen­den­cies”, this way you can define depen­den­cies between ClientLibs.
Let’s add a depen­den­cy on “cq.jquery”:
When you now reload the page the depen­den­cy is writ­ten:
<script type="text/javascript" src="https://blogsimages.adobe.com/etc/clientlibs/foundation/jquery.js"></script>
<script type="text/javascript" src="https://blogsimages.adobe.com/etc.clientlibs/myproject/clientlib.js"></script>

Step 6: Minify and Gzip

To deliv­er a bet­ter per­for­mance you can enable “Mini­fy” and “Gzip” for the “Adobe Gran­ite HTML Library Man­ag­er” (pre­vi­ous­ly also called “Day CQ HTML Library Man­ag­er”), in the Felix Con­fig­u­ra­tion con­sole (http://server/system/console/configMgr). These set­tings are rec­om­mend­ed for pro­duc­tion instal­la­tions.
By default the YUI com­pres­sor is used when mini­fy­ing files, you can bet­ter use the GCC (Google Clo­jure Com­pil­er) for this.
This is described here: https://helpx.adobe.com/experience-manager/kb/how-to-change-the-minification-engine-for-client-libraries-in-AEM.html

A common error with proxy clientlibs

When you use proxy clientlibs, then you may run into this error:
Unable to proxy yourfont.ttf. No sup­port­ed type for .ttf”, this can hap­pen for types oth­er than JS/CSS.
Rea­son for this is that resources oth­er than JS/CSS need to be put into a fold­er called resources.
 FAQ
Q: I don’t want to have all my JavaScript ref­er­ences in the <head>
A: Move the data-sly-call to the right loca­tion in your tem­plate, you can use ClientLib mul­ti­ple times
Q: Where are the gen­er­at­ed files stored in AEM?
A: They are stored in /var/clientlibs
Q: When devel­op­ing I want to have sin­gle file ref­er­ences in my HTML
A: Enable the debug-option in the HTML Library Man­ag­er
Q: Is there a con­sole so I can see the depen­den­cies?
A: Yes, look at this page http://server/libs/cq/ui/content/dumplibs.html
Q: Are there debug­ging options avail­able?
A: Yes, ?debugClientLibs=true writes out sin­gle files
Q: Can I rebuild the ClientLibs?
A: Yes, via this url: /libs/granite/ui/content/dumplibs.rebuild.html
Q: How can I use cache-bust­ing and ClientLibs?
A: You can enable the hash­ing of the url via ‘ver­sioned ClientLibs’.
Q: Do you have an exam­ple of this?
A: Yes, the “core” com­po­nents can be used as a reference: https://git.corp.adobe.com/CQ/aem-core-wcm-components
Q: What is the best prac­tice with regards to per­for­mance and caching
A: Via mod_expires / mod_deflate and the use of cache-bust­ing you can cache the css/js files on the brows­er to increase over­all per­for­mance of your pages. All of this will hap­pen in com­bi­na­tion with the dis­patch­er.




By aem4beginner

No comments:

Post a Comment

If you have any doubts or questions, please let us know.