Data Loader supports both SSR and CSR scenarios!
In SSR scenarios, useEffect
does not execute. This behavior means that under normal circumstances, it's impossible to fetch data before rendering a component.
To support this functionality, mainstream frameworks typically pre-fetch data using the data loader
provided by React Router and inject it into the route component. The route component then retrieves the data using useLoaderData for rendering.
This approach heavily relies on routing functionality and cannot be used directly with Module Federation.
To solve this problem, Module Federation provides component-level data fetching capabilities, allowing developers to fetch data and render components in SSR scenarios.
The use of can be broadly divided into two parts: components (functions) and applications. The difference between them is whether they include routing functionality.
Different actions are required depending on the role.
Each exposed module can have a corresponding .data
file with the same name. These files can export a loader function, which we call a Data Loader. It executes before the corresponding expose
component renders, providing data to the component. Here is an example:
Here, List.data.ts
needs to export a function named fetchData
, which will be executed before the List
component renders and injects its data. Here is an example:
The data from the loader function is injected into the producer's props with the key mfData
. Therefore, the producer needs to modify the code to consume this data, as shown below:
If you use Modern.js to develop a producer, and that producer's page is also accessed directly, you can use the Data Loader provided by Modern.js to inject data.
Its usage is almost identical to Module Federation's, except for the function name. This makes it easy to consume the Data Loader in the producer. Here's an example:
page.data.ts
file in the producer's page directory and export a function named loader
:page
:In SSR scenarios, this can only be used with Modern.js.
In the consumer, we need to use the createLazyComponent API to load the remote component and fetch its data.
By default, parameters are passed to the loader function. The type is dataFetchParams, which includes the following field:
isDowngrade
(boolean): Indicates whether the current execution context is in a fallback mode. For example, if Server-Side Rendering (SSR) fails, a new request is sent from the client-side (CSR) to the server to call the loader function. In this case, the value is true
.In addition to the default parameters, you can also pass the dataFetchParams
field in createLazyComponent
, which will be passed through to the loader function.
The return value of the loader function can only be a serializable data object.
The loader function can be executed on the server or in the browser. A loader function executed on the server is called a Server Loader, and one executed in the browser is called a Client Loader.
In CSR applications, the loader function is executed in the browser, so they are all Client Loaders by default.
In SSR applications, the loader function is only executed on the server, so they are all Server Loaders by default. In SSR, Module Federation directly calls the corresponding loader function on the server. When switching routes in the browser, Module Federation sends an HTTP request to the SSR service, which also triggers the loader function on the server.
Executing the loader function only on the server in SSR applications offers the following benefits:
By default, in SSR applications, the loader function is only executed on the server. However, in some scenarios, developers may want requests from the browser to go directly to the data source without passing through the SSR service. For example:
Module Federation supports adding an additional .data.client
file in SSR applications, which also exports a named loader. In this case, if the Data Loader on the server fails and falls back, or when switching routes in the browser, the application will execute this loader function in the browser like a CSR application, instead of sending another data request to the SSR service.
To use a Client Loader, there must be a corresponding Server Loader, and the Server Loader must be defined in a .data
file, not a .loader
file.
For application-level modules, we prefer to use RSC (React Server Components) to make the functionality more complete. This feature is currently under exploration, so please stay tuned.
No, it is not supported.
Currently, only the Rslib and Modern.js plugins can create a Data Loader.