Skip to content

Ship a luxon-bundled build alongside the external one - #23

Merged
sethherr merged 3 commits into
mainfrom
sethherr/bundle-luxon-into-package
Jul 25, 2026
Merged

Ship a luxon-bundled build alongside the external one#23
sethherr merged 3 commits into
mainfrom
sethherr/bundle-luxon-into-package

Conversation

@sethherr

@sethherr sethherr commented Jul 25, 2026

Copy link
Copy Markdown
Member

@bikeindex/time-localizer shipped a single build with luxon left external. That's right for consumers with a bundler, but bike_index uses importmap-rails with no bundler, where the bare import{DateTime}from"luxon" specifier means a second CDN pin and two chained cross-origin round trips (3.3 KB, then 254 KB of unminified luxon) gating every Stimulus controller on every page, since both are static imports.

Adds a second artifact rather than changing the existing one:

  • dist/index.js — unchanged. Luxon stays external and a peerDependency, so consumers that use luxon directly keep a single deduped copy.
  • dist/index.bundle.js — new. Luxon inlined, 72.4 KB minified / 23 KB gzipped: one request, nothing to resolve. Available as @bikeindex/time-localizer/bundle or by file path over a CDN.
  • README — documents which build to use, replacing a stale line that claimed luxon was already bundled.

The default build stays external because two copies of luxon means two module-scoped Settings objects. With Settings.defaultLocale = 'fr', a consumer's own luxon renders 2 nov. while a bundled copy renders Nov 2; Settings.now — how you freeze time in tests — stops applying the same way. Neither case errors, so the standalone build is opt-in and the README warns against pairing it with your own luxon.

Both artifacts build from one source file via prepublishOnly, and index.js is untouched, so the public API is unchanged. Version goes to 0.4.0; publishing is still the separate manual npm publish step.

sethherr and others added 2 commits July 25, 2026 08:45
The published package left luxon as an external import, so dist/index.js
shipped a bare `import{DateTime}from"luxon"` specifier for the consumer to
resolve. This contradicted the README, which already claimed luxon was
bundled.

bike_index uses importmap-rails with no bundler, so that bare specifier
meant a second CDN pin and two chained cross-origin round trips (3.3 KB,
then 254 KB of unminified luxon) gating every Stimulus controller on every
page, since both are static imports.

- Drop --external:luxon from the esbuild build; dist/index.js is now
  self-contained at 72.4 KB minified.
- Delete peerDependencies — luxon stays in devDependencies, which is all
  esbuild needs at build time.
- Bump to 0.4.0.

main, exports and files still point at dist/index.js, and index.js is
unchanged, so the public API and pinned artifact path are stable.

Co-Authored-By: Claude <noreply@anthropic.com>
Bundling luxon unconditionally would have regressed consumers that use
luxon directly: two copies means two module-scoped Settings objects, so
their Settings.defaultLocale / defaultZone / now would silently stop
applying to time-localizer's output. Verified with luxon 3.7.2 —
Settings.defaultLocale = 'fr' rendered "2 nov." from the consumer's copy
but "Nov 2" from the bundled one, with no error.

Ship both builds of the same source instead:

- dist/index.js keeps luxon external (peerDependency restored), so
  bundler consumers keep one deduped copy and their Settings apply.
- dist/index.bundle.js inlines luxon for consumers with no bundler,
  reachable as @bikeindex/time-localizer/bundle or by file path.
- README documents which build to use and warns against pairing the
  bundled one with your own luxon.

Both are outputs of one source file, rebuilt together by prepublishOnly.

Co-Authored-By: Claude <noreply@anthropic.com>
@sethherr sethherr changed the title Bundle luxon into time-localizer and release 0.4.0 Ship a standalone luxon-bundled build alongside the external one Jul 25, 2026
The lockfile was regenerated when peerDependencies was briefly removed and
not refreshed when it came back, so it no longer matched package.json.

Co-Authored-By: Claude <noreply@anthropic.com>
@sethherr sethherr changed the title Ship a standalone luxon-bundled build alongside the external one Ship a luxon-bundled build alongside the external one Jul 25, 2026
@sethherr
sethherr merged commit 7c81df5 into main Jul 25, 2026
4 checks passed
@sethherr
sethherr deleted the sethherr/bundle-luxon-into-package branch July 25, 2026 16:37
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.

1 participant