Skip to content

feat(ra-data-simple-prisma): add /server subpath export to keep react-admin out of server bundles#113

Open
dan2811 wants to merge 1 commit into
codeledge:mainfrom
dan2811:ra-data-simple-prisma/server-subpath-export
Open

feat(ra-data-simple-prisma): add /server subpath export to keep react-admin out of server bundles#113
dan2811 wants to merge 1 commit into
codeledge:mainfrom
dan2811:ra-data-simple-prisma/server-subpath-export

Conversation

@dan2811
Copy link
Copy Markdown
Contributor

@dan2811 dan2811 commented May 21, 2026

Hi, I was having an issue with a project that uses this package and I've had to resolve temporarily, using resolutions in my package.json. Have used claude to raise this PR which fixes my issue. Would be great if you could consider merging.

Disclaimer: I haven't looked in-depth at this code and I'm not familiar with this repo, so please review carefully! Hopefully it's not just AI slop!

Summary

ra-data-simple-prisma exposes both a client-side dataProvider (used
by react-admin in the browser) and server-side request handlers (used
inside Next.js API routes to talk to Prisma directly) from a single
bundle. That bundle has a top-level import { HttpError } from 'react-admin'
which is only used by the client dataProvider, but because it sits at
the top of dist/index.js / dist/index.mjs, any server-side import
of a handler transitively pulls in react-admin, ra-core,
ra-ui-materialui, and react-router-dom
at runtime.

On Vercel / Next.js this causes two real problems:

  1. The serverless function bundle is bloated with UI-only packages it
    never executes.
  2. ESM resolution can break the deployment. With react-router-dom@7.x
    the package's exports field causes Next.js NFT (file tracer) to
    include dist/index.js (CJS) while Node ESM resolution at runtime
    picks dist/index.mjs — the missing .mjs is then never traced and
    the function crashes with MODULE_NOT_FOUND in production.

Fix

Split into two entry points via subpath exports:

Entry Contents Pulls in react-admin?
ra-data-simple-prisma dataProvider + handlers (back-compat) yes (unchanged)
ra-data-simple-prisma/server handlers + helpers only no

Server-side consumers can switch to:

import { defaultHandler } from "ra-data-simple-prisma/server";

and react-admin (plus its transitive UI deps) disappears from the
function's traced files entirely.

Changes

  • New src/server.ts entry that re-exports only the server APIs.
  • Http.ts, audit/types.ts, audit/auditHandler.ts now use
    import type for their react-admin imports — these were already
    type-only usages, but the explicit type keyword guarantees esbuild
    erases them at build time so the server bundle has no require('react-admin').
  • package.json:
    • exports map for . (back-compat) and ./server with .d.ts,
      ESM, and CJS targets for each.
    • tsup now builds both entries.
    • react-admin moved to peerDependenciesMeta.optional = true so
      server-only consumers don't get install warnings.
    • New build:check script that asserts the server bundle has no
      react-admin reference.
  • tests/serverBundle.test.ts — Jest guard that fails CI if dist/server.{js,mjs}
    ever start referencing react-admin again.
  • README documents the new /server subpath.
  • Changeset (minor bump).

Non-breaking

The top-level entry is unchanged: it still re-exports both the
dataProvider and the handlers, so existing imports continue to work
without modification.

Test plan

  • pnpm build produces dist/index.{js,mjs,d.ts} and dist/server.{js,mjs,d.ts}
  • grep react-admin dist/server.* returns nothing
  • pnpm test passes (164/164, including the new serverBundle.test.ts)
  • pnpm build:check passes
  • Manual: import from "ra-data-simple-prisma/server" in a Next.js
    App Router function on Vercel, confirm the function bundle no
    longer traces react-admin / react-router-dom

The package previously exposed both the client-side `dataProvider` and
the server-side request handlers from a single bundle. The bundle
includes `import { HttpError } from 'react-admin'` at the top, so any
Next.js serverless function importing `defaultHandler` (or any other
handler) transitively pulls in `react-admin`, `ra-core`,
`ra-ui-materialui`, and `react-router-dom`. None of this is needed at
runtime on the server, but it inflates the Lambda bundle and triggers
ESM resolution failures on Vercel when NFT traces `dist/index.js` while
Node ESM resolves to `dist/index.mjs`.

Split the package into two entry points via subpath exports:

- `ra-data-simple-prisma`         -> client-side `dataProvider`
- `ra-data-simple-prisma/server`  -> server-side handlers only,
                                     no `react-admin` import

The top-level entry continues to re-export everything for backwards
compatibility. `react-admin` is now an optional peer dependency so
server-only consumers do not get install warnings.
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.

1 participant