Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

SSR Angular 8 application have lazy-load modules as undefined

I'm trying to set up my Angular 8 application to run with SSR but my lazyloaded modules triggers some undefined errors in webpack when I run my application with ng serve. It was working fine before with Angular 7 but going to Angular 8 broke everything. this is the error I'm getting on runtime (in node console)

ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'call' of undefined
TypeError: Cannot read property 'call' of undefined
    at __webpack_require__ (/Users/gwenaellarmet/Documents/Projects/ng-nouma/dist/server.js:137403:30)
    at Function.requireEnsure [as e] (/Users/gwenaellarmet/Documents/Projects/ng-nouma/dist/server.js:137422:25)
    at ɵ11 (/Users/gwenaellarmet/Documents/Projects/ng-nouma/dist/server.js:139660:6210)
    at RouterConfigLoader.loadModuleFactory (/Users/gwenaellarmet/Documents/Projects/ng-nouma/dist/server.js:232758:39)

I tried changing some of the tsconfig and the angular.json config but I'm always getting the same error. Ivy is not enable as it also triggers some error on build; I think it's linked but I'm not sure so for now I'm trying to get it work without Ivy

ERROR in src/app/pages/search/search.module.ts(68,12): error TS-991010: Value at position 12 in the NgModule.importss of SearchModule is not a reference: [object Object]
src/app/app.module.ts(41,12): error TS-991010: Value at position 6 in the NgModule.importss of AppModule is not a reference: [object Object]

tsconfig.json

{
  "compileOnSave": false,
  "angularCompilerOptions": {
    "enableIvy": true,
    "allowEmptyCodegenFiles": true
  },
  "compilerOptions": {
    "baseUrl": "./src",
    "importHelpers": true,
    "paths": {
      "@nouma/core": ["app/core/core.index.ts"],
      "@nouma/coreModule": ["app/core/core.module.ts"],
      "@nouma/material": ["app/utils/nouma-material/nouma-material.module.ts"],
      "@nouma/ui": ["app/ui/ui.index.ts"],
      "@nouma/env": ["environments/environment.ts"],
      "@nouma/errors": ["app/pages/error-pages/error-pages.index.ts"],
      "@nouma/home": ["app/pages/home/home.component.ts"],
      "@nouma/popins": ["app/pages/popins/popins.index.ts"],
      "@nouma/popinsModule": ["app/pages/popins/popins.module.ts"]
    },
    "incremental": true,
    "outDir": "./dist/out-tsc",
    "sourceMap": true,
    "declaration": false,
    "module": "esnext",
    "moduleResolution": "node",
    "emitDecoratorMetadata": true,
    "experimentalDecorators": true,
    "target": "es5",
    "typeRoots": [
      "node_modules/@types"
    ],
    "lib": [
      "es2018",
      "dom"
    ]
  }
}

tsconfig.server.json

{
  "extends": "./tsconfig.app.json",
  "compilerOptions": {
    "outDir": "../out-tsc/app-server",
    "baseUrl": "."
  },
  "angularCompilerOptions": {
    "entryModule": "app/app.server.module#AppServerModule"
  }
}

angular.json

