How do I use `externals` for JS builds to load JS externally?

I’ve written a script for integrating Algolia in my theme and it works fine. Below is my code:

import algoliasearch from 'algoliasearch/lite';
import instantsearch from 'instantsearch.js/es/lib/main';

// Defined by ESBuild
const baseURL = _baseURL;
const externalLinkSnippet = _externalLink;

// Configure InstantSearch.
const searchClient = algoliasearch(
	_appID,
	_searchKey,
);

// bla bla bla

Now, what I want to do is to load algoliasearch/lite and instantsearch.js/es/lib/main from CDN. Therefore, as stated in the docs, I tried using the externals parameter like this:

{{ $searchJS := resources.Get "js/search.js" | js.Build (dict "externals" (slice "algoliasearch" "instantsearch.js") }}

This does partly seem to work because the libraries are no longer embedded into the final search.js, however I keep seeing these requires in the output:

const v=m(require("algoliasearch/lite")),i=m(require("instantsearch.js/es/lib/main"))

Obviously, this fails to execute because native JS doesn’t understand require().

What should I do to make the constants v and m get assigned to window.algoliasearch and window.instantsearch?

Can you show more code or your repo itself? In my repo I have no need to load algoliasearch/lite. instantsearch.js does it all. Have a look at https://github.com/davidsneighbour/dnb-hugo-garuda/blob/master/assets/js/search.js - as of today that works…

Yes, that works, because you’ve already loaded the JS from CDN beforehand. In my theme, what I’ve done is that:

  • development builds use the npm repo as dependencies in JS
  • production builds use CDN JS as dependencies.

So, in my case, I want to be able to ignore the import statements in the JS in the production builds.
I’m sorry, I can’t share my full repo yet, but this is the JS:

import algoliasearch from 'algoliasearch/lite';
import instantsearch from 'instantsearch.js/es/lib/main';

// Defined by ESBuild
const baseURL = _baseURL;
const externalLinkSnippet = _externalLink;

// Configure InstantSearch.
const searchClient = algoliasearch(
	_appID,
	_searchKey,
);
// other stuff
//....

and this is the partial which builds the JS:


{{ $searchJS := "" }}
{{ with site.Params.algolia }}
	{{ $indexName := printf `"%s"` .indexName }}
	{{ $appID := printf `"%s"` .appID }}
	{{ $searchKey := printf `"%s"` .searchKey }}
	{{ $externalLink := printf `'%s'` (partial "svg" "fas fa-external-link-alt") }}
	{{ $baseURL := printf `"%s"` site.BaseURL }}
	{{ $defines := dict "_indexName" $indexName "_appID" $appID "_searchKey" $searchKey "_externalLink" $externalLink "process.env.NODE_ENV" $nodeEnv "_baseURL" $baseURL }}

	{{ if $mustOptimize }}
		{{ $algoliasearch := readFile "/node_modules/algoliasearch/dist/algoliasearch-lite.umd.js" | resources.FromString "js/algoliasearch-lite.umd.js" }}
		{{ $instantsearch := readFile "/node_modules/instantsearch.js/dist/instantsearch.production.min.js" | resources.FromString "js/instantsearch.production.js" }}
		{{ $searchJS = partial "functions/parse_js" (slice "js/search.js" $defines) }}
		{{/*  {{ $searchJS = resources.Get "js/search.js" | js.Build (dict "defines" $defines "externals" (slice "algoliasearch/lite" "instantsearch.js/es/lib/main")) }}  */}}

		{{ $searchJS = slice $algoliasearch $instantsearch $searchJS | resources.Concat "js/search.js" }}
	{{ else }}
		{{ $searchJS = resources.Get "js/search.js" | js.Build (dict "defines" $defines) }}
	{{ end }}
{{ end }}