Repository navigation
Conversation
Exposes the prebuilt bundles without the session recorder as proper package subpaths with ESM, CJS and TypeScript entrypoints, so apps that don't need a bundled recorder can drop ~72% of the SDK's gzipped size without deep imports into src/ or dist/. - build ESM versions of the core and async-modules bundles - add core/ and async-modules/ directory entrypoints (no exports map, so all existing deep imports keep working) - fall back to the unhashed CDN bundles when the SDK is bundled straight from src/, where the async module filename placeholders are never replaced - add npm run bundle-size to measure each entrypoint Refs mixpanel#482
|
Hey @Mohith26 thanks for the contribution! Can your problem be effectively solved by importing from We should definitely update our README to indicate this, we could also add export entries for shorter names as a simpler convenient approach |
|
Thanks for taking a look. I tried it, and yes, importing from
So the extra ESM builds and the
One thing to flag on 2, given what happened in 2.69.0: once |
Refs #482.
The SDK already builds bundles without the session recorder (
dist/mixpanel-core.cjs.js,dist/mixpanel-with-async-modules.cjs.js), but the only documented way to use them is a deep import intosrc/loaders/.... That path is raw source that every app re-bundles, it is awkward for newer bundlers (see the Turbopack comments in #482), and the async variant currently has a bug (below). This PR makes the slim bundles first-class:Changes
dist/mixpanel-core.module.js,dist/mixpanel-with-async-modules.module.js);copyTypes()writes their.d.tsfiles.core/andasync-modules/directories with a smallpackage.json(main,module,types) pointing at those bundles, and add them tofiles. I deliberately did not add anexportsmap, since that broke existing deep imports in 2.69.0; everything that resolves today (src/...,dist/...) still resolves.src/(the README'sloader-module-with-async-modulesimport), the__MP_RECORDER_FILENAME__/__MP_TARGETING_FILENAME__placeholders are never replaced, so session replay requestshttps://cdn.mxpnl.com/libs/__MP_RECORDER_FILENAME__(404). It now falls back to the unhashedmixpanel-recorder.min.js/mixpanel-targeting.min.js, which is what those imports did before the hashed bundles landed. Built bundles are unaffected and still get the hashed names.npm run bundle-sizebundles a minimal app (init+track) against each entrypoint with rollup + esbuild minify and prints the sizes.Bundle size (
npm run bundle-sizeafter a full build, Apple Silicon arm64; sizes are deterministic, same output on 3 runs)mixpanel-browsermixpanel-browser/async-modulesmixpanel-browser/coreTesting
npm test(lint + 923 unit tests) passes. Newtests/unit/entrypoints.jschecks that each entrypoint is published, thatmain/module/typespoint at outputs the rollup config actually produces, that the CJS bundle loads, and the src/ filename fallback.FULL=1 rollup -c), thennpm packand installed the tarball into a scratch project:require('mixpanel-browser/core')and/async-moduleswork in Node, esbuild picks the new.module.jsfiles, andtsc --strictresolves real types for both subpaths withmoduleResolutionnode10,node16andbundler.dist/byte-for-byte, so the build setup matches. I did not commitdist/since it is generated at release time; the new.module.jsfiles will appear on the nextnpm run build-dist.This doesn't shrink the default import, so it doesn't fully close #482, but it gives everyone who doesn't bundle session replay a supported way to drop about 93 KiB gzipped.
I used AI assistance for this PR and reviewed and tested the changes myself.