{
  "$schema": "./node_modules/@angular/cli/lib/config/schema.json",
  "version": 1,
  "newProjectRoot": "projects",
  "projects": {
    "ng-nouma": {
      "root": "",
      "sourceRoot": "src",
      "projectType": "application",
      "prefix": "app",
      "schematics": {},
      "architect": {
        "build": {
          "builder": "@angular-devkit/build-angular:browser",
          "options": {
            "outputPath": "dist/browser",
            "index": "src/index.html",
            "main": "src/main.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.app.json",
            "assets": [
              "src/favicon.ico",
              "src/robots.txt",
              "src/assets"
            ],
            "styles": [
              "src/app/utils/nouma-material/nouma-app-theme.scss",
              "src/styles.scss"
            ],
            "scripts": [
              "node_modules/jquery/dist/jquery.min.js",
              "node_modules/foundation-sites/dist/js/foundation.min.js"
            ],
            "lazyModules": [
              "src/app/pages/search/search.module",
              "src/app/pages/search/search.module",
              "src/app/pages/tender-detail/tender-detail.module",
              "src/app/pages/sources/sources.module",
              "src/app/pages/offer/offer.module",
              "src/app/pages/forgotten/forgotten.module",
              "src/app/pages/confirm/confirm.module",
              "src/app/pages/alerts/alerts.module",
              "src/app/pages/bookmarks/bookmarks.module",
              "src/app/pages/account/account.module",
              "src/app/pages/home/home.module"
            ]
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ],
              "optimization": true,
              "outputHashing": "all",
              "sourceMap": false,
              "extractCss": true,
              "namedChunks": false,
              "aot": true,
              "extractLicenses": false,
              "vendorChunk": false,
              "buildOptimizer": true
            },
            "local": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.local.ts"
                }
              ]
            }
          }
        },
        "serve": {
          "builder": "@angular-devkit/build-angular:dev-server",
          "options": {
            "browserTarget": "ng-nouma:build"
          },
          "configurations": {
            "production": {
              "browserTarget": "ng-nouma:build:production"
            },
            "local": {
              "browserTarget": "ng-nouma:build:local"
            }
          }
        },
        "extract-i18n": {
          "builder": "@angular-devkit/build-angular:extract-i18n",
          "options": {
            "browserTarget": "ng-nouma:build"
          }
        },
        "test": {
          "builder": "@angular-devkit/build-angular:karma",
          "options": {
            "main": "src/test.ts",
            "polyfills": "src/polyfills.ts",
            "tsConfig": "src/tsconfig.spec.json",
            "karmaConfig": "src/karma.conf.js",
            "styles": [
              "./node_modules/@angular/material/prebuilt-themes/indigo-pink.css",
              "src/styles.scss"
            ],
            "scripts": [],
            "assets": [
              "src/favicon.ico",
              "src/assets"
            ]
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": [
              "src/tsconfig.app.json",
              "src/tsconfig.spec.json"
            ],
            "exclude": [
              "**/node_modules/**"
            ]
          }
        },
        "server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/server",
            "main": "src/main.server.ts",
            "tsConfig": "src/tsconfig.server.json"
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            },
            "local": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.local.ts"
                }
              ]
            }
          }
        }
      }
    },
    "ng-nouma-e2e": {
      "root": "e2e/",
      "projectType": "application",
      "architect": {
        "e2e": {
          "builder": "@angular-devkit/build-angular:protractor",
          "options": {
            "protractorConfig": "e2e/protractor.conf.js",
            "devServerTarget": "ng-nouma:serve"
          },
          "configurations": {
            "production": {
              "devServerTarget": "ng-nouma:serve:production"
            },
            "local": {
              "devServerTarget": "ng-nouma:serve:local"
            }
          }
        },
        "lint": {
          "builder": "@angular-devkit/build-angular:tslint",
          "options": {
            "tsConfig": "e2e/tsconfig.e2e.json",
            "exclude": [
              "**/node_modules/**"
            ]
          }
        }
      }
    }
  },
  "defaultProject": "ng-nouma",
  "schematics": {
    "@schematics/angular:component": {
      "styleext": "scss"
    }
  }
}

packages.json

