htmx
htmx copied to clipboard
Do not initialize htmx automatically on DOM ready when loaded as module
As discussed in #1469, when using htmx in a module environment, some internal extensions, such as preload, do not work properly. This is because htmx initializes itself on DOM ready, while the extensions become available later in the lifecycle. Therefore, it is necessary to disable the auto-initialization of htmx in these environments and expose a new API function htmx.start() to initialize htmx manually.
import htmx from 'htmx.org';
import <extensions>
htmx.start();
Related Issue: #1469
@matteocontrini please give it a try. You can use my Repo+Branch in npm with the following command.
npm i htmx.org@"git+https://github.com/xhaggi/htmx#fix/ext-async-loading"
@xhaggi confirming it works.
I think the htmx import should be import * as htmx from 'htmx.org' and not import htmx from 'htmx.org', though.
Thank you @matteocontrini.
I think the htmx import should be import * as htmx from 'htmx.org' and not import htmx from 'htmx.org', though.
Why do you think we need a namespace import here?
import htmx, * as htmx2 from 'htmx.org'
console.log(htmx === htmx2) // --> true
@xhaggi it might be that typings are incorrect but there is no default export:
https://github.com/bigskysoftware/htmx/blob/34612f0d0cfcd631d145a308eef5e079a5a53181/src/htmx.d.ts
So TypeScript complains if you use the default import syntax.
If it works with plain JavaScript, I guess typings are wrong.
@matteocontrini I see what you mean. When I use your sample project in VSCode everything works. Compiling the main.ts and Vite dev/build also works. Am I missing anything to reproduce the problem?
import htmx from 'htmx.org';
import 'htmx.org/dist/ext/preload.js';
import 'htmx.org/dist/ext/debug.js';
htmx.start();
@xhaggi ah yes that's because that project uses esnext as the module syntax (see tsconfig.json), which automatically enables the esModuleInterop option that makes the default import syntax work.
If you change the module system to commonjs (the default) it won't work. So yeah, it depends on the setup, but import * as htmx from "htmx" should work always, I think.
@matteocontrini you are right and thank you for pointing me to the right direction. I wonder why there is a TypeScript test file src/htmx.test.ts where the default import is also used. When you call npx tsc --noEmit src/htmx.test.ts you get the error Module has not default export. Without the .d.ts you can use a default import and it works, also in your sample project. So it might be a problem with the type declaration, but that is out of scope of this PR.
I've tested and confirmed that this is working fine when using htmx and extensions with the native ESM support in the browser (without any JS bundler).
Marking this as an enhancement due to possible regressions. Will get this looked at soon, but in the meantime do you mind rebasing @xhaggi? Also, we don't edit the dist files directly, just the source.
@alexpetros done.
Also, we don't edit the dist files directly, just the source.
I know, and those changes were part of a commit that was marked to be skipped before the merge. I dropped that commit now.
@xhaggi can we close this PR since we merged this one? https://github.com/bigskysoftware/htmx/pull/1659
Sure. I can confirm that it works with the other fix.