Приложение SSR Angular 8 имеет модули ленивой загрузки как undefined

Я пытаюсь настроить приложение Angular 8 для работы с SSR, но мои лениво загруженные модули вызывают некоторые неопределенные ошибки в веб-пакете, когда я запускаю свое приложение с помощью ng serve. Раньше он работал нормально с Angular 7, но переход на Angular 8 сломал все. это ошибка, которую я получаю во время выполнения (в консоли узла)

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)

Я попытался изменить некоторые настройки tsconfig и angular.json, но всегда получаю одну и ту же ошибку. 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"
  }
}

угловой.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"
    }
  }
}

пакеты.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"
  }
}

Я создаю свое приложение с помощью npm run build:ssr и обслуживаю его с помощью npm run serve:ssr

Мне нужно, чтобы мое приложение отображало все модули и разметку с помощью SSR для целей SEO, и мне бы хотелось получить некоторую помощь в решении проблемы.

Вы перенесли все свои маршруты loadChildren для Angular 8?

Reactgular 07.06.2019 18:43

Да, теперь все мои маршруты выглядят так, следуя синтаксису Angular 8: { path: '', loadChildren: () => import('./pages/home/home.module').then(m => m.HomeModule), }

Gwenael Larmet 07.06.2019 18:46

Скидывайте все модули и потом включайте по одному, пока не найдете нарушителя.

Reactgular 07.06.2019 18:47

Хорошая идея, попробую

Gwenael Larmet 07.06.2019 18:52

Эта ошибка находится в файле server.js. Если я правильно помню, этот файл не является частью пакетов Angular. Они загружаются отдельно. Поэтому мне интересно, не может ли сервер загрузить модуль приложения в начале. У меня возникло бы искушение запустить SSR в отладчике.

Reactgular 07.06.2019 18:55

Без каких-либо отложенных модулей все работает нормально, поэтому проблема здесь, как я и ожидал, я попытаюсь отладить SSR, чтобы найти, где именно проблема.

Gwenael Larmet 07.06.2019 18:59

«Ivy не будет готов для всех вариантов использования. Некоторые функции, такие как i18n или Angular Universal, скорее всего, еще не будут полностью совместимы в предварительной версии». blog.angular.io/a-plan-for-version-8-0-and-ivy-b3318dfc19f7

Gilsdav 12.06.2019 22:16
Тестирование функциональных ngrx-эффектов в Angular 16 с помощью Jest
В системе управления состояниями ngrx, совместимой с Angular 16, появились функциональные эффекты. Это здорово и делает код определенно легче для...
Angular и React для вашего проекта веб-разработки?
Angular и React для вашего проекта веб-разработки?
Когда дело доходит до веб-разработки, выбор правильного front-end фреймворка имеет решающее значение. Angular и React - два самых популярных...
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Эпизод 23/17: Twitter Space о будущем Angular, Tiny Conf
Мы провели Twitter Space, обсудив несколько проблем, связанных с последними дополнениями в Angular. Также прошла Angular Tiny Conf с 25 докладами.
Угловой продивер
Угловой продивер
Оригинал этой статьи на турецком языке. ChatGPT используется только для перевода на английский язык.
Мое недавнее углубление в Angular
Мое недавнее углубление в Angular
Недавно я провел некоторое время, изучая фреймворк Angular, и я хотел поделиться своим опытом со всеми вами. Как человек, который любит глубоко...
Освоение Observables и Subjects в Rxjs:
Освоение Observables и Subjects в Rxjs:
Давайте начнем с основ и постепенно перейдем к более продвинутым концепциям в RxJS в Angular
7
7
7 346
3
Перейти к ответу Данный вопрос помечен как решенный

Ответы 3

Ответ принят как подходящий

Проблема в том, что есть две копии Angular в более старом способе настройки Universal и это сбивает с толку ленивую систему загрузки.

Вы можете вручную исправить эту проблему, обновив следующее:

пакет.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');

основной.сервер.тс

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")'
}

Ссылка: исправить ленивую загрузку и bundleDependencies

Этот ответ решил мою проблему, это действительно была проблема, команда Universal работает над выпуском для Angular 8. Я не понимаю, почему этот ответ был отклонен. Большое спасибо @paulws

Gwenael Larmet 14.06.2019 18:23

Для этого я получаю сообщение об ошибке «Ошибка: не удается найти модуль «require(»./server/main»)» после окончательной сборки.

Abijith Ajayan 07.04.2020 21:35

Этот ответ сработал для меня, за исключением последней части. Мне пришлось удалить внешние: { './dist/server/main': 'require("./server/main")' } Спасибо.

user1122002 15.05.2020 23:36
@nguniversal/module-map-ngfactory-loader устарела
azerafati 29.06.2020 08:10

Столкнулся с такой же проблемой, как и с этой: https://github.com/angular/universal/issues/1195. Что сработало для меня, так это применить исправление (https://github.com/angular/universal/blob/master/docs/v8-upgrade-guide.md), но не включать флаг --bundleDependencies all.

Вот базовый рабочий пример использования gCloud для SSR: https://github.com/jrodl3r/ng-fire-универсальный

Короче говоря, я только что удалил enableProdMode(); из server.ts, и он начал работать.


Это было здесь с помощью angular 7, но angular 8 требует изменений кода в файле server.ts, поэтому

  • Я сделал server.bak.ts в качестве резервного файла,
  • установить новый пустой проект с помощью SSR и
  • получил код из него в файл server.ts.

Другие вопросы по теме