relay icon indicating copy to clipboard operation
relay copied to clipboard

Distribute react-relay and other packages as ESM

Open gajus opened this issue 1 year ago • 2 comments
trafficstars

Feels like this change is well overdue.

gajus avatar Dec 11 '23 19:12 gajus

I agree. This would be a welcome improvement. When setting up Relay for side projects I often hit rough edges because of this.

If you, or anyone else, wants to start collecting a full picture of what work would be required here, that would be very helpful. Some questions on my mind:

  • Is it a prerequisite to move to ESM within Relay? Currently we use commonJS require/module.exports everywhere. Internally, we've long wanted to move to ES6 imports/exports but simply haven't had the bandwidth to prioritize it.
  • What changes would we need to make to our build pipeline? Is it possible with the tools we have today?
  • Can we support both commonJS and ESM? Will this be a breaking/problematic change for some users?

captbaritone avatar Jan 10 '24 18:01 captbaritone

Highly theoretically, you could just release relay-esm package that simply re-exports everything as ESM:

// Because Relay is a CommonJS module, we are having problems with Vite bundling it.
// Until Relay becomes an ESM module, we need to use this package to re-export it.
import { default as reactRelay } from 'react-relay';
import { default as relayRuntime } from 'relay-runtime';

export { type PreloadedQuery, type UseMutationConfig } from 'react-relay';
export {
  type CacheConfig,
  type Disposable,
  type FetchPolicy,
  type FragmentRefs,
  type GraphQLResponse,
  type GraphQLTaggedNode,
  type MutationParameters,
  type OperationType,
  type PayloadError,
  type RequestParameters,
  type SelectorStoreUpdater,
  type Variables,
  type VariablesOf,
} from 'relay-runtime';

export const ConnectionHandler = relayRuntime.ConnectionHandler;
export const Environment = relayRuntime.Environment;
export const Network = relayRuntime.Network;
export const QueryResponseCache = relayRuntime.QueryResponseCache;
export const RecordSource = relayRuntime.RecordSource;
export const Store = relayRuntime.Store;

export const loadQuery = reactRelay.loadQuery;
export const fetchQuery = reactRelay.fetchQuery;
export const useLazyLoadQuery = reactRelay.useLazyLoadQuery;
export const usePreloadedQuery = reactRelay.usePreloadedQuery;
export const graphql = reactRelay.graphql;
export const useFragment = reactRelay.useFragment;
export const useMutation = reactRelay.useMutation;
export const usePaginationFragment = reactRelay.usePaginationFragment;
export const useRelayEnvironment = reactRelay.useRelayEnvironment;
export const readInlineData = reactRelay.readInlineData;
export const useRefetchableFragment = reactRelay.useRefetchableFragment;
export const RelayEnvironmentProvider = reactRelay.RelayEnvironmentProvider;
export const commitMutation = reactRelay.commitMutation;

That's what we do internally in Contra.

gajus avatar Jan 19 '24 21:01 gajus