htmx icon indicating copy to clipboard operation
htmx copied to clipboard

Do not initialize htmx automatically on DOM ready when loaded as module

Open xhaggi opened this issue 2 years ago • 7 comments

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

xhaggi avatar Jun 07 '23 10:06 xhaggi

@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 avatar Jun 07 '23 10:06 xhaggi

@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.

matteocontrini avatar Jun 07 '23 20:06 matteocontrini

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 avatar Jun 08 '23 06:06 xhaggi

@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 avatar Jun 08 '23 06:06 matteocontrini

@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 avatar Jun 08 '23 09:06 xhaggi

@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 avatar Jun 08 '23 12:06 matteocontrini

@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.

xhaggi avatar Jun 09 '23 08:06 xhaggi

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).

guilleiguaran avatar Jul 25 '23 03:07 guilleiguaran

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 avatar Jul 29 '23 21:07 alexpetros

@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 avatar Aug 07 '23 11:08 xhaggi

@xhaggi can we close this PR since we merged this one? https://github.com/bigskysoftware/htmx/pull/1659

alexpetros avatar Aug 07 '23 15:08 alexpetros

Sure. I can confirm that it works with the other fix.

xhaggi avatar Aug 08 '23 10:08 xhaggi