4

i have created project with firebase store. Now i want to implement server side rendering on it. After i did everything for ssr when i run program this is what i get

ReferenceError: window is not defined
    at Object.ex9U (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:166129:4)
    at __webpack_require__ (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:26:30)
    at Module.vvyD (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:271824:80)
    at __webpack_require__ (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:26:30)
    at Module.PCNd (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:131612:74)
    at __webpack_require__ (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:26:30)
    at Module.ZAI4 (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:154371:80)
    at __webpack_require__ (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:26:30)
    at Module.24aS (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:47619:69)
    at __webpack_require__ (C:\Users\waqas\Desktop\ng-blog\dist\ng-blog\server\main.js:26:30)

A server error has occurred.
node exited with 1 code.
connect ECONNREFUSED 127.0.0.1:63621

here are my files package.json

{
    "name": "ng-blog",
    "version": "0.0.0",
    "scripts": {
        "ng": "ng",
        "start": "ng serve",
        "build": "ng build",
        "dev:ssr": "ng run ng-blog:serve-ssr",
        "serve:ssr": "node dist/ng-blog/server/main.js",
        "build:ssr": "ng build --prod && ng run ng-blog:server:production",
        "prerender": "ng run ng-blog:prerender"
    },
    "private": true,
    "dependencies": {
        "@angular/animations": "~11.2.10",
        "@angular/cdk": "^11.2.9",
        "@angular/common": "~11.2.10",
        "@angular/compiler": "~11.2.10",
        "@angular/core": "~11.2.10",
        "@angular/fire": "^6.1.4",
        "@angular/forms": "~11.2.10",
        "@angular/material": "^11.2.9",
        "@angular/platform-browser": "~11.2.10",
        "@angular/platform-browser-dynamic": "~11.2.10",
        "@angular/platform-server": "~11.2.10",
        "@angular/router": "~11.2.10",
        "@nguniversal/express-engine": "^11.2.1",
        "@ntegral/ngx-universal-window": "^1.0.2",
        "@tinymce/tinymce-angular": "^4.2.2",
        "angular-froala-wysiwyg": "^3.2.6-1",
        "angularfire2": "^5.4.2",
        "express": "^4.15.2",
        "firebase": "^7.24.0",
        "rxjs": "~6.6.0",
        "rxjs-compat": "^6.6.7",
        "tinymce": "^5.7.1",
        "tslib": "^2.0.0",
        "zone.js": "~0.11.3"
    },
    "devDependencies": {
        "@angular-devkit/build-angular": "~0.1102.9",
        "@angular/cli": "~11.2.9",
        "@angular/compiler-cli": "~11.2.10",
        "@nguniversal/builders": "^11.2.1",
        "@types/express": "^4.17.0",
        "@types/node": "^12.11.1",
        "typescript": "~4.1.5"
    }
}

Server.ts

import 'zone.js/dist/zone-node';

import { ngExpressEngine } from '@nguniversal/express-engine';
import * as express from 'express';
import { join } from 'path';

import { AppServerModule } from './src/main.server';
import { APP_BASE_HREF } from '@angular/common';
import { existsSync } from 'fs';

// 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/ng-blog/browser');
  const indexHtml = existsSync(join(distFolder, 'index.original.html')) ? 'index.original.html' : 'index';

  // Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
  server.engine('html', ngExpressEngine({
    bootstrap: AppServerModule,
  }));

  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 Universal engine
  server.get('*', (req, res) => {
    res.render(indexHtml, { req, providers: [{ provide: APP_BASE_HREF, useValue: req.baseUrl }] });
  });

  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 * from './src/main.server';

angular.json