{
  "name": "ng-nouma",
  "version": "0.0.0",
  "scripts": {
    "ng": "ng",
    "postinstall": "ivy-ngcc",
    "start": "ng serve",
    "start:opti": "ng serve --aot --optimization",
    "start:local": "ng serve --configuration=local",
    "start:prod": "ng serve --configuration=production",
    "build": "ng build --aot --build-optimizer --optimization",
    "build:prod": "ng build --prod --aot --build-optimizer --optimization",
    "build:local": "ng build --configuration=local --aot --build-optimizer --optimization",
    "test": "ng test",
    "lint": "ng lint",
    "bundle-report": "ng build --stats-json --aot --build-optimizer --optimization && webpack-bundle-analyzer dist/browser/stats.json",
    "bundle-report:prod": "ng build --stats-json --prod --aot --build-optimizer --optimization && webpack-bundle-analyzer dist/browser/stats.json",
    "e2e": "ng e2e",
    "compile:server": "webpack --config webpack.server.config.js --progress --colors",
    "serve:ssr": "node dist/server",
    "build:ssr": "npm run build:client-and-server-bundles && npm run compile:server",
    "build:ssr:staging": "npm run build:client-and-server-bundles:staging && npm run compile:server",
    "build:ssr:local": "npm run build:client-and-server-bundles:local && npm run compile:server",
    "build:client-and-server-bundles": "ng build --prod --aot --build-optimizer --optimization && ng run ng-nouma:server:production",
    "build:client-and-server-bundles:staging": "ng build --aot --build-optimizer --optimization && ng run ng-nouma:server",
    "build:client-and-server-bundles:local": "ng build --aot --build-optimizer --optimization --configuration=local && ng run ng-nouma:server"
  },
  "private": true,
  "dependencies": {
    "@agm/core": "^1.0.0-beta.5",
    "@angular/animations": "^8.0.0",
    "@angular/cdk": "~8.0.0",
    "@angular/common": "^8.0.0",
    "@angular/compiler": "^8.0.0",
    "@angular/core": "^8.0.0",
    "@angular/forms": "^8.0.0",
    "@angular/material": "^8.0.0",
    "@angular/platform-browser": "^8.0.0",
    "@angular/platform-browser-dynamic": "^8.0.0",
    "@angular/platform-server": "^8.0.0",
    "@angular/router": "^8.0.0",
    "@fortawesome/angular-fontawesome": "^0.4.0",
    "@fortawesome/fontawesome-pro": "^5.8.2",
    "@fortawesome/fontawesome-svg-core": "^1.2.18",
    "@fortawesome/free-brands-svg-icons": "^5.8.2",
    "@fortawesome/pro-light-svg-icons": "^5.8.2",
    "@fortawesome/pro-regular-svg-icons": "^5.8.2",
    "@fortawesome/pro-solid-svg-icons": "^5.8.2",
    "@nguniversal/common": "^7.1.1",
    "@nguniversal/express-engine": "^7.1.1",
    "@nguniversal/module-map-ngfactory-loader": "^7.1.1",
    "angular2-toaster": "^7.0.0",
    "angulartics2": "^7.5.2",
    "core-js": "^3.1.3",
    "express": "^4.17.1",
    "foundation-sites": "6.5.3",
    "hammerjs": "^2.0.8",
    "jquery": "^3.4.1",
    "ng-intercom": "^8.0.0-beta.1",
    "ngx-chips": "^2.0.0-beta.0",
    "ngx-cookie-service": "^2.2.0",
    "ngx-foundation": "1.0.8",
    "ngx-infinite-scroll": "^7.1.0",
    "ngx-mask": "^7.9.9",
    "rxjs": "~6.5.2",
    "sass-loader": "^7.1.0",
    "terser": "^4.0.0",
    "tslib": "^1.9.0",
    "zone.js": "~0.9.1"
  },
  "devDependencies": {
    "@angular-devkit/build-angular": "~0.800.0",
    "@angular/cli": "~8.0.0",
    "@angular/compiler-cli": "^8.0.0",
    "@angular/language-service": "^8.0.0",
    "@types/jasmine": "~3.3.13",
    "@types/jasminewd2": "~2.0.3",
    "@types/node": "~12.0.3",
    "codelyzer": "^5.0.1",
    "jasmine-core": "~3.4.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "^4.1.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "~2.0.5",
    "karma-jasmine": "~2.0.1",
    "karma-jasmine-html-reporter": "^1.4.2",
    "protractor": "~5.4.0",
    "ts-loader": "^6.0.1",
    "ts-node": "~8.2.0",
    "tslint": "~5.16.0",
    "typescript": "~3.4.5",
    "webpack-bundle-analyzer": "^3.3.2",
    "webpack-cli": "^3.2.0"
  }
}

I'm building my application with npm run build:ssr and serving it with npm run serve:ssr

I need my application rendering all the modules and markup with SSR for SEO purposes and would love to have some help to where the issue is.

like image 253
Gwenael Larmet Avatar asked Jun 07 '19 16:06

Gwenael Larmet


1 Answers

The problem is that there are two copies of Angular in the older way of setting up Universal and it confuses the lazy loading system.

You can manually fix this issue by updating the following:

package.json

add --bundleDependencies all at the end of the value of build:client-and-server-bundles

server.ts

remove the following lines

import {enableProdMode} from '@angular/core';     
import {ngExpressEngine} from '@nguniversal/express-engine';  
import {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';
enableProdMode();
const {AppServerModuleNgFactory, LAZY_MODULE_MAP} = require('./dist/server/main');

then add

const {AppServerModuleNgFactory, LAZY_MODULE_MAP, ngExpressEngine, provideModuleMap} = require('./dist/server/main');

main.server.ts

add

export {ngExpressEngine} from '@nguniversal/express-engine';
export {provideModuleMap} from '@nguniversal/module-map-ngfactory-loader';

webpack.server.config.js

add

externals: {
 './dist/server/main': 'require("./server/main")'
}

Reference: fix lazy loading and bundleDependencies

like image 70
Paul Mikki Avatar answered Sep 22 '22 21:09

Paul Mikki