Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Provide ESM support and add minified versions #123

Open
wants to merge 5 commits into
base: main
Choose a base branch
from

Conversation

marisst
Copy link
Contributor

@marisst marisst commented Dec 19, 2024

Change 1: ESM import and bundler support

Make it possible to import extensions as ESM modules and use bundlers (e.g. Webpack, Vite, Rollup).

  • currently it is possible to install extensions using npm install htmx-ext-extension-name and integrate them using <script src="node_modules/htmx-ext-extension-name/extension-name.js"></script>
  • however, import 'htmx-ext-extension-name'; results in Uncaught ReferenceError: htmx is not defined
  • there is a workaround available which requires creating a htms.js file to inject htmx in windows scope so that the extension can use the. It has to be done in a separate file because ESM imports are asynchronous. This PR elminates the need for the workaround and allows to integrate HTMX and extensions in much cleaner way using ESM imports. Most bundlers support this by default (e.g. Webpack, Vite, Rollup).
import `htmx.org`;
import `htmx-ext-extension-name`; // Replace `extension-name` with the extension name

This change solves 4 issues:

Change 2: Minified versions

Add minified extension script versions to unpkg.com/htmx-ext-extension-name.

  • significant script size reduction and improved page load speed in all applications using htmx extensions from CDN
  • unminified version will be available by unpkg.com/htmx-ext-extension-name/dist/extension-name.js
  • gzip version will be available by unpkg.com/htmx-ext-extension-name/dist/extension-name.min.js.gz

This change solves 2 issues:

Consistency with core htmx and documentation

The change is implemented following the approach of the core htmx library.

Documentation is updated in a corresponding pull request in the core htmx repository: bigskysoftware/htmx#3078.

Extra steps in deployment

This change adds 3 extra steps when publishing extensions to npm and require to run the following shell commands from the base directory of this repository.

  • npm install to install uglify-js dependency, which does the script minification
  • chmod +x scripts/dist-all.sh to add permissions executing the scripts/dist-all.sh script from npm
  • npm run dist to execute the script which generates IIFE, min, gzip and ESM versions of all extensions and adds them to a dist directory in each extensions folder. This command also prints the updated CDN script tags with latest version number and SRI hash to make documentation updates easier.

Guide for reviewers

This update changes 57 files in the repository because it touches boilerplate code. Here is an overview of the key changes.

Changes in the root and scripts directories (4 files):

  • scripts/dist-all.sh is a new script which adds sub-folder dist with distribution files in IIFE, min, gzip and ESM formats. It is heavily inspired of the dist script of the core htmx library and the test-all script.
  • package.json is added with the sole purpose to introduce uglify-js dependency and make it possible to run scripts/dist-all.sh from npm.
  • package-lock.json is automatically generated when running npm install based on package.json and the old version is therefore overridden. I believe that the old version is just a copy-paste leftover from when this repository was split out of the core repository, but please let me know if I am mistaken.
  • .gitignore is updated to avoid committing distribution files.

Changes in extension directories src/extension-name (53 files):

  • extension-name.js - extensions which were not following IIFE are now wrapped (10 files)
(function() {
    // extension code
})()
  • package.json of all extensions have been updated (23 files):
    • "htmx.org": "^2.0.2" is moved from devDependencies to dependencies
    • "main": "extension-name.js" is replaced with "main": "dist/extension-name.esm.js",
    • "unpkg": "dist/extension-name.min.js" is added
    • main and unpkg properties have been added after version and homepage properties for consistency, following the package.json file of the core htmx package.
    • only for core extensions: added "homepage": "https://htmx.org/extensions/extension-name/" property
  • package-lock.json has been automatically updated based on changes in package.json (20 files)

Copy link

netlify bot commented Dec 19, 2024

Deploy Preview for htmx-extensions canceled.

Name Link
🔨 Latest commit 19a23a8
🔍 Latest deploy log https://app.netlify.com/sites/htmx-extensions/deploys/676478dfb874540008031f99

@scrhartley
Copy link
Contributor

scrhartley commented Dec 19, 2024

"htmx.org": "^2.0.2" is moved from devDependencies to dependencies

