jQuery Breaks When Bundled/Minified

Hello.

My website makes use of jQuery. When I bundle jQuery with the help of Hugo’s native asset bundling mechanism and afterwards minify yet again with Hugo’s native minification along with my other JS assets, then my website can’t make use of jQuery since there happens some errors as can be seen from down below.

However, when I inject jQuery all by itself, even though the bundled one is still present, then everything works as expected:

<!--Required for the Medium style image zooming effect-->
{{ $transition := resources.Get "js/transition.js" }}
{{ $zoom := resources.Get "js/zoom.js" }}

<!--Required by the theme itself-->
{{ $jQuery := resources.Get "js/jquery.js" }}
<script type="text/javascript" src="{{ $jQuery.RelPermalink }}"></script>
{{ $bootstrap := resources.Get "js/bootstrap.js" }}

<!--Asset Bundling-->
{{ $jsCombined := slice $transition $zoom $jQuery $bootstrap | resources.Concat "js/main.js" }}

<!--Asset Minification-->
{{ $js := $jsCombined | resources.Minify }}

<!--Security Injection(fingerprinting & SRI)-->
{{ $jsSecured := $js | resources.Fingerprint "sha512" }}

<!--JS Injection-->
<script type="text/javascript" src="{{ $jsSecured.RelPermalink }}" integrity="{{ $jsSecured.Data.Integrity }}"></script>

<!-- dismiss expanded navigation bar with click -->
<script>$(document).on('click', function() { $('.collapse').collapse('hide'); })</script>

<!--Matomo-->
{{ if .Site.Params.Matomo.url }}
	<script type="text/javascript">
		var _paq = _paq || [];
		/* tracker methods like "setCustomDimension" should be called before "trackPageView" */
		_paq.push(['trackPageView']);
		_paq.push(['enableLinkTracking']);
		(function() {
			var u="{{ .Site.Params.Matomo.url }}";
			_paq.push(['setTrackerUrl', u+'piwik.php']);
			_paq.push(['setSiteId', '1']);
			var d=document, g=d.createElement('script'), s=d.getElementsByTagName('script')[0];
			g.type='text/javascript'; g.async=true; g.defer=true; g.src=u+'piwik.js'; s.parentNode.insertBefore(g,s);
		})();
	</script>
{{ end }}

Why does jQuery gets broken when it gets bundled and minified with others?

1 Like

Hi, instead of screenshots, please post the actual code you are using to bundle/minify jQuery

please see the edit

You’re including your js/jquery.js here:

{{ $jQuery := resources.Get "js/jquery.js" }}
<script type="text/javascript" src="{{ $jQuery.RelPermalink }}"></script>

Then “doing it again” here:

{{ $jsCombined := slice $transition $zoom $jQuery $bootstrap | resources.Concat "js/main.js" }}

So, try removing the first one, and see what happens.

Sorry, my mistake at explaining.

The above piece of code is live now and it works fine. However, if I remove the stand alone jQuery injection line from the above code block then it fails and jQuery is no longer functional.

As you mentioned, yes, jQuery is included twice but they don’t collide. What I meant to say at first is that on my initial try(when I wasn’t injecting jQuery as a stand alone like now) my above bundling/minification(same code as above just no stand alone jQuery injection) was yielding the above errors in the screenshots.

So clearly there is something wrong going on with Hugo’s bundling or minification.

I see what you mean now. Can you share your site git repo so that we can clone it locally and attempt to reproduce?

Yeap, it’s already available here.

I tried cloning your git repo locally, but get this when running hugo server:

$ hugo server 
Total in 102 ms
Error: Error building site: "/Users/zwbetz/Development/Sites/cansurmeli.com/content/posts/9 - Tips for iPhone Repair.md:62:5": failed to extract shortcode: template for shortcode "img" not found

My theme is a submodule, so probably it’s not included in your clone currently.

Therefore, from my project’s root directory, could you execute these commands:

$ git submodule add git@gitlab.cansurmeli.com:can/minimal.git themes/minimal
$ git submodule init
$ git submodule update

Looking at this:

I see that it’s already minified. Double minification is the most likely cause of your problems.

You’re right, I was re-minifying an already minified version of jQuery.

However, I just tried it with jQuery’s non-minified version and the result is still the same as above. I see the same error output as before.

OK, I misread the error message. What jQuery distribution are you using? I understand there are several for different “module setups”.

Your error says that the global “$” variable isn’t defined – you can verify this in the Chrome console:

console.log($);
> ƒ (e,t){return new w.fn.init(e,t)}
console.log(jQuery);
> ƒ (e,t){return new w.fn.init(e,t)}

The above is on a test with jQuery. If you use one of the CDN versions (meant for inclusion in the header), they should have both of the above globals set, but I suspect you could also do something like this:

var $ = jQuery;

CDN version

<script src=https://code.jquery.com/jquery-3.3.1.min.js></script>

I’m using the one I’ve downloaded from jQuery’s own website.

So can we conclude that it’s a bug with jQuery? Could you also elaborate a bit more on module setups.

Regarding the suggestion of var $ = jQuery;: I’ve done that(put that into my jQuery.js as a global var) and the result is still the same.

@can

The commands you gave to clone/init/update the theme submodule didn’t work, since the URL was SSH not HTTPS. I changed it to HTTPS, but then it prompted me for my git credentials. So I just deleted the submodule then did a plain git clone of it.

Oddly, I’m not seeing the error on my end. Chrome DevTools Console is clean. For reference, here is screenshot output of those commands bep mentioned

Nevermind, I see the error now when commenting out this line as you mentioned

<script type="text/javascript" src="{{ $jQuery.RelPermalink }}"></script>

Experimenting some more, this looks to be related to concatenation, not minification.

If you don’t minify the JS combined file, the error still happens.

Wondering if this is related to: https://github.com/gohugoio/hugo/issues/5403

@can – I was half-right. The issue was concatenation-related, but not how I initially thought.

The concatenation order matters, so you need to list jQuery first, since your other JS libraries depend on it.

So change this:

{{ $jsCombined := slice $transition $zoom $jQuery $bootstrap | resources.Concat "js/main.js" }}

To this:

{{ $jsCombined := slice $jQuery $transition $zoom $bootstrap | resources.Concat "js/main.js" }}

And your errors should go away.

3 Likes

That actually works.

Really appreciate it. Thanks a bunch.