Re: Shopify CDN: Minification failed

Why is automatic file minification failing on my Shopify CDN?

Quondy
Pathfinder
97 0 32

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 26 (26)

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
3 0 1

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
3 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
29 0 18

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.

stijns96
Shopify Partner
6 0 3

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.

mmarienko
Shopify Partner
23 0 15

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
Mavi90
Excursionist
31 0 9

Hey,
Does this repo also solve this issue for Debut theme?

Thanks

mmarienko
Shopify Partner
23 0 15

use this one https://github.com/mmarienko/shopify-autominified-theme better

Regards, Max Marienko - Shopify Expert
Mavi90
Excursionist
31 0 9

Heyy,

 

Sorry to be annoying, I'm new to this!

 

Should I fork this repo and then merge it to my store repo?

 

Thanks, 

Maria 

 

Mavi90
Excursionist
31 0 9

Hi,

I think I figured it out!

 

The only issue I am encountering is an error when running Shopify theme push. I keep generating new SHOPIFY_CLI_THEME_TOKEN and still get an invalid password error. (Shown in image below)

What do I do now?

 

Thanks,

Maria

Screenshot 2024-02-05 at 3.32.26 PM.png

mmarienko
Shopify Partner
23 0 15

these links can help you to understand that issue and fix it:
https://shopify.dev/docs/themes/tools/cli/ci-cd
https://shopify.dev/docs/themes/tools/theme-access 

I can only assume that you either specify the wrong store in SHOPIFY_STORE or use some other password (not from Theme Access app)

Regards, Max Marienko - Shopify Expert
Mavi90
Excursionist
31 0 9

Hey,

 

I got it all set up, but I don't think it works with the debut theme.👎

 

In github actions, it says its running. But I'm still getting that Shopify CDN: Minification failed.

 

Are you sure it works with debut version 17.13?

 

Thanks,

Maria Screenshot 2024-02-06 at 11.20.45 AM.pngScreenshot 2024-02-06 at 11.22.40 AM.png

mmarienko
Shopify Partner
23 0 15

The GitHub actions must be successfully completed, not running.
Are you sure you opened the theme with the same ID you provided? Try to hard reload the page: Command(Ctrl) + R.
Try to open the minified theme through Code editor and check if the assets are minified there

Regards, Max Marienko - Shopify Expert
mmarienko
Shopify Partner
23 0 15

I see that your files are already minified. Did my solution help you?

Screenshot 2024-02-07 at 20.29.38.png

Regards, Max Marienko - Shopify Expert
Mavi90
Excursionist
31 0 9

Yes I did it! Thanks for the help

stijns96
Shopify Partner
6 0 3

To be honest I wouldn't convert your es6 to es5. Regardless of the errors you get with es6. In most cases, this will give you much more code than necessary. Often even so much more than the minified version of your ES6.

 

So I would only minify the code myself, but certainly not convert it to es5. The only reason you would want to do that is if your user often uses older browsers. See the image below for a fairly simple example. Left ES6^, right ES5.

 

stijn_code_0-1709620139687.png

 

jthk116
Shopify Partner
38 3 9

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.
mmarienko
Shopify Partner
23 0 15

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
ajprice07
Shopify Partner
1 0 0

Hi, do you have this for refresh theme?  I'm having this same issue.  I've been manually updating the JS which is tedious and difficult to locate all instances.  I've also run into errors when trying to minify that don't let me compress.

mmarienko
Shopify Partner
23 0 15

it suits any theme just add the CI/CD pipeline

Regards, Max Marienko - Shopify Expert
mmarienko
Shopify Partner
23 0 15

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
Tourist
9 0 1

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)
    })
  }
}

NicoRi
Excursionist
15 0 4

Same issue here with "Studio" theme v12, all .js asset files untouched - so there's definitely a divergence on Shopify's side regarding the CDN's target version and the ES version used by (at least some) themes officially provided/maintained by Shopify.