Note: This site is currently "Under construction". I'm migrating to a new version of my site building software. Lots of things are in a state of disrepair as a result (for example, footnote links aren't working). It's all part of the process of building in public. Most things should still be readable though.

Make And Use A JavaScript Module Directly Inside A Single HTML File

Introduction

I like writing completely self contained files in my notes that publish and work directly on my site without additional build steps or processing. I'm also moving more and more to using JavaScript modules for things. It took a bit to figure out how to combine those two since modules usually come as separate files.

Here's what I'm doing:

HTML

<script type="text/template" class="widget">
  export function ping() {
    console.log('This is from the inline module')
  }
</script>

<script type="module">
  const { ping } = await import(
    URL.createObjectURL(
      new Blob(
        [document.querySelector('.widget').innerText],
        {type: 'application/javascript'}
      )
    )
  )
  ping()
</script>

Details

  • The first `script`` tag contains the code for the module

  • Browsers don't try to execute `script`` tags when the `type`` attribute is set to `text/template``. So, the first tag doesn't do anything directly

  • The second `script`` tag is a regular module

  • Instead of loading a module from a separate file it uses `.createObjectURL()`` to simulate a new file to load from

  • The `.innerText`` content from the first script is included in a `Blob`` which gets assigned a type of `application/javascript`` and fed into the `.createObjectURL()``

  • When all of that is passed to `await import()`` it acts the same as if an external file was used and the contents of the first `script`` tag get loaded as a module

  • Check the console and you'll see the "This is from the inline module" output from calling `ping()``

With all that in place I can write a single file that includes the module directly. I really like the approach.

References