{
    "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
    "version": 1,
    "newProjectRoot": "projects",
    "projects": {
        "ng-blog": {
            "projectType": "application",
            "schematics": {
                "@schematics/angular:component": {
                    "inlineTemplate": false,
                    "inlineStyle": false,
                    "style": "scss",
                    "skipTests": true
                },
                "@schematics/angular:class": {
                    "skipTests": true
                },
                "@schematics/angular:directive": {
                    "skipTests": true
                },
                "@schematics/angular:guard": {
                    "skipTests": true
                },
                "@schematics/angular:interceptor": {
                    "skipTests": true
                },
                "@schematics/angular:module": {
                    "skipTests": true
                },
                "@schematics/angular:pipe": {
                    "skipTests": true
                },
                "@schematics/angular:service": {
                    "skipTests": true
                }
            },
            "root": "",
            "sourceRoot": "src",
            "prefix": "app",
            "architect": {
                "build": {
                    "builder": "@angular-devkit/build-angular:browser",
                    "options": {
                        "outputPath": "dist/ng-blog/browser",
                        "index": "src/index.html",
                        "main": "src/main.ts",
                        "polyfills": "src/polyfills.ts",
                        "tsConfig": "tsconfig.app.json",
                        "aot": true,
                        "assets": [
                            "src/favicon.ico",
                            "src/assets"
                        ],
                        "styles": [
                            "src/styles.scss",
                            "src/theme.scss",
                            "node_modules/tinymce/skins/ui/oxide/skin.min.css",
                            "node_modules/tinymce/skins/ui/oxide/content.min.css",
                            "node_modules/tinymce/skins/content/default/content.min.css",
                            "./node_modules/froala-editor/css/froala_editor.pkgd.min.css",
                            "./node_modules/froala-editor/css/froala_style.min.css"

                        ],
                        "scripts": [
                            "node_modules/tinymce/tinymce.min.js",
                            "node_modules/tinymce/themes/silver/theme.js"
                        ]
                    },
                    "configurations": {
                        "production": {
                            "fileReplacements": [{
                                "replace": "src/environments/environment.ts",
                                "with": "src/environments/environment.prod.ts"
                            }],
                            "optimization": true,
                            "outputHashing": "all",
                            "sourceMap": false,
                            "namedChunks": false,
                            "extractLicenses": true,
                            "vendorChunk": false,
                            "buildOptimizer": true,
                            "budgets": [{
                                    "type": "initial",
                                    "maximumWarning": "2mb",
                                    "maximumError": "5mb"
                                },
                                {
                                    "type": "anyComponentStyle",
                                    "maximumWarning": "6kb",
                                    "maximumError": "10kb"
                                }
                            ]
                        }
                    }
                },
                "serve": {
                    "builder": "@angular-devkit/build-angular:dev-server",
                    "options": {
                        "browserTarget": "ng-blog:build"
                    },
                    "configurations": {
                        "production": {
                            "browserTarget": "ng-blog:build:production"
                        }
                    }
                },
                "extract-i18n": {
                    "builder": "@angular-devkit/build-angular:extract-i18n",
                    "options": {
                        "browserTarget": "ng-blog:build"
                    }
                },
                "server": {
                    "builder": "@angular-devkit/build-angular:server",
                    "options": {
                        "outputPath": "dist/ng-blog/server",
                        "main": "server.ts",
                        "tsConfig": "tsconfig.server.json"
                    },
                    "configurations": {
                        "production": {
                            "outputHashing": "media",
                            "fileReplacements": [
                                {
                                    "replace": "src/environments/environment.ts",
                                    "with": "src/environments/environment.prod.ts"
                                }
                            ],
                            "sourceMap": false,
                            "optimization": true
                        }
                    }
                },
                "serve-ssr": {
                    "builder": "@nguniversal/builders:ssr-dev-server",
                    "options": {
                        "serverTarget": "ng-blog:server",
                        "browserTarget": "ng-blog:build"
                        
                    },
                    "configurations": {
                        "production": {
                            "browserTarget": "ng-blog:build:production",
                            "serverTarget": "ng-blog:server:production"
                        }
                    }
                },
                "prerender": {
                    "builder": "@nguniversal/builders:prerender",
                    "options": {
                        "browserTarget": "ng-blog:build:production",
                        "serverTarget": "ng-blog:server:production",
                        "routes": [
                            "/"
                        ]
                    },
                    "configurations": {
                        "production": {}
                    }
                }
            }
        }
    },
    "defaultProject": "ng-blog"
}

i dont understand what is the issue when i use npm run dev:ssr i get this error

David
  • 33,444
  • 11
  • 80
  • 118
waqas waqas
  • 197
  • 9
  • 22
  • on SSR, there is no `window`, because you are on the server, not on the browser. So you have to make your window null-safe. You may see many trick on google about that. – Random Apr 27 '21 at 12:32
  • Have a look here https://stackoverflow.com/a/56936770/1160794 – David May 04 '21 at 09:15

2 Answers2

5

Add "module": "commonjs", inside compilerOptions at tsconfig.server.json.

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "module": "commonjs",
    "outDir": "./out-tsc/server",
    "target": "es2019",
    "types": [
      "node"
    ]
  },
  "files": [
    "src/main.server.ts",
    "server.ts"
  ],
  "angularCompilerOptions": {
    "entryModule": "./src/app/app.server.module#AppServerModule"
  }
}

credit link

Antikhippe
  • 6,316
  • 2
  • 28
  • 43
Santosh
  • 3,477
  • 5
  • 37
  • 75
1

Install the ssr-window from NPM (https://www.npmjs.com/package/ssr-window)

In JS File use like below -

import {getWindow} from "ssr-window";

ngOnInit() {
const width = getWindow().innerWidth;
}

There is no change for the Html file, you can use like below-

<main  (window:resize)="onResize()">
  <app-header></app-header>
</main>