Dynamic import produces duplicate class instance in production

3 days ago 4
ARTICLE AD BOX

Don't use import(import.meta.url) as a singleton mechanism. In Vite dev this may appear to work because modules are served close to native ESM semantics, but production builds are builds are bundled and chunked. The module URL you see in source is not a stable identity boundary after build.

Move the singleton/state to a separate module and import that module from both places. If you need lazy loading, keep a cached promise using a static import specifier. If your app can load multiple bundles that each contain X, then module-singleton semanticas are not enough; use an explicit shared registry, dependency injection, or externalize X so there is only one physical copy.

Example:

// x-loader.ts let xPromise: Promise<typeof import('./x')> | undefined export function loadX() { return (xPromise ??= import('./x')) }

and if what you actually need is shared state:

// x-singleton.ts export const xSingleton = createX() // anywhere import { xSingleton } from './x-singleton'

Make module identity boring. Do not make correctness depend on how Vite decides to chunk production output.

Ezequias Dinella's user avatar

2 Comments

Thanks a lot for your great explanation. I wonder how the following observation fits in: If instead of calling import() I compare the incoming url with import.meta.url it seams to be working just fine. Can I rely on that?

2026-05-15T04:56:38.107Z+00:00

Because what I‘m actually trying to achieve is to load X solely by a url. I‘m looking for a way of “stringifying” a reference to X, and to parse is back to restore the instance of X. But everything happens inside the same module instance. The json is going out and coming back in. I don’t see how any of your examples would help me with that.

2026-05-15T05:01:36.77Z+00:00

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.

Read Entire Article