Skip to content

Add minified ESM build output for each package#4820

Merged
calebporzio merged 1 commit intomainfrom
josh/add-module-esm-min-build
Apr 30, 2026
Merged

Add minified ESM build output for each package#4820
calebporzio merged 1 commit intomainfrom
josh/add-module-esm-min-build

Conversation

@joshhanley
Copy link
Copy Markdown
Collaborator

The Scenario

Users loading Alpine directly in the browser via <script type="module"> (no bundler) have been importing Alpine from a minified ESM file that was present in every npm tarball up to 3.15.10:

<script type="module" src="/app.js"></script>
import Alpine from '../node_modules/alpinejs/dist/module.esm.min.js';

window.$selectedFiles = Alpine.reactive([]);
Alpine.start();

From 3.15.11 onwards that file is gone, so the import fails and the page breaks.

The Problem

dist/module.esm.min.js has never actually been produced by scripts/build.js. The module.js branch of bundleFile() only emits module.esm.js and module.cjs.js; only the cdn.js branch produces a .min.js variant:

'module.js': () => {
    build({
        entryPoints: [`packages/${package}/builds/${file}`],
        outfile: `packages/${package}/dist/${file.replace('.js', '.esm.js')}`,
        ...
    })

    build({
        entryPoints: [`packages/${package}/builds/${file}`],
        outfile: `packages/${package}/dist/${file.replace('.js', '.cjs.js')}`,
        ...
    })
},

The file that shipped in previous releases was a stale artifact from a maintainer's local dist/ folder, generated by an older build and swept into each npm publish because dist/ is not cleaned before builds. The 3.14.9 and 3.15.10 tarballs on npm both contain byte-for-byte identical module.esm.min.js files with version:"3.13.10" baked in, meaning anyone importing that path for the last several releases has been running 3.13.10 code regardless of the installed version.

3.15.11 was the first release cut by the new GitHub Actions workflow, which runs from a clean checkout, so the stale file no longer rides along.

The Solution

Add a legitimate minified ESM output to the module.js branch in scripts/build.js, mirroring the pattern already used by cdn.js / cdn.min.js:

build({
    entryPoints: [`packages/${package}/builds/${file}`],
    outfile: `packages/${package}/dist/${file.replace('.js', '.esm.min.js')}`,
    bundle: true,
    minify: true,
    platform: 'neutral',
    mainFields: ['module', 'main'],
}).then(() => {
    outputSize(package, `packages/${package}/dist/${file.replace('.js', '.esm.min.js')}`)
})

This restores the file path users were already relying on and makes the no-bundler ESM use case a first-class build target. Because the file is now generated from the current source on every release, it will contain the correct ALPINE_VERSION rather than being frozen at 3.13.10.

The change applies uniformly to every module-emitting package (alpinejs plus the plugins), keeping the three module outputs consistent: module.esm.js, module.esm.min.js, module.cjs.js.

Fixes #4818

Emit `module.esm.min.js` alongside the existing `module.esm.js` and
`module.cjs.js` so browsers loading modules directly from
`node_modules` (via `<script type="module">`) have a minified
option without needing a bundler.

This restores a path that users had been importing from in previous
releases. The file was present in earlier tarballs only as a stale
artifact from a maintainer's local `dist/` folder, and disappeared
in 3.15.11 when the release workflow moved to a clean checkout.

Fixes #4818
@calebporzio calebporzio merged commit a8d8f4a into main Apr 30, 2026
2 checks passed
@calebporzio
Copy link
Copy Markdown
Collaborator

Thanks!

@calebporzio calebporzio deleted the josh/add-module-esm-min-build branch April 30, 2026 20:32
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.

Missing dist/module.esm.min.js in 3.15.11

2 participants