Skip to content

2.9.24: inlined loglevel UMD takes its AMD branch — .default.getLogger is not a function (regression from 2.9.23) #1428

Description

@alireza-yadegari

Summary

@livekit/components-react@2.9.24 inlines loglevel's UMD source into dist/room-Bfb4OWAI.mjs and reads it back through .default. The inlined wrapper keeps its AMD branch, so in any environment where a global define.amd exists, module.exports is never assigned and the package throws at module evaluation:

TypeError: <ns>.default.getLogger is not a function

2.9.23 is unaffected. Pinning to 2.9.23 is the only workaround we found.

The difference between 2.9.23 and 2.9.24

2.9.23dist/contexts-BtSGUJjc.mjs:2647, direct call on the module:

], I = zr.getLogger("lk-components-js");

2.9.24dist/room-Bfb4OWAI.mjs:2578, via .default:

], R = Ms.default.getLogger("lk-components-js");

where (same file, line 2405):

var Ms = /* @__PURE__ */ di(So(), 1);

So is an esbuild __commonJS factory wrapping loglevel's UMD source, inlined verbatim (same file, ~line 900):

So = /* @__PURE__ */ Qn(((e, t) => {
  (function(n, r) {
    "use strict";
    typeof define == "function" && define.amd ? define(r) : typeof t == "object" && t.exports ? t.exports = r() : n.log = r();
  })(e, function() { /* … loglevel … */ });
}));

Why that breaks

If a global define with .amd is present, the first branch wins: define(r) is called and t.exports is never assigned. So() therefore returns an empty exports object, __toESM({}, 1).default is {}, and .getLogger is undefined.

This is specifically a consequence of inlining the UMD build. A normal import loglevel from "loglevel" — which @livekit/components-core@0.12.15 still does, and which works — leaves the resolution to the host, where loglevel's self-reference (log.default === log) makes .default correct.

Where a global define.amd comes from

Two independent cases hit us:

  1. Build time — bundlers that parse AMD syntax. Our Next.js output: 'export' prerender fails at module evaluation for every page that transitively imports LiveKit. Reproduces identically under both Turbopack and webpack (next build --webpack), so it is not a Turbopack-specific interop quirk.
  2. Runtime — an AMD loader on the page. We load part of our app as AMD micro-frontends, so window.define.amd is defined globally; the LiveKit bundle then throws in the browser on load.

Note for reproduction

Importing the package directly in Node works, because there is no global define:

node --input-type=module -e "import('@livekit/components-react').then(()=>console.log('OK'))"
# → OK

So this can't be reproduced with a plain Node import — it needs a build, or a page with an AMD loader present.

What does not help

For anyone else hitting this, we measured all of these and none of them work:

  • transpilePackages: ['@livekit/components-core', '@livekit/components-react']
  • serverExternalPackages: [...] — the external then fails to load with the same error
  • next build --webpack instead of Turbopack

Only pinning to 2.9.23 fixes it.

Environment

  • @livekit/components-react 2.9.24 (broken) / 2.9.23 (works)
  • @livekit/components-core 0.12.15
  • livekit-client 2.22.1
  • loglevel 1.9.1 (as pinned by components-core)
  • Next.js 16.3.3, output: 'export'; also webpack 5.110 for the AMD micro-frontend bundle
  • Node 24

Suggested fix

Don't inline loglevel's UMD build — either keep loglevel external (as components-core does), or inline its CJS/ESM entry rather than the UMD one so there is no define.amd branch to take.

Happy to test a canary against both of our builds if that helps.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

Labels

No labels
No labels

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions