Skip to content

fix(react-native): preserve wrapped Expo static exports - #4799

Merged
marandaneto merged 1 commit into
mainfrom
fix/expo-serial-assets-normalization
Sep 7, 2026
Merged

marandaneto merged 1 commit into
mainfrom
fix/expo-serial-assets-normalization

Conversation

@marandaneto

Copy link
Copy Markdown
Member

Problem

Follow-up to the Expo compatibility issue deferred in #4778.

Wrapping Expo's serializer with createPostHogMetroSerializer() breaks static exports. Those exports can return assets or JSON rather than a single { code, map } bundle. The wrapper tries to read them as JavaScript and throws.

An output-only guard is not enough. The wrapper first injects a placeholder module, which causes Expo's PostHog per-asset hook to skip the real Chunk ID. Returning the output afterward would preserve that placeholder.

The standard getPostHogExpoConfig() setup does not install this wrapper and is not affected by this particular composition bug.

Changes

  • Delegate static exports to the custom serializer before injecting a placeholder or callback. Keep its arguments and output unchanged, and invoke it once.
  • Recognize explicit serializer options, ordinary source URLs, and JSC-safe URLs. Preserve Expo's option precedence.
  • Leave the default Metro serializer and non-static bundle behavior unchanged.
  • Document that Expo Chunk IDs require the per-asset hook configured by getPostHogExpoConfig().
  • Add regression coverage and a posthog-react-native patch changeset.

This is a focused Expo static-export fix. It does not add generic support for arbitrary custom serializers that return assets without identifying a static export.

Validation

  • New regressions reproduced the crash and placeholder interference before the fix.
  • Full React Native suite: 43 files, 714 tests passed.
  • React Native oxlint, formatting, and pnpm turbo --filter=posthog-react-native build passed.
  • Six additional local checks used the real Expo serializer on iOS and Android, covering explicit options, ordinary URLs, and JSC-safe URLs. Exported code and source maps retained matching IDs with no placeholder.
  • Autoreview of 942a0d2b7 against origin/main found no actionable issues.

The real-serializer checks used an isolated fixture with @expo/metro-config@0.20.17 and Metro 0.82.5 because the workspace's Expo/Metro development dependency combination cannot load that serializer. The fixture is not part of this PR. Validation ran on Node 24.18.1. No real app export, Hermes compilation, or EAS Update upload was performed.

Release info Sub-libraries affected

Libraries affected

  • All of them
  • posthog-js (web)
  • posthog-js-lite (web lite)
  • posthog-node
  • posthog-react-native
  • @posthog/react-native-plugin
  • @posthog/react
  • @posthog/ai
  • @posthog/convex
  • @posthog/next
  • @posthog/nextjs-config
  • @posthog/nuxt
  • @posthog/openfeature-node-provider
  • @posthog/openfeature-web-provider
  • @posthog/rollup-plugin
  • @posthog/webpack-plugin
  • @posthog/types
  • @posthog/browser-common

Checklist

  • Tests for new code
  • Accounted for the impact of any changes across different platforms
  • Accounted for backwards compatibility of any changes (no breaking changes!)
  • Took care not to unnecessarily increase the bundle size

If releasing new changes

  • Added the equivalent patch changeset file manually

🤖 Agent context

Autonomy: Human-driven (agent-assisted)

Implemented with the Pi coding agent using GitHub CLI, Vitest, and isolated autoreview. The investigation confirmed that an output-only pass-through could ship a placeholder ID, so this change delegates before injection instead. Local investigation artifacts are excluded from the PR. Human review is required.

@marandaneto marandaneto self-assigned this Sep 5, 2026
@marandaneto
marandaneto marked this pull request as ready for review September 5, 2026 06:53
@marandaneto
marandaneto requested a review from a team as a code owner September 5, 2026 06:53
@greptile-apps

greptile-apps Bot commented Sep 5, 2026

Copy link
Copy Markdown
Contributor

Reviews (1): Last reviewed commit: "fix(react-native): preserve wrapped Expo..." | Re-trigger Greptile

@dustinbyrne dustinbyrne left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The early static-export return preserves Expo serialization and per-asset instrumentation. No conflict found with the downstream exception-stack contracts; sdk-specs does not directly specify Metro serialization.

@marandaneto
marandaneto merged commit 3161e0d into main Sep 7, 2026
67 checks passed
@marandaneto
marandaneto deleted the fix/expo-serial-assets-normalization branch September 7, 2026 19:32
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.

3 participants