Shopify CDN: Minification failed

Quondy
Pathfinder
97 0 31

Hello community,

 

I received a warning from semrush after running a website audit, it concerns 904 CSS and Javascrip files not minified. 

 

All of them contain the following: /cdn/shop/t/104/assets/

 

When I select and open the link it appears that Shopify CDN: Minification failed.

 

Why shopify is failing in minifiying the files while it should be automatic? How to solve this?

 

Here an example of the unminified file: : https://mastrozavattistore.com/cdn/shop/t/104/assets/predictive-search.js?v=162273246065392412141690... 

/** Shopify CDN: Minification failed

Line 16:0 Transforming class syntax to the configured target environment ("es5") is not supported yet
Line 17:13 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 29:21 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 38:10 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 42:10 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 44:4 Transforming const to the configured target environment ("es5") is not supported yet
Line 64:14 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 68:13 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 78:9 Transforming object literal extensions to the configured target environment ("es5") is not supported yet
Line 79:4 Transforming const to the configured target environment ("es5") is not supported yet
... and 31 more hidden warnings

**/
class PredictiveSearch extends SearchForm {
  constructor() {
    super();
    this.cachedResults = {};
    this.predictiveSearchResults = this.querySelector('[data-predictive-search]');
    this.allPredictiveSearchInstances = document.querySelectorAll('predictive-search');
    this.isOpen = false;
    this.abortController = new AbortController();
    this.searchTerm = '';

    this.setupEventListeners();
  }

  setupEventListeners() {
    this.input.form.addEventListener('submit', this.onFormSubmit.bind(this));

    this.input.addEventListener('focus', this.onFocus.bind(this));
    this.addEventListener('focusout', this.onFocusOut.bind(this));
    this.addEventListener('keyup', this.onKeyup.bind(this));
    this.addEventListener('keydown', this.onKeydown.bind(this));
  }

  getQuery() {
    return this.input.value.trim();
  }

  onChange() {
    super.onChange();
    const newSearchTerm = this.getQuery();
    if (!this.searchTerm || !newSearchTerm.startsWith(this.searchTerm)) {
      // Remove the results when they are no longer relevant for the new search term
      // so they don't show up when the dropdown opens again
      this.querySelector('#predictive-search-results-groups-wrapper')?.remove();
    }

    // Update the term asap, don't wait for the predictive search query to finish loading
    this.updateSearchForTerm(this.searchTerm, newSearchTerm);

    this.searchTerm = newSearchTerm;

    if (!this.searchTerm.length) {
      this.close(true);
      return;
    }

    this.getSearchResults(this.searchTerm);
  }

  onFormSubmit(event) {
    if (!this.getQuery().length || this.querySelector('[aria-selected="true"] a')) event.preventDefault();
  }

  onFormReset(event) {
    super.onFormReset(event);
    if (super.shouldResetForm()) {
      this.searchTerm = '';
      this.abortController.abort();
      this.abortController = new AbortController();
      this.closeResults(true);
    }
  }

  onFocus() {
    const currentSearchTerm = this.getQuery();

    if (!currentSearchTerm.length) return;

    if (this.searchTerm !== currentSearchTerm) {
      // Search term was changed from other search input, treat it as a user change
      this.onChange();
    } else if (this.getAttribute('results') === 'true') {
      this.open();
    } else {
      this.getSearchResults(this.searchTerm);
    }
  }

  onFocusOut() {
    setTimeout(() => {
      if (!this.contains(document.activeElement)) this.close();
    });
  }

  onKeyup(event) {
    if (!this.getQuery().length) this.close(true);
    event.preventDefault();

    switch (event.code) {
      case 'ArrowUp':
        this.switchOption('up');
        break;
      case 'ArrowDown':
        this.switchOption('down');
        break;
      case 'Enter':
        this.selectOption();
        break;
    }
  }

  onKeydown(event) {
    // Prevent the cursor from moving in the input when using the up and down arrow keys
    if (event.code === 'ArrowUp' || event.code === 'ArrowDown') {
      event.preventDefault();
    }
  }

  updateSearchForTerm(previousTerm, newTerm) {
    const searchForTextElement = this.querySelector('[data-predictive-search-search-for-text]');
    const currentButtonText = searchForTextElement?.innerText;
    if (currentButtonText) {
      if (currentButtonText.match(new RegExp(previousTerm, 'g')).length > 1) {
        // The new term matches part of the button text and not just the search term, do not replace to avoid mistakes
        return;
      }
      const newButtonText = currentButtonText.replace(previousTerm, newTerm);
      searchForTextElement.innerText = newButtonText;
    }
  }

