alexzuza / angular-plugin-architecture-with-module-federation

An example of building pluggable Angular architecture with the help of webpack 5 Module Federation
75 stars 31 forks source link

TypeError: moduleFactory.create is not a function. #3

Open ghost opened 3 years ago

ghost commented 3 years ago

Hi, Thank you for your great work here! I have tried to get the plugin architecture to work. I created the plugin and can build it successfully. The plugin Loader itself just works fine while loading the javascript source file. The result of the pluginLoader load function (the moduleFactory object) looks like this

image

The load Plugin Function itself gives me the error massage TypeError: moduleFactory.create is not a function. (In 'moduleFactory.create(this.injector)', 'moduleFactory.create' is undefined) in the resolve part of the load function! Can you point me with that information what I am doin wrong?

Thanks For Help

faileon commented 1 year ago

Late to the party but I believe the factories are deprecated in newer Angular versions. Now to instantiate the module you can do it like this:

import { createNgModule } from '@angular/core';

const moduleRef = createNgModule(moduleClass);

Later when you want to instantiate a component you should use the component class directly. Question is how to obtain the component classes from instantiated module. You can perhaps use the bootstrap components and/or entryComponents of the module, but I did not find a non-hacky way to access those properties. Instead I solved it with custom DI tokens.

// get hold of some component via DI -> 'entry' is a custom string token in the loaded module
const entryComponentClass = moduleRef.injector.get('entry');

this.viewContainerRef.createComponent(entryComponentClass, {
      injector: moduleRef.injector,
      ngModuleRef: moduleRef
    });

In the plugin's module:

@NgModule({
  imports: [CommonModule],
  declarations: [PluginEntryComponent],
  providers: [
    {
      provide: 'entry',
      useValue: PluginEntryComponent,
    },
  ],
})
export class SomePluginModule{}