Skip to content

fix: bundle openapi-fetch into sdk-analytics dist to avoid broken .cjs resolution - #1399

Open
ZayanKhan-12 wants to merge 2 commits into
MetaMask:mainfrom
ZayanKhan-12:fix/1340-sdk-analytics-openapi-fetch-interop
Open

fix: bundle openapi-fetch into sdk-analytics dist to avoid broken .cjs resolution#1399
ZayanKhan-12 wants to merge 2 commits into
MetaMask:mainfrom
ZayanKhan-12:fix/1340-sdk-analytics-openapi-fetch-interop

Conversation

@ZayanKhan-12

@ZayanKhan-12 ZayanKhan-12 commented Aug 4, 2026

Copy link
Copy Markdown

Description

Fixes #1340

Root cause

@metamask/sdk-analytics ships a CJS bundle (dist/index.js) that contains a runtime require("openapi-fetch"). openapi-fetch's require export condition resolves to dist/cjs/index.cjs — a .cjs file. Webpack configs that have no module rule for .cjs (notably create-react-app / react-scripts 5, whose final asset/resource fallback only excludes js|mjs|jsx|ts|tsx) emit that file as a static asset URL instead of parsing it as JavaScript:

// module for "openapi-fetch" inside a CRA production bundle:
518(e,t,r){"use strict";e.exports=r.p+"static/media/index.e68f0740787a395b4ef6.cjs"}

So import_openapi_fetch.default is a URL string, and the module-level new Analytics(...) singleton throws import_openapi_fetch.default is not a function the moment the package is loaded. This matches the reports here and in Web3Auth/web3auth-web#2224 (same error via @web3auth/modal@metamask/sdk@metamask/sdk-analytics), and explains why Vite-based apps are unaffected (Vite handles .cjs).

Note this is not an openapi-fetch version regression — 0.13.5 and 0.13.8 ship byte-equivalent packaging (verified by diffing the npm tarballs), and an import-style/interop tweak in our source cannot help, because in the failing toolchain the resolved module contains no function at all.

Fix

Bundle openapi-fetch into the dist output via tsup noExternal (config moved to a tsup.config.ts, following the existing sdk-multichain precedent), so consumer bundlers never resolve the problematic .cjs file. openapi-fetch is tiny (~6 kB min, no runtime deps) and the emitted d.ts was already self-contained, so openapi-fetch moves from dependencies to devDependencies. yarn.lock is unchanged.

Testing

Reproduction (before fix), minimal CRA app whose entry does import { analytics } from '@metamask/sdk-analytics', with published @metamask/sdk-analytics@0.0.5 + openapi-fetch@0.13.8 (the reporter's versions):

npx react-scripts build   # react-scripts 5.0.1
node build/static/js/main.*.js
# TypeError: (0 , f.default) is not a function
#     at new <anonymous> (...)   <- Analytics constructor, exactly the reported error

After replacing the installed package with this branch's build and rebuilding the same CRA app:

node build/static/js/main.*.js
# analytics loaded: object

Also verified plain webpack 5 (default config) bundles both before and after without error, so this changes nothing for toolchains that already worked.

Commands run in the monorepo:

  • yarn workspace @metamask/sdk-analytics build — succeeds; grep openapi_fetch dist/index.js has no matches (dependency fully inlined, dist 4 kB → 17 kB)
  • node -e "require('.../dist/index.js')" and ESM import of dist/index.mjs — both load; analytics.track is a function
  • yarn workspace @metamask/sdk-analytics test:ci — 2 files, 6 tests passed
  • yarn workspace @metamask/sdk-communication-layer build — succeeds (downstream consumer)
  • Not run: full monorepo test suite / e2e.

🤖 Generated with Claude Code


Note

Low Risk
Packaging-only change for a deprecated analytics package; increases dist size but avoids changing runtime API or security-sensitive logic.

Overview
Fixes runtime failures in create-react-app and similar Webpack setups where @metamask/sdk-analytics loaded openapi-fetch as an external require, which resolved to a .cjs file that Webpack treated as a static asset—so createClient was a URL string and analytics threw "default is not a function" on import.

openapi-fetch is now inlined into the published ESM/CJS dist via a new tsup.config.ts with noExternal: ['openapi-fetch'], and the build script delegates to tsup instead of inline CLI flags. The dependency moves from dependencies to devDependencies since consumers no longer resolve it at install time.

Reviewed by Cursor Bugbot for commit b4fbdbb. Bugbot is set up for automated code reviews on this repo. Configure here.

ZayanKhan-12 and others added 2 commits August 3, 2026 20:34
…s resolution

The published @metamask/sdk-analytics CJS bundle contains
`require("openapi-fetch")`. openapi-fetch's `require` export condition
resolves to `dist/cjs/index.cjs`, and webpack configs without a rule for
`.cjs` files (notably create-react-app / react-scripts 5, where the
final `asset/resource` fallback only excludes js/mjs/jsx/ts/tsx) emit
that file as a static asset URL instead of parsing it as JavaScript. At
runtime `import_openapi_fetch.default` is then a string, and
instantiating the module-level Analytics singleton throws
"import_openapi_fetch.default is not a function".

Bundle openapi-fetch into the dist output via tsup's `noExternal` so
consumer bundlers never resolve the problematic `.cjs` file, and move
the dependency to devDependencies since it is no longer required at
runtime. The emitted d.ts is already self-contained.

Fixes MetaMask#1340

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
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.

[Bug]: Installing @metamask/sdk-analytics causing import_openapi_fetch.default is not a function

1 participant