0

Angular module federation works for my multi-project angular app when using loadRemoteModule() on a standalone component. This standalone component is being used as a "widget" and therefore does not require routing. However, some module imports use .forRoot() which can only be done in a parent module. In my case it is

imports: [
    TimeagoModule.forRoot()
],

This is not allowed in a standalone component as I get the following error:

NG2012: 'imports' contains a ModuleWithProviders value, likely the result of a 'Module.forRoot()'-  style call. These calls are not used to configure components and are not valid in standalone component imports - consider importing them in the application bootstrap instead.                                                     
                                                                               
  18     TimeagoModule.forRoot(),      

If I do not import the module .forRoot(), the module I am trying to use throws a runtime error: NullInjectorError: No provider for TimeagoFormatter!

How can I handle this? Is a change required to my standalone component or do I need to somehow expose the entire module?

My webpack.config.js:

module.exports = withModuleFederationPlugin({
  name: 'my-widget',
exposes: {
    './Config': './src/libs/my-standalone-component.ts',
  },

shared: {
    ...shareAll({ singleton: true, strictVersion: true, requiredVersion: 'auto' }),
  },

Loading it in my main application:

const options: PluginOptions = {
            type: 'module',
            remoteEntry: '../my-component/remoteEntry.js',
            exposedModule: './Config',
            className: 'MyStandaloneComponent'
          };
          const component$ = from(loadRemoteModule(options)).pipe(
            map((exposedModules: any) => {
              return exposedModules['MyStandaloneComponent'];
            })
          );

My standalone component:

@Component({
  standalone: true,
  imports: [
    CommonModule,
    TimeagoModule
  ],
  ...
})
export class MyStandaloneComponent

EDIT: I found a workaround to this problem using the TimeagoModule by specifying the providers:

providers: [
    {
      provide: TimeagoFormatter,
      useClass: TimeagoDefaultFormatter
    },
    {
      provide: TimeagoClock,
      useClass: TimeagoDefaultClock
    }
  ],

However, this is not a true solution to the problem since other libraries may implement additional logic in a ModuleWithProviders (.forRoot() or .forChild())

christopher
  • 615
  • 5
  • 11

0 Answers0