  switchOption(direction) {
    if (!this.getAttribute('open')) return;

    const moveUp = direction === 'up';
    const selectedElement = this.querySelector('[aria-selected="true"]');

    // Filter out hidden elements (duplicated page and article resources) thanks
    // to this https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/offsetParent
    const allVisibleElements = Array.from(this.querySelectorAll('li, button.predictive-search__item')).filter(
      (element) => element.offsetParent !== null
    );
    let activeElementIndex = 0;

    if (moveUp && !selectedElement) return;

    let selectedElementIndex = -1;
    let i = 0;

    while (selectedElementIndex === -1 && i <= allVisibleElements.length) {
      if (allVisibleElements[i] === selectedElement) {
        selectedElementIndex = i;
      }
      i++;
    }

    this.statusElement.textContent = '';

    if (!moveUp && selectedElement) {
      activeElementIndex = selectedElementIndex === allVisibleElements.length - 1 ? 0 : selectedElementIndex + 1;
    } else if (moveUp) {
      activeElementIndex = selectedElementIndex === 0 ? allVisibleElements.length - 1 : selectedElementIndex - 1;
    }

    if (activeElementIndex === selectedElementIndex) return;

    const activeElement = allVisibleElements[activeElementIndex];

    activeElement.setAttribute('aria-selected', true);
    if (selectedElement) selectedElement.setAttribute('aria-selected', false);

    this.input.setAttribute('aria-activedescendant', activeElement.id);
  }

  selectOption() {
    const selectedOption = this.querySelector('[aria-selected="true"] a, button[aria-selected="true"]');

    if (selectedOption) selectedOption.click();
  }

  getSearchResults(searchTerm) {
    const queryKey = searchTerm.replace(' ', '-').toLowerCase();
    this.setLiveRegionLoadingState();

    if (this.cachedResults[queryKey]) {
      this.renderSearchResults(this.cachedResults[queryKey]);
      return;
    }

    fetch(`${routes.predictive_search_url}?q=${encodeURIComponent(searchTerm)}&section_id=predictive-search`, {
      signal: this.abortController.signal,
    })
      .then((response) => {
        if (!response.ok) {
          var error = new Error(response.status);
          this.close();
          throw error;
        }

        return response.text();
      })
      .then((text) => {
        const resultsMarkup = new DOMParser()
          .parseFromString(text, 'text/html')
          .querySelector('#shopify-section-predictive-search').innerHTML;
        // Save bandwidth keeping the cache in all instances synced
        this.allPredictiveSearchInstances.forEach((predictiveSearchInstance) => {
          predictiveSearchInstance.cachedResults[queryKey] = resultsMarkup;
        });
        this.renderSearchResults(resultsMarkup);
      })
      .catch((error) => {
        if (error?.code === 20) {
          // Code 20 means the call was aborted
          return;
        }
        this.close();
        throw error;
      });
  }

  setLiveRegionLoadingState() {
    this.statusElement = this.statusElement || this.querySelector('.predictive-search-status');
    this.loadingText = this.loadingText || this.getAttribute('data-loading-text');

    this.setLiveRegionText(this.loadingText);
    this.setAttribute('loading', true);
  }

  setLiveRegionText(statusText) {
    this.statusElement.setAttribute('aria-hidden', 'false');
    this.statusElement.textContent = statusText;

    setTimeout(() => {
      this.statusElement.setAttribute('aria-hidden', 'true');
    }, 1000);
  }

  renderSearchResults(resultsMarkup) {
    this.predictiveSearchResults.innerHTML = resultsMarkup;
    this.setAttribute('results', true);

    this.setLiveRegionResults();
    this.open();
  }

  setLiveRegionResults() {
    this.removeAttribute('loading');
    this.setLiveRegionText(this.querySelector('[data-predictive-search-live-region-count-value]').textContent);
  }

  getResultsMaxHeight() {
    this.resultsMaxHeight =
      window.innerHeight - document.querySelector('.section-header').getBoundingClientRect().bottom;
    return this.resultsMaxHeight;
  }

  open() {
    this.predictiveSearchResults.style.maxHeight = this.resultsMaxHeight || `${this.getResultsMaxHeight()}px`;
    this.setAttribute('open', true);
    this.input.setAttribute('aria-expanded', true);
    this.isOpen = true;
  }

  close(clearSearchTerm = false) {
    this.closeResults(clearSearchTerm);
    this.isOpen = false;
  }

  closeResults(clearSearchTerm = false) {
    if (clearSearchTerm) {
      this.input.value = '';
      this.removeAttribute('results');
    }
    const selected = this.querySelector('[aria-selected="true"]');

    if (selected) selected.setAttribute('aria-selected', false);

    this.input.setAttribute('aria-activedescendant', '');
    this.removeAttribute('loading');
    this.removeAttribute('open');
    this.input.setAttribute('aria-expanded', false);
    this.resultsMaxHeight = false;
    this.predictiveSearchResults.removeAttribute('style');
  }
}

customElements.define('predictive-search', PredictiveSearch);

 

