angularserver-side-renderingangular-ssr

Angular: from renderModule to CommonEngine: A required Injectable was not found in the dependency injection tree


I have a monorepo application with two applications, one backend made with Node and the other with Angular. I am trying to use the backend to render in SSR mode the Angular application and so far I was doing it this way:

constructor(
    @inject(TYPES.Logger) private readonly logger: Logger,
    @inject(TYPES.Server) private readonly server: Server,
    @inject(TYPES.Template) private readonly template: Template,
) {
    const frontendServerApplication = resolve(`${this.frontendServerFolder}/main.js`);

    import(frontendServerApplication).then((mainModule) => {
        this.AppServerModule = mainModule.default.AppServerModule;
        this.renderModule = mainModule.default.renderModule;
        this.ɵSERVER_CONTEXT = mainModule.default.ɵSERVER_CONTEXT;
    });
}
// This is the rendered html
const html = await this.renderModule(this.AppServerModule, {
    document: result,
    url: ctx.request.url,
    extraProviders: this.getExtraProviders(ctx, result),
});
return html

I recently upgraded to Angular 17 and I want to use CommonEngine for rendering:

const html = await commonEngine.render({
    bootstrap: this.AppServerModule,
    document: result,
    url: ctx.request.url,
    providers: this.getExtraProviders(ctx, result),
});
return html;

But when I load the application, I get the following error:

RuntimeError: NG0402: A required Injectable was not found in the dependency injection tree. If you are bootstrapping an NgModule, make sure that the `BrowserModule` is imported.
    at Object.useFactory (file:///home/marc/Desarrollo/packages/core/src/change_detection/scheduling/ng_zone_scheduling.ts:64:17)
    at Object.factory (file:///home/marc/Desarrollo/packages/core/src/di/r3_injector.ts:550:32)
    at file:///home/marc/Desarrollo/packages/core/src/di/r3_injector.ts:436:35
    at runInInjectorProfilerContext (file:///home/marc/Desarrollo/packages/core/src/render3/debug/injector_profiler.ts:279:5)
    at R3Injector.hydrate (file:///home/marc/Desarrollo/packages/core/src/di/r3_injector.ts:435:11)
    at R3Injector.get (file:///home/marc/Desarrollo/packages/core/src/di/r3_injector.ts:291:23)
    at injectInjectorOnly (file:///home/marc/Desarrollo/packages/core/src/di/injector_compatibility.ts:71:26)
    at ɵɵinject (file:///home/marc/Desarrollo/packages/core/src/di/injector_compatibility.ts:95:58)
    at injectArgs (file:///home/marc/Desarrollo/packages/core/src/di/injector_compatibility.ts:307:17)
    at Object.multiRecord.factory (file:///home/marc/Desarrollo/packages/core/src/di/r3_injector.ts:410:37) {
  code: 402

Am I missing something along the way? Thanks


Solution

  • I solved the issue by moving the CommonEngine logic to the server.ts of the Angular application and encapsulating it in a function that I expose and consume from the Backend application. This way, I no longer have errors.