htmx
htmx copied to clipboard
Add ES Module (ESM) support to the factory
Hi there 👋,
Currently, the factory supports AMD, CJS and browser environments. However, modern websites and browsers have proper module (ESM) support.
Let's say you want to do something like this:
<!DOCTYPE html>
<html lang="en">
<head>
<title>HTMX via ESM</title>
</head>
<body>
<script type="module">
import htmx from 'https://unpkg.com/htmx.org'
htmx.logAll()
</script>
</body>
</html>
Your browser will tell you that htmx.org doesn't export a default. Similarly, something like this also does not work:
import { logAll } from 'https://unpkg.com/htmx.org'
logAll()
Both are completely valid use cases and have, as of writing this, over 97% browser support.
I think adoption would be rather simple. Everything already works in NodeJS or rather CommonJS (CJS). All that's needed would be to extend the factory to export ESM modules in a browser.
If you want to take this one step further, we could also consider to properly defining entry points via NodeJS' exports. This would be particularly helpful if you wish to load extensions.
I would be happy to contribute a small patch.
Cheers! Joe
Hey, it seems (I know nothing about all this so you tell me 😆) we have esm support in v2 alpha, if you're willing to take a look and test if things work as expected?
Hey, it seems (I know nothing about all this so you tell me 😆) we have esm support in v2 alpha, if you're willing to take a look and test if things work as expected?
Nope, no luck. 2.0 doesn't export anything. And the extensions are not declared in the package.json file, either.
I happen to know a thing or two about ESM, I am happy to help. Just say the word and I will gladly submit a patch.
in v2.0 we have a .esm.js file that does export htmx:
https://github.com/bigskysoftware/htmx/blob/f004978bbbf68befb49bfef7f17a2ec25ce35ae0/dist/htmx.esm.js#L3917
in v2.0 we have a .esm.js file that does export htmx:
https://github.com/bigskysoftware/htmx/blob/f004978bbbf68befb49bfef7f17a2ec25ce35ae0/dist/htmx.esm.js#L3917
Yes, I saw that, but that's not how you export an ESM module ;)
I must have missed what export stands for. ;)
And for the sake of everyone’s sanity, let’s not overcomplicate it for nothing.
in v2.0 we have a .esm.js file that does export htmx: https://github.com/bigskysoftware/htmx/blob/f004978bbbf68befb49bfef7f17a2ec25ce35ae0/dist/htmx.esm.js#L3917
Yes, I saw that, but that's not how you export an ESM module ;)
Would you like to elaborate on this...? I too have been laboring under the delusion that one exported ECMAScript modules with the export command.
Please excuse my previous response. I didn't explain it well. Let me try again:
Yes, export is used to export in ESM, but nothing is ever simple in JavaScript. htmx is an anonymous function. Anonymous functions may only be exported as a default. So, you either name the export, name the function, or export it as a default. Defaults don't need to be named.
Again, super happy to provide a patch, with tests. If my help is still welcome ❤️🩹
is it an anonymous function? I thought it was a plain javascript object returned by the IIFE...
is it an anonymous function? I thought it was a plain javascript object returned by the IIFE...
https://github.com/bigskysoftware/htmx/blob/f004978bbbf68befb49bfef7f17a2ec25ce35ae0/src/htmx.js#L1
It's exporting the outer wrapper, not the object. Both would not be leading to the desired result. The latter would allow at least something like import * as htmx from 'htmx.org'. But that's maybe not the way to go here. A default export might be the most elegant and intuitive solution for most.
Please excuse my previous response. I didn't explain it well. Let me try again:
Appreciated! And don't worry about it.
The latter would allow at least something like import * as htmx from 'htmx.org'.
Correct me if I'm wrong, but the current export { htmx } statement we have in the the esm wrapper supports this, right?
The latter would allow at least something like import * as htmx from 'htmx.org'.
Correct me if I'm wrong, but the current
export { htmx }statement we have in the theesmwrapper supports this, right?
No, it does not. export htmx without the breakets might work… I would need to check.
But again, whether there is a bug, this is fairy easy to reproduce:
Here is HTMX.org 2.0-alpha2
Here is Lit, just to show how a module should look like in a browser.
Oh, I know exactly what you're talking about—you can't export anonymous objects from an export statement i.e. the export {} just doesn't work. I completely forgot about that. Okay so the existing factory is bugged—we can fix that.
Is the change you were going to suggest just export default htmx?
I am adding myself to this as I also need ESM exports to allow reuse.
there are some hacks to overcome it....
https://github.com/terrablue/htmx-esm btw, is used by
https://github.com/primatejs/primate https://primatejs.com/modules/htmx
If this is implemented, it would be nice to add deep exports in package.json for the extensions such that it's possible to do something like export * from "htmx.org/client-side-templates/handlebars"; to be picked up by the bundler, see https://github.com/terrablue/htmx-esm/blob/master/package.json#L11-L38
I would be more than happy to get rid of the needless vendoring, seeing as I need to update it every time a new HTMX version comes out.
If this is implemented, it would be nice to add deep exports in
package.jsonfor the extensions such that it's possible to do something likeexport * from "htmx.org/client-side-templates/handlebars";to be picked up by the bundler, see https://github.com/terrablue/htmx-esm/blob/master/package.json#L11-L38I would be more than happy to get rid of the needless vendoring, seeing as I need to update it every time a new HTMX version comes out.
Yes, I mentioned that in the original ticket report. I will submit a patch for that.
Is the change you were going to suggest just
export default htmx?
Yes, I believe this would be most consistent with the docs, where you call htmx.someFunction. Be it on a window or module scope. I will be easy copy and paste for most people.
Since there seems to be plenty of traffic on this issue, I will submit a patch targeting the 2.0 release.
I looked at the code for 2.0 and decided to discontinue using HTMX. Maybe someone else will pick this up someday.
I looked at the code for 2.0 and decided to discontinue using HTMX. Maybe someone else will pick this up someday.
Would you like to share what it was about the 2.0 code that discouraged you? It's really not that different
I looked at the code for 2.0 and decided to discontinue using HTMX. Maybe someone else will pick this up someday.
Would you like to share what it was about the 2.0 code that discouraged you? It's really not that different
Hi @alexpetros, I would rather not discourage anyone. I know how much work goes into a project this size. Thus, will stick to errors:
- extensions are not built in 2.0
- test suite wasn't fully working (some files were renamed, but not their references)
- extension are neither CSJ or ESM compatible
As a personal note: Tools like Wireit and Rollup or ESbuild might make the build processes more smooth. Lifting browser support to Baseline 2023 might also simplify things.
I appreciate the effort put into this package <3 We use mostly Web Components and are fairly happy writing JavaScript code and have maybe not the ideal user profile.
Ok! Well, anyway, we're going to switch to default exports for htmx 2.0: https://github.com/bigskysoftware/htmx/pull/2428