Replies 13 (13)
ChivillaBay
Visitor
2 0 1

I am having that same issue and also getting Low text to HTML ratio warnings. It started around the 1st week of July. 

sambuxc
Shopify Partner
2 0 2

I am also getting a similar problem when using Vite to compress my main JS file.

 

Screenshot 2023-08-23 at 12.12.53.png

mcb1
Shopify Partner
1 0 0

This is happening for me too. Its weird to me because the Dawn theme is using es6, why would they change this?

truemoroz
Shopify Partner
2 0 0

Same problem

Loggo
Visitor
2 0 0

Any fix to this? I'm also having this issue, using Ride V11... Disappointing to be getting this type of error using a Shopify supplied theme rather than 3rd party.

trucranems
Excursionist
15 0 2

I'm having the same problem

Rebecca-S
Shopify Partner
1 0 0

Have you found a solution Quondy? I am seeing these es5 not supported errors on my site too.  I asked Shopify support and this is what they said:

04:38 (Support Advisor): The error message "Transforming const to the configured target environment ("es5") is not supported yet" refers to a JavaScript transformation problem.

04:39 (Support Advisor): The error happens because your code is trying to transform a const declaration (an ES6 feature) into ES5, but the tool or environment you're using doesn't support this transformation.

04:39 Rebecca: and what would have to be done to fix this?

04:40 (Support Advisor): To address the "Transforming const to the configured target environment ("es5") is not supported yet" issue, there are two primary strategies depending on your specific situation and needs.

04:41 Rebecca: What are they?

04:41 (Support Advisor): 1. Convert ES6 to ES5 manually:
- Go through your JavaScript files, find where const is used, and replace with var. This can be a bit time-consuming but would solve the transformation error.
2. Use a more modern transpiler:
- If you are intentionally converting your JavaScript from ES6 to ES5 for compatibility reasons (such as support for older browsers), consider using a different, more modern tool (or updating the current tool) to perform that conversion.

04:42 (Support Advisor): Babel is one commonly used tool that can convert ES6 (including const statements) to ES5.

However they did say that they don't believe this error is related to my initial issue of the Semrush error "pages have too large HTML" that has suddenly appeared even though nothing has changed on the site.

stijn_code
Shopify Partner
2 0 0

Is there a staff member who can share why Shopify is still targeting es5 while using es6?

 

For now we will stick with es6, because http2 is fast enough to process these types of files. Converting them to es5 makes the files much larger than they need to be for modern browsers.

 

Since I can not really find any git repo for this, I'll post this comment here.

marienko
Shopify Partner
16 0 8

I've created a repo that solves this issue for Dawn theme: https://github.com/mmarienko/shopify-gulp-theme using Gulp 4 and Babel (+ Tailwind). You can use it as a reference or as your starting point. 

I'll be glad if you star or fork the repository.


Regards, Max Marienko - Shopify Expert
jthk116
Shopify Partner
20 1 2

Hi, I'm seeing this issue too. I see that no one from Shopify has officially addressed it here yet. Wondering if anyone has heard anything concrete as a resolution for this? Wouldn't want to spend time converting the entire file for our theme only to find out there are other issues or having to troubleshoot through how that might impact everything going on in there

Please like and accept solution if I was helpful, thanks!

Jay K.
marienko
Shopify Partner
16 0 8

Hi Jthk116 :)) my theme's repo with Github CI/CD pipeline can help you to automatically minify and convert (ES6 -> ES5) all your JS and CSS to exclude the issue: https://github.com/mmarienko/shopify-autominified-theme just follow the instructions inside. Will be glad if you star or fork the repository.

Regards, Max Marienko - Shopify Expert
marienko
Shopify Partner
16 0 8

Did it help you? The integration will change only the theme you selected. Your code in the repository will remain the same, not minified and not transpired.

I think this is a cool solution that will help everyone avoid this issue until Shopify fixes it themselves.

Regards, Max Marienko - Shopify Expert
Apolline
New Member
9 0 0

Hello,  

I also have this issue. Does it impact my TTFB and my FCP ?

 

Thanks a lot !

** Shopify CDN: Minification failed

Line 7:0 Transforming let to the configured target environment ("es5") is not supported yet
Line 14:28 Transforming array spread to the configured target environment ("es5") is not supported yet

**/
let subscribers = {}

function subscribe(eventName, callback) {
  if (subscribers[eventName] === undefined) {
    subscribers[eventName] = []
  }

  subscribers[eventName] = [...subscribers[eventName], callback];

  return function unsubscribe() {
    subscribers[eventName] = subscribers[eventName].filter((cb) => {
      return cb !== callback
    });
  }
};

function publish(eventName, data) {
  if (subscribers[eventName]) {
    subscribers[eventName].forEach((callback) => {
      callback(data)
    })
  }
}