I'm not sure this makes sense since it ties you a particular version of htmx
and the extensions tend to be updated less often, so you're more likely to want to update htmx and not the extension.
Additionally you're introducing a possibility of mixed extension versions potentially causing htmx version conflicts.

@scrhartley
Copy link
Contributor

In this docs PR, they seem to imply that you can already do:

import 'htmx-ext-debug/debug.js';

@marisst marisst changed the title Provide minified extension versions and add ESM to support bundlers Provide minified versions and add ESM to support bundlers Dec 20, 2024
@marisst marisst changed the title Provide minified versions and add ESM to support bundlers Provide minified versions and add ESM support allowing to use bundlers Dec 20, 2024
@marisst marisst changed the title Provide minified versions and add ESM support allowing to use bundlers Provide minified versions and add ESM support Dec 20, 2024
@marisst marisst changed the title Provide minified versions and add ESM support Provide minified versions and add bundler support through ESM Dec 20, 2024
@marisst
Copy link
Contributor Author

marisst commented Dec 20, 2024

@scrhartley Simon, thank you for your comments.

Regarding moving "htmx.org": "^2.0.2" from devDependencies to dependencies in extension package.json

I'm not sure this makes sense since it ties you a particular version of htmx
and the extensions tend to be updated less often, so you're more likely to want to update htmx and not the extension.

You are right about htmx updating more often than any of the extensions. The dependency ties you to a minimum version of htmx.org using the ^ operator. If a newer version is available, it will be used automatically. I don't see this being a problem. Please let me know if I am missing something.

Additionally you're introducing a possibility of mixed extension versions potentially causing htmx version conflicts.

I see. I imagine a version conflict if somebody is, let's say, strictly using version 2.0.0 of htmx.org in their project/package.json, but they also depend on a version of an extension (e.g. htmx-ext-preload), which requires ^2.0.3 of htmx.org. This will result in a failed build, because 2.0.0 and ^2.0.3 are incompatible.

I this case they should upgrade from 2.0.0 to at least 2.0.3 version of htmx.org in order to use this version of the extension. Otherwise they can use an older version of the extension, which does not require ^2.0.3 of htmx.org. I believe this is how it should be, otherwise extensions cannot evolve to use the latest features of the htmx core library.

What I can do is to make sure the minimum version of htmx that each extension requires really represents the lowest possible version it can function with. Anyways, this change does not break existing ways of integrating htmx extensions, so I don't think this should be a concern to stop the PR. What do you think?

In this docs PR, they seem to imply that you can already do:

import 'htmx-ext-debug/debug.js';

The docs PR you mentioned is describing a workaround, which requires creating a separate htmx.js to inject htmx into the window scope, so that the extensions can use it. It has to be done in a separate file, because ESM imports are asynchronous.

This PR fixes the root cause which has created the need for the workaround. With this PR there is no need to create a separate htmx.js file and inject htmx to the windows scope. It provides a much cleaner way of importing extensions.

import `htmx.org`;
import `htmx-ext-extension-name`; // Replace `extension-name` with the extension name

I have updated the description of this PR to reference the workaround, and I have also left a comment in bigskysoftware/htmx#2668. I hope that answers your concern.

@marisst marisst changed the title Provide minified versions and add bundler support through ESM Provide minified versions and add bundler support with ESM Dec 20, 2024
@marisst marisst changed the title Provide minified versions and add bundler support with ESM Provide minified versions and bundler support with ESM Dec 20, 2024
@scrhartley
Copy link
Contributor

I appreciate the detailed reply.
You make good arguments and clearly you understand things better than I do.

For the IIFE change, for the files previously without it, they don't seem to fall into the use cases described in the page you linked.
Have you just made this change for consistency?

@marisst
Copy link
Contributor Author

marisst commented Dec 20, 2024

For the IIFE change, for the files previously without it, they don't seem to fall into the use cases described in the page you linked.
Have you just made this change for consistency?

@scrhartley Yes it's mainly for consistency with the other 14 extensions which are already are in the IIFE form. If you have a concern about this change please let me know and I will revert it. It's not very important for the scope of the PR.

@marisst marisst changed the title Provide minified versions and bundler support with ESM Provide bundler support with ESM and minified versions Dec 21, 2024
@marisst marisst changed the title Provide bundler support with ESM and minified versions Provide ESM support and add minified versions Dec 21, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants