TIL how to alias dependencies in ES modules fetched from the ESM CDN

I’m slowly getting into Preact, Deno + Deno Fresh and Typescript. So far, Deno Fresh has been enjoyable. Naturally, just like Deno it allows for importing ES modules via HTTPS. At some point today I wanted to use an NPM package, one which uses React internally, and I had to figure out how to tell that dependency to not use React but Preact instead.

Screenshot of the third code block from the post

So, to recap: load an React-related ES module from a CDN but have it use Preact as dependency instead.

Preact comes with its own compatibility layer, preact/compat:

[…] our compatibility layer that allows you to leverage the many libraries of the React ecosystem and use them with Preact. This is the recommended way to try out Preact if you have an existing React app.

And then there is ESM.sh, a global CDN for NPM packages with ES Module format. Luckily, ESM has a super-handy feature for aliasing dependencies which allows me to tell ESM to get a NPM package but change its internal requirement from react to preact/compat! Noice.

I wanted to import Statery (“surprise-free state management!") which internally uses React (excerpt from its index.ts):

import { useEffect, useRef, useState } from "react"

So, in a Node- & React-based app I’d call it like this (after adding the NPM package to my package.json:

import { makeStore, useStore } from "statery";

In my Deno Fresh- & Preact-based app I instead use ESM’s URL with aliasing parameters:

import {
  makeStore,
  useStore
} from "https://esm.sh/statery@0.5.4?alias=react:preact/compat&deps=preact@10.8.2";

Side note: if I omit the deps= argument ESM assumes I want the latest version of Preact (10.10.x), which clashes with 10.8.2 used in Fresh (at the time of this writing).

When I fetch the standard ESM URL for Statery (https://esm.sh/statery@0.5.4) as well as the one containing the alias argument (https://esm.sh/statery@0.5.4?alias=react:preact/compat&deps=preact@10.8.2), and then follow the single import URL in each of them to get to its module, I can see the following difference:

// before
import{useState as a,useRef as b,useEffect as i}from"/v87/react@18.2.0/es2022/react.js"

// after
import{useState as a,useRef as b,useEffect as i}from"/v87/preact@10.8.2/es2022/compat.js"

That is neat.

So: aliasing works absolutely fine, and it’s a good-enough practice until I’m told otherwise by people more knowledgeable than myself. :)

Thanks to the absolute champs over at denoland/fresh/discussions/ for the pointer.

Tags: #til #esm #javascript #typescript #deno #preact

💬 Reply by email     ⭐️ Also on micro.blog
Carlo Zottmann @czottmann