Remix ESM module workaround

Important note : not useful anymore for React Flow

React flow can now be imported normally into remix, see xyflow/xyflow#1953 (comment)

The fix can be still useful for other packages


A screenshot showing an exemple from the react flow library working with remix

Run it with npm run dev

Files added

Usage

Component using useModuleLoader

const OverviewFlow = () => {

    const {
        default: ReactFlow,
        addEdge,
        MiniMap,
        Controls,
        Background,
        useNodesState,
        useEdgesState,
        MarkerType,
      } = useModuleLoader("react-flow-renderer") as any;
    
    // ...
}

From app/components/flow.tsx

Wrapping

A component using useModuleLoader should be wrapped in a ModuleLoader
The string used as index will be used as the argument for useModuleLoader

<ModuleLoader imports={{ "react-flow-renderer": getReactFlowRenderer }}>
    <Flow />
</ModuleLoader>

From app/routes/index.tsx

Dynamics imports

module.exports = {
    getReactFlowRenderer: async () => await import("react-flow-renderer"),
};

From esm-module.ts

Additionnal information

Types

I did not manage to make the types work so typescript and your IDE will have no informations on the import.

However, you can import types using a regular static import statement without crash, if :

  • you are not importing the same type with useModuleLoader
  • you are using the imported type only for type checking with typescript

Example in app/components/flow.tsx

import type { ReactFlowInstance, OnConnect, Edge, Node } from "react-flow-renderer";

// ...

const onConnect: OnConnect = (params) =>
    setEdges((eds: Edge[]) => addEdge(params, eds));