Current JS Setup #
I wanted to update the JavaScript for the Vega Lite charts and Mermaid diagrams shortcodes.
The JavaScript for both shortcodes used to be imported into the page based on some front matter in Hugo pages.
Check out the mermaid: false front matter in the template for my blog posts:
| |
If set to true, the script.hml partial would load the appropriate JavaScript:
| |
I kept forgetting to set the true front matter to load the correct JS for each page and honestly just wanted:
- The latest JS for my plugins like Vega and Mermaid
- Keep all the JS inside the
vega.htmlandmermaid.htmlshortcode files (which is how Hugo supports plugin-type inclusions).
JavaScript EcmaScript (ES) Modules to the rescue!
ES Modules #
Mozilla Developer Network covers ES Modules thoroughly. The bit that I hadn’t realized previously is that ES Modules are loaded very efficiently by modern browsers through their use of caching. If an ES Module is loaded once on a page, it will not be loaded again if there are other attempts to load it.
This is the workaround I needed to stop doing if mermaid is true then load the mermaid.js in the script block dance.
Instead, I can just load the ES Module for, say, Mermaid or Vega multiple times without worrying about the browser loading it again.
Bottom line: I could rework my shortcodes to use ES Modules, and stop worrying about whether I needed to explicitly mermaid: true or vega: true load them.
I made a series of changes to my shortcodes and how scripts are loaded in the Hugo site behind this blog.
For example, the Mermaid shortcode now looks like this with a script type=module and a modern import statement (ignore the Go-isms because it’s really a Go HTML template):
| |
Mermaid is smart enough not to initialize more than once per page, so we’re good.
Optimized Builds #
While looking at the browser console I notices that there were many more networking requests that I expected. Yes, the main ES module file was only being requested once, but what are all these ‘chunks’?

Module loading with option build-time chunks being loaded as static dependencies (sub-imports)
I loaded my Tips page and looked at what the Vega requests looked like, and it was the same: 20 or more requests. I followed one of the links and saw in the documentation header that this is a build-time optimization that ES modules make trivially easy:
| |
And it all makes sense now why I see Rollup being used all over the place to optimize builds by only included what is strictly necessary.
So double win:
- I only import ES modules once when I reference them 1+ times: browser caching.
- Only the strictly necessary code is downloaded due to optional module static analysis and tree shaking.
Neat!