Search code examples
htmlcdnpreact

A method to get specific exports when using <script src="">


I'm making a site with Preact & Tailwind. In the code here (I know it doesn't have head, body, e.t,c but that isn't relevant to the code):

<script src="https://unpkg.com/tailwindcss-jit-cdn"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/preact/10.11.2/preact.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/htm/3.1.1/htm.js"></script>
<script>
htm.bind(h)
let component = htm`<p>Hello World</p>`

</script>

htm and h are parts of the Preact and HTM cdn. How do I get htm and h from the preact/htm cdns? I don't want to use a node_modules, as i want it to be a copypastable template html to use anywhere, like WordPress, replit, codepen, e.t.c. I also don't want to use as the way my code is setup it would look weird and bad to read.


Solution

  • Adding a dependency (or dependencies) via <script> adds those to the global scope. h, in the example above, is undefined as you have not specified where it comes from.

    <script src="https://unpkg.com/tailwindcss-jit-cdn"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/preact/10.11.2/preact.min.js"></script>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/htm/3.1.1/htm.js"></script>
    <script>
        let html = htm.bind(preact.h)
        let component = html`<p>Hello World</p>`
    </script>
    

    (Adjusted code, as htm.bind alone will not work. Need to assign & use the result).

    This, however, is less than ideal in the modern age of ESM. Messing with globals is just rather unnecessary. Instead, use the following:

    <script src="https://unpkg.com/tailwindcss-jit-cdn"></script>
    <script type="module">
        import { h } from 'https://cdn.skypack.dev/preact';
        import htm from 'https://cdn.skypack.dev/htm';
    
        let html = htm.bind(h);
        let component = html`<p>Hello World</p>`;
    </script>
    

    Or, even better yet, use htm/preact export to skip manually binding altogether:

    <script src="https://unpkg.com/tailwindcss-jit-cdn"></script>
    <script type="module">
        import { html } from 'https://cdn.skypack.dev/htm/preact';
        let component = html`<p>Hello World</p>`;
    </script>
    

    Unpkg has a number of issues (very difficult to fix, if not impossible. Not a criticism, unpkg was built in a different time) regarding ESM usage, specifically for Preact, resolving package.json "exports" and sometimes duping the Preact instance. This is an issue for hooks, as they require a singleton by design. This is why I'd recommend Skypack or esm.sh. They're built for ESM and work brilliantly.