Skip to content

@module-federation/enhanced: shareInfoRes.get is not a function while trying to load shared dependency #2497

@fcano-ut

Description

@fcano-ut

Describe the bug

Hi!

I was doing an experiment with enhanced, first of all sorry if this is more like a problem of my mis-understanding of the tool, more than a bug.

I want to achieve the following:

  • Register the consumers/producers using the Module Federation Webpack plugin, to be able to get shared dependency versions from package.json (instead of having to hardcode)
  • Register the consumers at runtime (using registerRemotes), to be able to dynamically register them based on window environment variables and various other logics

My config looks rougly like this:

// host
new ModuleFederationPlugin({
  name: 'host',
  shared: {
    '@usertesting/ui-toolkit': {
      eager: true,
      requiredVersion: packageJson.dependencies['@usertesting/ui-toolkit']
    }
  }
})

// micro-frontend
new ModuleFederationPlugin({
  name: 'microfrontend',
  shared: {
    '@usertesting/ui-toolkit': {
      requiredVersion: packageJson.dependencies['@usertesting/ui-toolkit']
    }
  }
})

I'm not sure if that combination is supported, or if I should instead use init from @module-federation/enhanced. But assuming that combination is supported, then I'm finding what I believe is a bug.

I'm trying to load all the versions of our UI toolkit from all micro-frontends, and start the host and all the apps with the latest version. That means that if the host has version ^1.1.0 and a micro-frontend ^1.2.0, I want the host to use 1.2.0.

My host entrypoint looks roughly like this:

loadUiToolkit()
  .then(() => {
    import('./bootstrap'); // initialize the app
  });

async function loadUiToolkit() {
  registerRemotes([
    {
      name: 'microfrontend',
      entry: mfManifestUrl,
    }
  ]);
  
  await preloadRemote([{
    nameOrAlias: 'microfrontend',
    depsRemote: [
      {nameOrAlias: '@usertesting/ui-toolkit'},
    ]
  }]);
  
  await loadShare('@usertesting/ui-toolkit');
}

To my understanding this should do the trick:

  • Register the app
  • Pre-load the ui toolkit dependency
  • Load the UI toolkit shared dependency (thus, add the latest version to the share scope, so that all apps use that version)

However I have the following error: shareInfoRes.get is not a function while trying to load shared dependency (failing in the loadShare function)

Screenshot 2024-05-16 at 09 06 24

I tried swapping preloadRemote with loadRemote, but even if I load the remote beforehand, the loadShare function fails with the same error

  // ...
  await loadRemote('microfrontend');
  await loadShare('@usertesting/ui-toolkit'); // ❌ shareInfoRes.get is not a function while trying to load shared dependency

I would like to know if (a) What I'm trying to do is possible, and (b) if this is a bug in my setup or an actual bug in the library

Thank you for reading this far.

Reproduction

I can create a reproduction example but I first want to validate if my setup is even supported (using webpack config to register, and enhanced plugin to load)

Used Package Manager

npm

System Info

Validations

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