title: Inlining ECMAScript Modules in HTML
body: <p>I've been experimenting with new <a href="https://jakearchibald.com/2017/es-modules-in-browsers/" rel="noreferrer">native ECMAScript module support</a> that has recently been added to browsers. It's pleasant to finally be able import scripts directly and cleanly from JavaScript.</p>
  <a href="https://795258201.glitch.me/example.html" rel="noreferrer">    <strong><code> /example.html  </code></strong>    </a>
  <pre class="lang-html prettyprint-override"><code>&lt;script type=&quot;module&quot;&gt;
    import {example} from '/example.js';
  
    example();
  &lt;/script&gt;
  </code></pre>
  <a href="https://795258201.glitch.me/example.js" rel="noreferrer">    <strong><code> /example.js </code></strong>    </a>
  <pre class="lang-js prettyprint-override"><code>export function example() {
    document.body.appendChild(document.createTextNode(&quot;hello&quot;));
  };
  </code></pre>
  <p>However, this only allows me to import modules that are defined by separate <strong>external</strong> JavaScript files. I usually prefer to inline some scripts used for the initial rendering, so their requests don't block the rest of the page. With a traditional informally-structured library, that might look like this:</p>
  <a href="https://795258201.glitch.me/inline-traditional.html" rel="noreferrer">    <strong><code> /inline-traditional.html  </code></strong>    </a>
  <pre class="lang-html prettyprint-override"><code>&lt;body&gt;
  &lt;script&gt;
    var example = {};
  
    example.example = function() {
      document.body.appendChild(document.createTextNode(&quot;hello&quot;));
    };
  &lt;/script&gt;
  &lt;script&gt;
    example.example();
  &lt;/script&gt;
  </code></pre>
  <p>However, naively inlining modules files obviously won't work, since it would remove the filename used to identify the module to other modules. HTTP/2 server push may be the canonical way to handle this situation, but it's still not an option in all environments.</p>
  <p>Is it possible to perform an equivalent transformation with ECMAScript modules?</p>
  <p>Is there any way for a <code>&lt;script type=&quot;module&quot;&gt;</code> to import a module exported by another in the same document?</p>
  <hr />
  <p>I imagine this could work by allowing the script to specify a file path, and behave as though it had already been downloaded or pushed from the path.</p>
  <a href="https://795258201.glitch.me/inline-name.html" rel="noreferrer">    <strong><code> /inline-name.html  </code></strong>    </a>
  <pre class="lang-html prettyprint-override"><code>&lt;script type=&quot;module&quot; name=&quot;/example.js&quot;&gt;
    export function example() {
      document.body.appendChild(document.createTextNode(&quot;hello&quot;));
    };
  &lt;/script&gt;
  
  &lt;script type=&quot;module&quot;&gt;
    import {example} from '/example.js';
  
    example();
  &lt;/script&gt;
  </code></pre>
  <p>Or maybe by an entirely different reference scheme, such as is used for local SVG references:</p>
  <a href="https://795258201.glitch.me/inline-id.html" rel="noreferrer">    <strong><code> /inline-id.html  </code></strong>    </a>
  <pre class="lang-html prettyprint-override"><code>&lt;script type=&quot;module&quot; id=&quot;example&quot;&gt;
    export function example() {
      document.body.appendChild(document.createTextNode(&quot;hello&quot;));
    };
  &lt;/script&gt;
  &lt;script type=&quot;module&quot;&gt;
    import {example} from '#example';
  
    example();
  &lt;/script&gt;
  </code></pre>
  <p>But neither of these hypotheticals actually work, and I haven't seen an alternative which does.</p>