Statement : How to merge multiple JS/CSS files into one
Solution :
How to embed multiple categories.
Reference Article : http://blogs.adobe.com/experiencedelivers/experience-management/clientlibs-explained-example/
Solution :
- In this example used proxy clientlibs approach, this is available and recommended since AEM6.2
- The AEM Client Library (or ClientLib) functionality will manage all your JavaScript and CSS resources in your application. It takes cares of dependency management, merging files and minifying content (removing unnecessary white spaces).
The following application scenarios will be explained:
- multiple components with their own JavaScript and CSS files
- CSS resources have to go in the , JavaScript resources at the end of the page
- Resources need to be minified
- changing the minification engine
Let’s get started!
Step 1: Creating components and ClientLib nodes
First we make a few components, in this example 3 components 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 property to every “clientlib” node called “categories” of type String[] with the single value of “myproject.components” (to get a String[] type click the “Multi” button).
Now add a Boolean property “allowProxy”, and set this to true. This will make the clientlibs available via the url /etc.clientlibs/, so it means they are not having the /apps reference.
Your components-folder will look now like this:
Step 2: Adding JavaScript and CSS resources
Now we are going to add some simple JavaScript and CSS resources in the “clientlib” nodes.
Create following files inside of your “clientlib” folder of “MyFirstComponent”:
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 other components to achieve something that looks like this:
The configuration of the components are now finished.
Step 3: Using ClientLibs in your component
Now the setup of the ClientLib is finished we can invoke the ClientLibs in your page components. When you are using a JSP you can use cq:includeClientlib . In case you are using the HTML Template Language (HTL), you can use the data-sly-call to invoke the ClientLib. In this article HTL will be used for the examples.
We start with putting the following into the element of our page:
The value of the “categories” properties of the “clientlib” nodes are “myproject.components”, which is what we need to provide above.
This results in the following HTML-output:
This has a few downsides:
- 6 server calls have to be made to fetch the resources.
- Application structure is exposed.
Step 4: Merging files
To merge the several clientlib files into one, we define a clientlibs that is embedding the other categories. Example here is taken from /apps/weretail/clientlibs/clientlib-base.
Step 5: Dependencies
Another property you can add to the “clientlib” node is “dependencies”, this way you can define dependencies between ClientLibs.
Let’s add a dependency on “cq.jquery”:
When you now reload the page the dependency is written:
Step 6: Minify and Gzip
To deliver a better performance you can enable “Minify” and “Gzip” for the “Adobe Granite HTML Library Manager” (previously also called “Day CQ HTML Library Manager”), in the Felix Configuration console (http://server/system/console/configMgr). These settings are recommended for production installations.
By default the YUI compressor is used when minifying files, you can better use the GCC (Google Clojure Compiler) 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
Common error with proxy clientlibs
When you use proxy clientlibs, then you may run into this error:
“Unable to proxy yourfont.ttf. No supported type for .ttf”, this can happen for types other than JS/CSS.
Reason for this is that resources other than JS/CSS need to be put into a folder called resources.
FAQ
Q: I don’t want to have all my JavaScript references in the
A: Move the data-sly-call to the right location in your template, you can use ClientLib multiple times
A: Move the data-sly-call to the right location in your template, you can use ClientLib multiple times
Q: Where are the generated files stored in AEM?
A: They are stored in /var/clientlibs
A: They are stored in /var/clientlibs
Q: When developing I want to have single file references in my HTML
A: Enable the debug-option in the HTML Library Manager
A: Enable the debug-option in the HTML Library Manager
Q: Is there a console so I can see the dependencies?
A: Yes, look at this page http://server/libs/cq/ui/content/dumplibs.html
A: Yes, look at this page http://server/libs/cq/ui/content/dumplibs.html
Q: Are there debugging options available?
A: Yes, ?debugClientLibs=true writes out single files
A: Yes, ?debugClientLibs=true writes out single files
Q: Can I rebuild the ClientLibs?
A: Yes, via this url: /libs/granite/ui/content/dumplibs.rebuild.html
A: Yes, via this url: /libs/granite/ui/content/dumplibs.rebuild.html
Q: How can I use cache-busting and ClientLibs?
A: You can enable the hashing of the url via ‘versioned ClientLibs’.
A: You can enable the hashing of the url via ‘versioned ClientLibs’.
Q: Do you have an example of this?
A: Yes, the “core” components can be used as a reference: https://git.corp.adobe.com/CQ/aem-core-wcm-components
A: Yes, the “core” components can be used as a reference: https://git.corp.adobe.com/CQ/aem-core-wcm-components
Q: What is the best practice with regards to performance and caching
A: Via mod_expires / mod_deflate and the use of cache-busting you can cache the css/js files on the browser to increase overall performance of your pages. All of this will happen in combination with the dispatcher.
A: Via mod_expires / mod_deflate and the use of cache-busting you can cache the css/js files on the browser to increase overall performance of your pages. All of this will happen in combination with the dispatcher.
How to embed multiple categories.
In AEM, a category include will merge and compress all the files into a single js (or css) include. This is done per category include.
If you want to merge multiple categories, you should consider using the embed option in categories dependencies. How this works is:
- Create a new category (for e.g. cq-embed)
- Define embed dependencies ('cq.foundation-main','cq.shared') for the new category you have created.
- Reference your new category.
Reference Article : http://blogs.adobe.com/experiencedelivers/experience-management/clientlibs-explained-example/