Expand my Community achievements bar.

Learn about Edge Delivery Services in upcoming GEM session

Minification not working for clientlib postload

Avatar

Level 8

Hi All,

The below error prevent minification of clientlib postload -

See example at https://www.edwardsvacuum.com/etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-16...

This is the edwardsvaccum site https://www.edwardsvacuum.com/en

12.10.2022 15:21:45.493 ERROR [205.223.232.167 [1665588105228] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1663755324858-lc.min.js HTTP/1.1] com.google.javascript.jscomp /apps/settings/wcm/designs/edwards/clientlib-postloaded.js:15667: ERROR - Parse error. ‘(’ expected
12.10.2022 15:21:45.493 WARN [205.223.232.167 [1665588105228] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1663755324858-lc.min.js HTTP/1.1] com.google.javascript.jscomp 1 error(s), 0 warning(s)
12.10.2022 15:21:45.493 ERROR [205.223.232.167 [1665588105228] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1663755324858-lc.min.js HTTP/1.1] com.adobe.granite.ui.clientlibs.processor.gcc.impl.GCCScriptProcessor Processed /apps/settings/wcm/designs/edwards/clientlib-postloaded.js. 1 error(s), 0 warning(s)
12.10.2022 15:21:45.505 INFO [205.223.232.167 [1665588105228] GET

 

Please find the attachment

Vani1012_0-1666011244164.png

 

Can anyone please help how to move forward to fix this issue.

 

Thanks,

Vani.

14 Replies

Avatar

Community Advisor

Hi there, 

You might not want to put sensitive customer information on the web, but however, you might have some invalid JavaScript or SCSS involved; is the compiler is throwing an error. On your local development machine, You start validating all the dependencies and embed declarations, if those declarations are all valid, you can next start removing scripts being included in the js.txt or css.txt.You need to reverse engineer the configuration of the client library to find the problem.

Avatar

Level 8

I am not sure whether the compiler is throwing an error or not

I didn't understand what is reverse engineer here.

Can you explain to me more about what I have to do 

Avatar

Community Advisor

Yup, you will try to find the problem by removing embed, and dependencies declarations. Every removal of something you will try to compile the .css and .js by visiting the using localhost:4502/etc.clientlibs/****.css and .js

If after removing all embed, and dependencies declarations, you can start removing declarations in the css.txt and js.txt; we are trying to find out where the broken code is; you might have some invalid JavaScript or SCSS involved.

Avatar

Level 8

What I understood is, I have to remove the embed and dependencies declarations and check how the compiled .css and.js get affected if I  remove those.

 

Also, you can see in the screenshot I don't have any CSS.txt and js.txt file in my client lib, then how can I remove the declarations?

Avatar

Community Advisor

DId you get any errors while removing embed and dependencies declarations?

Avatar

Level 8

I observed that some other min.js files are minified successfully. The problem is with this file only https://www.edwardsvacuum.com/etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-16..., How to debug this. Could you please help.  

Avatar

Level 7

I tried to minify your javascript via online service. It was more or less successful. Because the connected compiler service shows an error, you cannot minify this code. In the past I faced on same situation. I tried to change the language version this didn't work either.

Avatar

Community Advisor

yeah looking closely at your screenshot, js.txt and css.txt does not exist. How is your client library including those files in the compilation?

Avatar

Level 8

In my error.log I found this error

 
18.10.2022 14:26:29.573*ERROR* [[0:0:0:0:0:0:0:1] [1666083388511] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1666083088665-lc.min.js HTTP/1.1] com.google.javascript.jscomp /apps/settings/wcm/designs/edwards/clientlib-postloaded.js:15667: ERROR - Parse error. '(' expected
    classNames = {
               ^

18.10.2022 14:26:29.573 *WARN* [[0:0:0:0:0:0:0:1] [1666083388511] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1666083088665-lc.min.js HTTP/1.1] com.google.javascript.jscomp 1 error(s), 0 warning(s)
18.10.2022 14:26:29.573 *ERROR* [[0:0:0:0:0:0:0:1] [1666083388511] GET /etc.clientlibs/settings/wcm/designs/edwards/clientlib-postloaded.lc-1666083088665-lc.min.js HTTP/1.1] com.adobe.granite.ui.clientlibs.processor.gcc.impl.GCCScriptProcessor Processed /apps/settings/wcm/designs/edwards/clientlib-postloaded.js. 1 error(s), 0 warning(s)
 
This is the js file
class CustomSelectClass {
classNames = {
initialization: 'ds_c-custom-select--initialized',
selectNative: 'ds_c-custom-select__native',
selectCustom: 'ds_c-custom-select__custom',
selectCustomActive: 'ds_c-custom-select__custom--is-active',
selectTrigger: 'ds_c-custom-select__trigger',
selectOptions: 'ds_c-custom-select__options',
selectCustomOptionActive: 'ds_c-custom-select__option--is-active',
selectCustomOptionHover: 'ds_c-custom-select__option--is-hover',
};

constructor(el) {
if (!el) return;
// Assign component node to root.
this.selectName = el.dataset.name;
this.selectNative = el.querySelector(`.${this.classNames.selectNative}`);
this.selectCustom = el.querySelector(`.${this.classNames.selectCustom}`);
this.selectTrigger = el.querySelector(`.${this.classNames.selectTrigger}`);
this.selectOptions = el.querySelector(`.${this.classNames.selectOptions}`);
this.selectOptionsList = Array.from(this.selectOptions.children);
this.optionsCount = this.selectOptionsList.length;
this.optionChecked = '';
this.optionHoveredIndex = -1;
this.listenCustomSelect();
this.listenNativeSelect();
this.updateSelectCustomOnOptionInteraction();
el.classList.add(this.classNames.initialization);
}

set isOpened(value) {
return value ? this.openSelectCustom() : this.closeSelectCustom();
}

get isOpened() {
return this.selectCustom.classList.contains(this.classNames.selectCustomActive);
}

// - Toggle custom select visibility when clicking the "box"
// - Update custom select value when clicking in an option
// - Navigate through options when using keyboard up/down
// - Pressing Enter or Space selects the current hovered option
// - Close the select when clicking outside of it
// - Sync both selects values when selecting an option. (native or custom)

// Create custom methods here.
listenCustomSelect() {
this.selectTrigger.addEventListener('click', () => {
this.isOpened = !this.isOpened;
});
}

openSelectCustom() {
this.selectCustom.classList.add(this.classNames.selectCustomActive);
this.selectCustom.setAttribute('aria-hidden', 'false');

if (this.optionChecked) {
const optionCheckedIndex = this.selectOptionsList.findIndex(
(el) => el.getAttribute('data-value') === this.optionChecked
);
this.updateOptionHovered(optionCheckedIndex);
}

// Add related event listeners
this.tempClickWatcher = this.watchClickOutside.bind(this);
this.tempKeyboardWatcher = this.supportKeyboardNavigation.bind(this);
document.addEventListener('click', this.tempClickWatcher);
document.addEventListener('keydown', this.tempKeyboardWatcher);
}

closeSelectCustom() {
this.selectCustom.classList.remove(this.classNames.selectCustomActive);
this.selectCustom.setAttribute('aria-hidden', 'true');

this.updateOptionHovered(-1);

// Remove related event listeners
document.removeEventListener('click', this.tempClickWatcher);
document.removeEventListener('keydown', this.tempKeyboardWatcher);
}

updateOptionHovered(newIndex) {
const prevOption = this.selectOptions.children[this.optionHoveredIndex];
const option = this.selectOptions.children[newIndex];

if (prevOption) prevOption.classList.remove(this.classNames.selectCustomOptionHover);
if (option) option.classList.add(this.classNames.selectCustomOptionHover);

this.optionHoveredIndex = newIndex;
}

updateOptionChecked(value, text) {
const prevValue = this.optionChecked;
const prevOption = this.selectOptions.querySelector(`[data-value="${prevValue}"`);
const option = this.selectOptions.querySelector(`[data-value="${value}"`);

if (prevOption) prevOption.classList.remove(this.classNames.selectCustomOptionActive);
if (option) option.classList.add(this.classNames.selectCustomOptionActive);

this.selectTrigger.textContent = text;
this.optionChecked = value;

if (this.selectName) {
const optionCheckedEvent = new CustomEvent(this.selectName, {
detail: this.optionChecked,
});
document.dispatchEvent(optionCheckedEvent);
}
}

watchClickOutside(event) {
const clickOutside = !this.selectCustom.contains(event.target);
if (clickOutside) this.closeSelectCustom();
}

supportKeyboardNavigation(event) {
// press down -> go next
if (event.keyCode === 40 && this.optionHoveredIndex < this.optionsCount - 1) {
event.preventDefault(); // prevent page scrolling
this.updateOptionHovered(this.optionHoveredIndex + 1);
}

// press up -> go previous
if (event.keyCode === 38 && this.optionHoveredIndex > 0) {
event.preventDefault(); // prevent page scrolling
this.updateOptionHovered(this.optionHoveredIndex - 1);
}

// press Enter or Space -> select the option
if (event.code === 'Enter' || event.code === 'NumpadEnter' || event.code === 'Space') {
event.preventDefault();

const option = this.selectOptions.children[this.optionHoveredIndex];
const value = option && option.getAttribute('data-value');

if (value) {
this.selectNative.value = value;
this.updateOptionChecked(value, option.textContent);
}
this.closeSelectCustom();
}

// press ESC -> close selectCustom
if (event.code === 'Escape') {
this.closeSelectCustom();
}
}

listenNativeSelect() {
// Toggle selectCustom when focused selectNative is triggered by Enter or Space.
this.selectNative.addEventListener('keypress', (event) => {
if (event.code === 'Enter' || event.code === 'NumpadEnter' || event.code === 'Space') {
event.preventDefault();
this.isOpened = !this.isOpened;
}
});

// Update selectCustom value when selectNative is changed.
this.selectNative.addEventListener('change', (event) => {
const { value } = event.target;
const respectiveOption = this.selectOptions.querySelector(`[data-value="${value}"]`);

this.updateOptionChecked(value, respectiveOption.textContent);
});
}

updateSelectCustomOnOptionInteraction() {
// Update selectCustom value when an option is clicked or hovered
this.selectOptionsList.forEach((option, index) => {
option.addEventListener('click', (event) => {
const value = event.target.getAttribute('data-value');

// Sync native select to have the same value
this.selectNative.value = value;
this.updateOptionChecked(value, event.target.textContent);
this.closeSelectCustom();
});

option.addEventListener('mouseenter', () => {
this.updateOptionHovered(index);
});
});
}
}

// To use this controller import it in your main js
// and run: new CustomSelectController().init();

class CustomSelectController {
init() {
const elements = document.querySelectorAll('.ds_c-custom-select');
elements.forEach((el) => new CustomSelectClass(el));
}
}

new CustomSelectController().init();

Avatar

Community Advisor

@Vani1012 , just coming back to your post, from looking at what you have pasted, the error shows me that you are using ES6, JavaScript classes. Sorry, unfortunately, the out of the box AEM is configured for ES5 only. You can spend some time trying to understand how to re-configure the compiler with this blog article here for ES6 support > https://www.kryptonsquare.com/services/Consulting/Adobe-experience-manager-implementation-expert/aem...

 

The rule of thumb is, if you can, use a nodeJS application to compile your code; doing so has many benefits like, code sniffing, reusability, scoping, etc... when you write JS code directly in /crx/de, you lose all the great benefits from a nodeJS application.

For now, you have two solutions. 1 update all ES6 syntax to ES5 manually. 2 try to configure your AEM environment to compile ES6 syntax.

Avatar

Level 8

In my Adobe Granite HTML Library Manager Js:processor is configured as in below screenshot

Vani1012_0-1666172354886.png

I tried adding jsProcessor in my clientlib folder, even after that also the file isnt minified.

Vani1012_1-1666172594517.png

Could you please help me to fix the issue.

 

 

 

Avatar

Community Advisor

In my practice, storing ES6 syntax in AEM client libraries is uncommon. I'd say, you might need to spend some time looking online for other solutions to enable ES6 or write your own... however, like I said, a standard practice is to have a Node JS application that will compile code down to ES5, and then uploaded to AEM as a client library.

Avatar

Level 8

This is the path of file in my project where the ES6 code is included

atlascopco-ac-commons\ac-commons\ui.apps\src\main\content\jcr_root\apps\settings\wcm\designs\accommons\clientlib-postloaded-dynamic\CustomSelect.controller.js,

Isnt this the correct way of adding ES6 in .js file?

 

And also is there any way to replace ES6 with ES5, If there is a way could you please suggest the steps to do and also the feasibility.