Dynamic Plugin Loading with Angular
Use Angular's dynamic import to load plugins lazily and register them with the Dependency Injection system without needing to list them statically.
import { Injectable, Injector, Compiler } from '@angular/core';
@Injectable({
providedIn: 'root',
})
export class PluginLoaderService {
constructor(private injector: Injector, private compiler: Compiler) {}
async loadPlugin(pluginName: string) {
// Dynamic import to lazily load the plugin module
const module = await import(
`./plugins/${pluginName}/${pluginName}.module`
).then(m => m[`${pluginName}Module`]);
// Compile the module and resolve the module instance
const moduleFactory = await this.compiler.compileModuleAsync(module);
const moduleRef = moduleFactory.create(this.injector);
// Assume the plugin provides a static '.forRoot()' method to register its services
if (module.forRoot) {
this.injector = module.forRoot(moduleRef.injector);
}
}
}
This service provides functionality to dynamically load and compile a plugin module by its name. The `loadPlugin()` method uses the dynamic imports feature from the ES2020 specification, allowing Angular to load only the necessary code for a plugin, without the need to list it in the main application bundle. After dynamically importing, it compiles the module and uses its `.forRoot()` method to register any services with Angular's dependency injection system.