πŸ₯ž The tale of ESM and the bundlless bundler πŸ“š

Adam Crockett πŸŒ€ - Jun 23 '20 - - Dev Community

I have an ongoing project which uses 99% ESM (ecmascript modules) no build steps ecetera. With the rise of Deno (finally) I thought about how a browser could work with the same non centralized dependcy manager, (eg. You).

We already have cdns and esmodules, but with a far larger common js (CJS) ecosystem, thanks to node.js writing the rulebook in the interim. But some time later an official ecmascript standard was released, import export ❀️. To be fair to node.js, they started supporting it under a flag and nowerdays it's a working thing. But I put it to you that the damage has been done, we still see CJS style libraries everywhere.

It seems like slow progress for library authors to catch-up, that's also making a big assumption that they even care to target ESM directly, bundlers and tooling such as Babel and Typescript gave us the ability to transpile this functionality down to lesser EcmaScript, in some circumstances for the best support the resulting code uses require.

Detour

If we head over to pika.dev you will find a wonderful CDN that will find ESM supported libraries over at npm, provide a URL, distribution code and even Typescript types all in one request! it's a great tool for Deno and also frontend too.

Your brain on Pika

The trouble is that you will quickly start cycling through libraries degrading your original choice if that library isn't currently supporting ESM. An example, for some reason I want to use jQuery, I query pika and no, jQuery is found but doesn't support ESM, so now what?

Withdrawal

I might think of libraries similar to jQuery, maybe Zepto, is that thing still around? Nope, okay what about this one, "bobs-jquery-esm-fork"... So first I think, do I trust this Bob? Is he going to steal my πŸ’° money somehow, I do some digging, okay looks legit, is Bob keeping this fork up-to-date? Hmm it's the best option I have.
I could raise a ticket over on Microsoft GitHub, but I really neeeed jQuery in my life right now. Hmph okay let's do it.

Anger

You can see the problem with ESM, despite it's many advantages, perf and simplicity benefits, I should just go get a library and use it and not have to deal with this πŸ’©.

Denial

What to do, what to do? Well I'm going to look for some tooling like webpack but in the style of ESM. Looks like pika built something called pika pack. What's that? Well
the glossy marketing website hadn't been created so I couldn't understand what the engineers where saying it does, but I understand one thing, superseded by Snowpack.

Snowpack, now that's a great name πŸ’ but is it marriage material? The docs are okay, 4 🌟. TLDR on this one, it's incredible but not for my project which is a pitty, Typescript has been a big part of my life even before it was cool. However Typescript support seems to be largely Babel powered and configuration is abstracted, this is probably great but not me, I'm a tinkerer and I believe that defaults don't cut it for long.

Acceptance Criteria

So what else? Without going down the realms of the obscure, let's just make something, it's not like I didn't explore and research before coming to the conclusion that I would like the following.

  • Convert CJS to ESM
  • Must have developer buy in and open source support
  • Use npm or yarn to download dependencies just like Webpack workflows.
  • Must not bundle (HTTP2 and 3 I'm thinking of you)
  • Create a config file which specifies the dependencies I would like to πŸ§™β€β™‚οΈ magically transform into ESM.
  • Ability to add CDN urls to this list and have them download and ESMify, this should cover edge cases where transforming didn't work out.
  • Must accept both Typescript and JavaScript sources; transpiling to .mjs (tsc can't do this!)
  • All ESM to sit in a flat directory structure just like modern node_modules, guess we should call it es_modules folder.
  • The tool must focus only on dependencies for the browser but will try to help Deno users with node_module compatibility.
  • must throw away unused CJS or development deps via runtime headless browser evaluation
  • Generate .importmaps to stitch it all together

Not again!

Wow that's going to take me 20 years, fortunately Typescript to the rescue, the TSC compiler has some and I say that loosely, documentation on using the TSC compiler Api. This Api allows a developer to write up bespoke compiler programs using TSC under the hood, it sounds involved but it's not to bad really, you can write a compiler in maybe 30 lines. Anyway it has some interesting properties that make it ideal, for one, it has transformers. No not Optimus 🚚, I mean it introspects code you tell it to and allows you to change stuff. If I point my custom tsc program at a CJS module, I can have it take in JavaScript and typescript and have that all transform to export import syntax.

There is even a transform out in userland I can use, now all I need to do is impliment the rest of my wish list.

❀️ Hope you enjoyed! πŸ¦„
🌟 Please star the repo if interested, it helps me out alot!🌟

Introducing Unpack

github.com/adam-cyclones/unpack

... but at the moment its broken because I am refactoring it into lib and cli packages.

. . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . . .