-
Notifications
You must be signed in to change notification settings - Fork 126
field-editor-shared ESM build contains a bare require(), breaking Vite production builds #2173
Description
Summary
@contentful/field-editor-shared@3.1.4 ships an ESM file (dist/esm/queryClient.js) containing a bare CommonJS require() for runtime react-query v4/v5 detection. This is invalid in ESM and throws Uncaught ReferenceError: require is not defined in the browser when SharedQueryClientProvider / createDefaultQueryClient first runs — which, via @contentful/default-field-editors, happens during the first CMA fetch and crashes any custom app built with vite build.
vite dev masks the bug because esbuild's dep prebundler silently wraps require. vite build (Rollup) leaves the bare identifier in the production bundle.
Offending code
@contentful/field-editor-shared/dist/esm/queryClient.js:
import * as React from 'react'; import { QueryClient, QueryClientProvider, useQuery as useRQv4, useQueryClient as useHostQueryClientV4 } from '@tanstack/react-query'; const rqVersion = require('@tanstack/react-query').version; // ← invalid in ESM const RQ_MAJOR = parseInt(rqVersion ?? '4', 10); const IS_V5 = RQ_MAJOR >= 5;
Versions
@contentful/field-editor-shared: 3.1.4@contentful/default-field-editors: 2.2.19@tanstack/react-query(nested): 4.44.0- Vite 6.4.2 / Rollup, Node 22
Reproduction
- Vite + React app.
npm i @contentful/default-field-editors @contentful/react-apps-toolkit @tanstack/react-query.- Render any
FieldWrapper. npm run build && npm run preview→ browser console showsUncaught ReferenceError: require is not defined, source-mapped to therequire('@tanstack/react-query').versionline.
Suggested fix
Replace the require() version sniff with a feature check — it works in any module system and doesn't depend on package.json resolution:
import * as RQ from '@tanstack/react-query'; // `useSuspenseQuery` was introduced in @tanstack/react-query v5. const IS_V5 = typeof (RQ as { useSuspenseQuery?: unknown }).useSuspenseQuery === 'function';
A published ESM file shouldn't contain a bare require().
Workaround for consumers (until a fix is released)
A small Vite pre plugin that statically rewrites the expression:
const patchFieldEditorSharedRequire = (): Plugin => ({ name: 'patch-field-editor-shared-require', enforce: 'pre', transform(code, id) { if (!id.includes('@contentful/field-editor-shared')) return null; const needle = `require('@tanstack/react-query').version`; if (!code.includes(needle)) return null; return { code: code.split(needle).join('"4"'), map: null }; }, });