HUGO

Hugo integration with js.Build (ESBuild) and multiple output files

{{ resources.Get "script.js" | js.Build }} uses the ESBuild api as a single entry point and expects a single output file (to pass through additional pipes).

ESBuild, though, sometimes creates multiple output files from a single entry point, e.g. code splitting, external source maps, and “import *.css” statements in javascript files.

This leads to my question: how will/should Hugo handle multiple outputs from ESBuild in Hugo Pipes? Currently, Hugo already added external source maps as a developer utility. The css example is an issue I encountered (#8411) and the code splitting would be an issue if Hugo further integrated with ESBuild.

That is a good question, and I’m not totally sure. The current source map solution isn’t ideal, but we added it just because we really needed it. I have written some about CSS import in the relevant issue.

As to code splitting, we obviously would need something “more”, and I guess the real benefit comes from reuse – so we need a registry/cache for that. I’m thinking that we would need something ala:

{{ $js = $js | js.Build }}
{<script src="{{ .RelPermalink }}"></script>
{{ range .Fragments }}
{<script src="{{ .RelPermalink }}"></script>
{{ end }}

Where .Fragments would be potentially be code also used by others.

Do you know what the status is in ESBuild re code splitting?

It looks like the feature was released in version 0.5.16 (current version is 0.11.17). It is still marked as a WIP on the main page and it currently works only with the esm output format. I have not experimented with ESBuild nor explored the code enough, though, to fully comment on its status.

Adjust resolveComponentInAssets to handle CSS imports the way we handle JS imports (I assume this should work, but I have not tested)

I will look into this method to see if there is a way to resolve the CSS import; however, I’m not sure if it would make sense. The only way to know a .js file in assets is importing a CSS file is during the transform() method unless we parse the code for import statements and resolve them through Hugo before handing it over to ESBuild. Unless I misunderstand,which is very possible as I’ve only been going through Hugo for a few weeks and you have years of experience.

I will see if I can use the {{ .Fragments }} idea, maybe with a {{ if css }} or {{ if js }} or something to allow html script tags or stylesheet tags. Other ideas are very welcome.