Hi team, we’ve run into a reproducible issue with @segment/analytics-next when it’s consumed inside a multi-layer package setup.
Summary
When @segment/analytics-next is included inside a library that is then re-bundled downstream (e.g. Vite → Vite → Vite), the dynamic import of ../plugins/ajs-destination does not retain a stable module shape. The code assumes:
const mod = await import('../plugins/ajs-destination')
mod.ajsDestinations(/* … */)
But after bundling, this often becomes:
import("./index-xxxx.mjs").then(mod => mod.ajsDestinations)
…and mod ends up being:
Module { [Symbol.toStringTag]: "Module" }
with no ajsDestinations property, leading to:
TypeError: mod.ajsDestinations is not a function
This causes a hard crash or blank screen unless we patch the package to tolerate different module shapes.
This leads to a crash or a blank screen. Our temporary workaround does not fully resolve the issue — it only prevents the hard failure and allows the app to degrade gracefully without going blank.
What we’ve observed
The original ajs-destination module does export ajsDestinations.
However, when analytics-next is bundled more than once, Vite / ESBuild / Rollup reshape the module, and the dynamic import may return any of the following:
mod.ajsDestinations
mod.default.ajsDestinations
mod.default (function)
mod itself (function)
A Module {} namespace wrapper with no callable export
The SDK only checks for mod.ajsDestinations, so any other shape causes initialization to fa
const ajs =
mod.ajsDestinations ??
mod.default?.ajsDestinations ??
(typeof mod.default === 'function' ? mod.default : null) ??
(typeof mod === 'function' ? mod : null)
This restores functionality and avoids blank pages, but obviously isn’t ideal.
Request
Would it be possible for the SDK to:
-
Make the dynamic import resolution more robust (supporting default and function exports), or
-
Move the legacy-destination loader to a statically imported module (avoiding dynamic import shape drift), or
-
Provide a documented API/flag to disable legacy destination loading entirely when bundling?
This would make the SDK more resilient in real-world bundler pipelines (especially monorepos, Vite library mode, and multi-layer package architectures).
Happy to provide repro steps or a minimal Vite project that demonstrates the issue.
Thanks!
Hi team, we’ve run into a reproducible issue with @segment/analytics-next when it’s consumed inside a multi-layer package setup.
Summary
When @segment/analytics-next is included inside a library that is then re-bundled downstream (e.g. Vite → Vite → Vite), the dynamic import of ../plugins/ajs-destination does not retain a stable module shape. The code assumes:
But after bundling, this often becomes:
import("./index-xxxx.mjs").then(mod => mod.ajsDestinations)…and mod ends up being:
Module { [Symbol.toStringTag]: "Module" }with no ajsDestinations property, leading to:
TypeError: mod.ajsDestinations is not a functionThis causes a hard crash or blank screen unless we patch the package to tolerate different module shapes.
This leads to a crash or a blank screen. Our temporary workaround does not fully resolve the issue — it only prevents the hard failure and allows the app to degrade gracefully without going blank.
What we’ve observed
The original ajs-destination module does export ajsDestinations.
However, when analytics-next is bundled more than once, Vite / ESBuild / Rollup reshape the module, and the dynamic import may return any of the following:
mod.ajsDestinations
mod.default.ajsDestinations
mod.default (function)
mod itself (function)
A Module {} namespace wrapper with no callable export
The SDK only checks for mod.ajsDestinations, so any other shape causes initialization to fa
This restores functionality and avoids blank pages, but obviously isn’t ideal.
Request
Would it be possible for the SDK to:
Make the dynamic import resolution more robust (supporting default and function exports), or
Move the legacy-destination loader to a statically imported module (avoiding dynamic import shape drift), or
Provide a documented API/flag to disable legacy destination loading entirely when bundling?
This would make the SDK more resilient in real-world bundler pipelines (especially monorepos, Vite library mode, and multi-layer package architectures).
Happy to provide repro steps or a minimal Vite project that demonstrates the issue.
Thanks!