Skip to content

[Bug]: SSR doesn't work with module federation #8211

@diegodepaula

Description

@diegodepaula

Version

System:
    OS: Linux 6.6 Ubuntu 20.04.4 LTS (Focal Fossa)
    CPU: (24) x64 AMD Ryzen 9 3900X 12-Core Processor
    Memory: 14.91 GB / 15.58 GB
    Container: Yes
    Shell: 5.0.17 - /bin/bash

Details

Story

We had a remote module and a consumer working with SSR and no issues, but after upgrading react to 19.2.3 and upgrading the @modern-js packages (plugin-bff, plugin-express, runtime, server-runtime) to 2.6.3 - 2.70.2 and @module-federation/modern-js to 0.22.1 the project keeps crashing every single time the ssr is changed to true or mode: 'stream'.

The last working SSR + module federation versions we used was version 2.68.5 for @modern-js plugin-bff, plugin-express, runtime, server-runtime and 0.18.4 for @module-federation/modern-js.

I absolutely have tried everything from the tutorials, documentation, tried to find in the issues similar cases, tried to research on the web, tried to debug but nothing solves and sometimes lead to different errors such as [Module Federation DTS] Error: The attribute remoteEntry of REMOTE_NAME must not be undefined.

At this point I don't think that it's an implementation issue, but if it is, it's possible that this is an indicator that there's something missing in the documentation, or in the worst case, the SSR isn't supported anymore along with module-federation.

We spend the last year developing our system using Modern.js framework due to the support to SSR + module federation because we have dozens of teams working on the many pages we have, and now we there's this question mark if modern.js will still maintain this feature or if it will be deprecated.

I made this repo: https://github.com/diegodepaula/modern-module and a ISSUE_REPORT.md file https://github.com/diegodepaula/modern-module/blob/main/ISSUE_REPORT.md with some information about what we've investigated so far.

It's important to mention that I've also tried implementing the remote load using

import { lazyLoadComponentPlugin } from '@module-federation/modern-js/react';
import { getInstance, loadRemote } from '@module-federation/modern-js/runtime';
const instance = getInstance();
instance?.registerPlugins([lazyLoadComponentPlugin()]);
const RemoteWelcome = instance?.createLazyComponent({
  loader: () => loadRemote('remote/Welcome'),
  loading: <div>Loading...</div>,
  fallback: () => <div>Failed to load remote component</div>,
});

as well, even though there's no information about it in the docs but it also doesn't work as well. At this point I don't really know what else to try.

More information of our findings below:

Errors

Module Federation config not loading - "mfConfig.name can not be empty" error
[Module Federation DTS] Error: The attribute remoteEntry of REMOTE_NAME must not be undefined


Bug Description

When using the @module-federation/modern-js plugin, the module-federation.config.ts file is not being loaded correctly, causing a build error even though the configuration file exists and is syntactically valid.

Error Message

Error: [ Modern.js Module Federation ] mfConfig.name can not be empty!
    at patchMFConfig (node_modules/@module-federation/modern-js/dist/cjs/cli/configPlugin.js:123:31)

Environment

  • Modern.js: 2.70.2
  • @module-federation/modern-js: 0.22.1
  • React: 19.0.0
  • Node.js: v20.20.0
  • npm: 10.8.2
  • TypeScript: 5.0.4
  • ts-node: 10.9.2
  • OS: Ubuntu (WSL)

Reproduction

Repository

[Link to your reproduction repository once uploaded]

Steps to Reproduce

  1. Create a Modern.js app with the official plugin:
npm install @module-federation/modern-js
  1. Configure modern.config.ts:
import { appTools, defineConfig } from '@modern-js/app-tools';
import { moduleFederationPlugin } from '@module-federation/modern-js';

export default defineConfig({
  runtime: { router: true },
  server: { 
    ssr: { mode: 'stream' },
    port: 3001 
  },
  plugins: [
    appTools({ bundler: 'webpack' }),
    moduleFederationPlugin(),
  ],
});
  1. Create module-federation.config.ts in project root:
export default {
  name: 'remote',
  manifest: { filePath: 'static' },
  filename: 'static/remoteEntry.js',
  exposes: {
    './Welcome': './src/components/Welcome.tsx',
  },
  shared: {
    react: { singleton: true },
    'react-dom': { singleton: true },
  },
};
  1. Run npm run dev

Expected Behavior

The development server should start successfully with Module Federation configured.

Actual Behavior

Build fails with error: "mfConfig.name can not be empty!"

Analysis

Through extensive debugging, we found:

  1. ✅ Config file exists and is syntactically correct
  2. ✅ Plugin registers and executes
  3. ts-node is installed for TypeScript config loading
  4. mfConfig object is empty/undefined when passed to patchMFConfig()

The plugin's validation check fails at line 123:

if (!mfConfig.name) throw new Error(`mfConfig.name can not be empty!`);

This suggests the configuration file is not being discovered or parsed correctly before being passed to the plugin's internal functions.

Attempted Solutions

All following attempts failed with the same error:

  • ✅ Used createModuleFederationConfig() helper
  • ✅ Used plain object export
  • ✅ Tested with both Webpack and Rspack
  • ✅ Tested with and without SSR
  • ✅ Installed ts-node and typescript
  • ✅ Tested JavaScript config file (.js)
  • ✅ Cleared all caches and reinstalled dependencies

Impact

This is a blocking issue that prevents Module Federation from working with Modern.js, despite following the official documentation exactly.

Additional Context

This configuration follows the official documentation:

The same pattern is shown in the official examples repository but doesn't work when implemented.

Questions

  1. Is there a specific configuration requirement not mentioned in the docs?
  2. Are there known version incompatibilities?
  3. Should the config be passed differently when using SSR with streaming mode?

Any guidance on resolving this issue would be greatly appreciated. Happy to provide additional debugging information if needed.

Reproduce link

https://github.com/diegodepaula/modern-module

Reproduce Steps

Create a remote module
Create a consumer module
Enable SSR (mode: 'stream') in both modules
Try to import the remote module in the consumer module
Try to access the page
If the npm run dev doesn't crash the consumer application will crash when the user tries to access it

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions