Angular 17 SSR - No tasks executed on server

50 Views Asked by At

Recently, I updated an Angular project from version 16 to version 17. Today, I decided to add SSR to the project. The project is running with no problems when served using npm run dev:ssr, and the HTML is being rendered on the server side, but no logic written in TypeScript is being executed on server at all, and I need some things to be executed on server.

For example, this is the constructor of my AppComponent:

    constructor(

Blockquote

    private _router: Router,
    @Inject(PLATFORM_ID) private platformId: Object) {
 console.log(isPlatformServer(this.platformId) ? 'Server' : 'Client'); 

}

And it is always being executed in browser for some reason, but I need to write some code that's gonna be executed on server first. I think my project might be improperly configured, but I'm not sure where to find the solution.

Further info about the project:

  1. It contains 4 Lazy Loaded modules (if this is relevant);

  2. Here's my AppServerModule code:

    import { NgModule } from '@angular/core'; import { ServerModule } from '@angular/platform-server';

     import { AppModule } from './app.module';
     import { AppComponent } from './app.component';
    
     import { FlexLayoutServerModule } from '@ngbracket/ngx-layout/server';
    
     @NgModule({
       imports: [
         AppModule,
         ServerModule,
         FlexLayoutServerModule,
       ],
       bootstrap: [AppComponent],
     })
     export class AppServerModule {}
    
  3. Here's my server.ts:

  
    import 'zone.js/node';
    
    import { APP_BASE_HREF } from '@angular/common';
    import { CommonEngine } from '@angular/ssr';
    import * as express from 'express';
    import { existsSync } from 'node:fs';
    import { join } from 'node:path';
    import AppServerModule from './src/main.server';
    
    // The Express app is exported so that it can be used by serverless Functions.
    export function app(): express.Express {
      const server = express();
      const distFolder = join(process.cwd(), 'dist/KempaWebApp/browser');
      const indexHtml = existsSync(join(distFolder, 'index.original.html'))
        ? join(distFolder, 'index.original.html')
        : join(distFolder, 'index.html');
    
      const commonEngine = new CommonEngine();
    
      server.set('view engine', 'html');
      server.set('views', distFolder);
    
      // Example Express Rest API endpoints
      // server.get('/api/**', (req, res) => { });
      // Serve static files from /browser
      server.get('*.*', express.static(distFolder, {
        maxAge: '1y'
      }));
    
      // All regular routes use the Angular engine
      server.get('*', (req, res, next) => {
        const { protocol, originalUrl, baseUrl, headers } = req;
    
        commonEngine
          .render({
            bootstrap: AppServerModule,
            documentFilePath: indexHtml,
            url: `${protocol}://${headers.host}${originalUrl}`,
            publicPath: distFolder,
            providers: [{ provide: APP_BASE_HREF, useValue: baseUrl }],
          })
          .then((html) => res.send(html))
          .catch((err) => next(err));
      });
    
      return server;
    }
    
    function run(): void {
      const port = process.env['PORT'] || 4000;
    
      // Start up the Node server
      const server = app();
      server.listen(port, () => {
        console.log(`Node Express server listening on http://localhost:${port}`);
      });
    }
    
    // Webpack will replace 'require' with '__webpack_require__'
    // '__non_webpack_require__' is a proxy to Node 'require'
    // The below code is to ensure that the server is run only when not requiring the bundle.
    declare const __non_webpack_require__: NodeRequire;
    const mainModule = __non_webpack_require__.main;
    const moduleFilename = mainModule && mainModule.filename || '';
    if (moduleFilename === __filename || moduleFilename.includes('iisnode')) {
      run();
    }
    
    export default AppServerModule;
 
  1. This is what I have in main.server.ts:

export { AppServerModule as default } from './app/app.module.server';

If there's any other relevant info I can provide, please, ask me in the comment.

UPDATE: Here's my angular.json:



    {
    
          "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
          "version": 1,
          "newProjectRoot": "projects",
          "projects": {
            "AuroraWebApp": {
              "projectType": "application",
              "schematics": {
                "@schematics/angular:component": {
                  "style": "scss"
                },
                "@schematics/angular:application": {
                  "strict": false
                }
              },
              "root": "",
              "sourceRoot": "src",
              "prefix": "app",
              "architect": {
                "build": {
                  "builder": "@angular-devkit/build-angular:browser",
                  "options": {
                    "outputPath": "dist/AuroraWebApp/browser",
                    "index": "src/index.html",
                    "main": "src/main.ts",
                    "polyfills": [
                      "zone.js"
                    ],
                    "tsConfig": "tsconfig.app.json",
                    "inlineStyleLanguage": "scss",
                    "assets": [
                      "src/favicon.ico",
                      "src/assets",
                      "src/robots.txt",
                      "src/sitemap.xml"
                    ],
                    "styles": [
                      "src/styles.scss"
                    ],
                    "scripts": []
                  },
                  "configurations": {
                    "production": {
                      "budgets": [
                        {
                          "type": "initial",
                          "maximumWarning": "500kb",
                          "maximumError": "2mb"
                        },
                        {
                          "type": "anyComponentStyle",
                          "maximumWarning": "2kb",
                          "maximumError": "10kb"
                        }
                      ],
                      "index": {
                        "input": "src/index.prod.html",
                        "output": "index.html"
                      },
                      "fileReplacements": [
                        {
                          "replace": "src/environments/environment.ts",
                          "with": "src/environments/environment.prod.ts"
                        }
                      ],
                      "outputHashing": "all"
                    },
                    "staging": {
                      "budgets": [
                        {
                          "type": "initial",
                          "maximumWarning": "500kb",
                          "maximumError": "2mb"
                        },
                        {
                          "type": "anyComponentStyle",
                          "maximumWarning": "2kb",
                          "maximumError": "10kb"
                        }
                      ],
                      "fileReplacements": [
                        {
                          "replace": "src/environments/environment.ts",
                          "with": "src/environments/environment.staging.ts"
                        }
                      ],
                      "outputHashing": "all"
                    },
                    "development": {
                      "buildOptimizer": false,
                      "optimization": false,
                      "vendorChunk": true,
                      "extractLicenses": false,
                      "sourceMap": true,
                      "namedChunks": true
                    }
                  },
                  "defaultConfiguration": "production"
                },
                "serve": {
                  "builder": "@angular-devkit/build-angular:dev-server",
                  "configurations": {
                    "production": {
                      "buildTarget": "AuroraWebApp:build:production"
                    },
                    "development": {
                      "buildTarget": "AuroraWebApp:build:development"
                    }
                  },
                  "defaultConfiguration": "development"
                },
                "extract-i18n": {
                  "builder": "@angular-devkit/build-angular:extract-i18n",
                  "options": {
                    "buildTarget": "AuroraWebApp:build"
                  }
                },
                "test": {
                  "builder": "@angular-devkit/build-angular:karma",
                  "options": {
                    "polyfills": [
                      "zone.js",
                      "zone.js/testing"
                    ],
                    "tsConfig": "tsconfig.spec.json",
                    "inlineStyleLanguage": "scss",
                    "assets": [
                      "src/favicon.ico",
                      "src/assets",
                      "src/robots.txt",
                      "src/sitemap.xml"
                    ],
                    "styles": [
                      "src/styles.scss"
                    ],
                    "scripts": []
                  }
                },
                "server": {
                  "builder": "@angular-devkit/build-angular:server",
                  "options": {
                    "outputPath": "dist/AuroraWebApp/server",
                    "main": "server.ts",
                    "tsConfig": "tsconfig.server.json",
                    "inlineStyleLanguage": "scss"
                  },
                  "configurations": {
                    "production": {
                      "outputHashing": "media",
                      "fileReplacements": [
                        {
                          "replace": "src/environments/environment.ts",
                          "with": "src/environments/environment.prod.ts"
                        }
                      ]
                    },
                    "staging": {
                      "outputHashing": "media",
                      "fileReplacements": [
                        {
                          "replace": "src/environments/environment.ts",
                          "with": "src/environments/environment.staging.ts"
                        }
                      ]
                    },
                    "development": {
                      "buildOptimizer": false,
                      "optimization": false,
                      "sourceMap": true,
                      "extractLicenses": false,
                      "vendorChunk": true
                    }
                  },
                  "defaultConfiguration": "production"
                },
                "serve-ssr": {
                  "builder": "@angular-devkit/build-angular:ssr-dev-server",
                  "configurations": {
                    "development": {
                      "browserTarget": "AuroraWebApp:build:development",
                      "serverTarget": "AuroraWebApp:server:development"
                    },
                    "production": {
                      "browserTarget": "AuroraWebApp:build:production",
                      "serverTarget": "AuroraWebApp:server:production"
                    }
                  },
                  "defaultConfiguration": "development"
                },
                "prerender": {
                  "builder": "@angular-devkit/build-angular:prerender",
                  "options": {
                    "routes": [
                      "/"
                    ]
                  },
                  "configurations": {
                    "production": {
                      "browserTarget": "AuroraWebApp:build:production",
                      "serverTarget": "AuroraWebApp:server:production"
                    },
                    "development": {
                      "browserTarget": "AuroraWebApp:build:development",
                      "serverTarget": "AuroraWebApp:server:development"
                    }
                  },
                  "defaultConfiguration": "production"
                }
              }
            }
          },
          "cli": {
            "cache": {
              "enabled": false
            },
            "analytics": false
          }
        }
    
    
0

There are 0 best solutions below