Universal: Error: You must pass in a NgModule or NgModuleFactory to be bootstrapped

Created on 7 Mar 2019  路  5Comments  路  Source: angular/universal

Bug Report

First of all, sorry for my bad english :)

What is the expected behavior?

Correct answer of server.

What is the current behavior?

I create project with universal support three months ago and today i try to update dependencies of my project, all works but not universal, it crashe, because code

let { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(`./dist/server/main`);

in server.ts (https://angular.io/guide/universal) return undefined. I opened this dist/server/main.js and didn't found this variables. I compare code of this file with code in my another project with the same solution and detect that my main file too small: 112 lines of code, when file in another project has 1000+ lines of code.

Content of dist/server/main.js file:

(function(e, a) { for(var i in a) e[i] = a[i]; }(exports, /******/ (function(modules) { // webpackBootstrap
/******/    // The module cache
/******/    var installedModules = {};
/******/
/******/    // The require function
/******/    function __webpack_require__(moduleId) {
/******/
/******/        // Check if module is in cache
/******/        if(installedModules[moduleId]) {
/******/            return installedModules[moduleId].exports;
/******/        }
/******/        // Create a new module (and put it into the cache)
/******/        var module = installedModules[moduleId] = {
/******/            i: moduleId,
/******/            l: false,
/******/            exports: {}
/******/        };
/******/
/******/        // Execute the module function
/******/        modules[moduleId].call(module.exports, module, module.exports, __webpack_require__);
/******/
/******/        // Flag the module as loaded
/******/        module.l = true;
/******/
/******/        // Return the exports of the module
/******/        return module.exports;
/******/    }
/******/
/******/
/******/    // expose the modules object (__webpack_modules__)
/******/    __webpack_require__.m = modules;
/******/
/******/    // expose the module cache
/******/    __webpack_require__.c = installedModules;
/******/
/******/    // define getter function for harmony exports
/******/    __webpack_require__.d = function(exports, name, getter) {
/******/        if(!__webpack_require__.o(exports, name)) {
/******/            Object.defineProperty(exports, name, { enumerable: true, get: getter });
/******/        }
/******/    };
/******/
/******/    // define __esModule on exports
/******/    __webpack_require__.r = function(exports) {
/******/        if(typeof Symbol !== 'undefined' && Symbol.toStringTag) {
/******/            Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
/******/        }
/******/        Object.defineProperty(exports, '__esModule', { value: true });
/******/    };
/******/
/******/    // create a fake namespace object
/******/    // mode & 1: value is a module id, require it
/******/    // mode & 2: merge all properties of value into the ns
/******/    // mode & 4: return value when already ns object
/******/    // mode & 8|1: behave like require
/******/    __webpack_require__.t = function(value, mode) {
/******/        if(mode & 1) value = __webpack_require__(value);
/******/        if(mode & 8) return value;
/******/        if((mode & 4) && typeof value === 'object' && value && value.__esModule) return value;
/******/        var ns = Object.create(null);
/******/        __webpack_require__.r(ns);
/******/        Object.defineProperty(ns, 'default', { enumerable: true, value: value });
/******/        if(mode & 2 && typeof value != 'string') for(var key in value) __webpack_require__.d(ns, key, function(key) { return value[key]; }.bind(null, key));
/******/        return ns;
/******/    };
/******/
/******/    // getDefaultExport function for compatibility with non-harmony modules
/******/    __webpack_require__.n = function(module) {
/******/        var getter = module && module.__esModule ?
/******/            function getDefault() { return module['default']; } :
/******/            function getModuleExports() { return module; };
/******/        __webpack_require__.d(getter, 'a', getter);
/******/        return getter;
/******/    };
/******/
/******/    // Object.prototype.hasOwnProperty.call
/******/    __webpack_require__.o = function(object, property) { return Object.prototype.hasOwnProperty.call(object, property); };
/******/
/******/    // __webpack_public_path__
/******/    __webpack_require__.p = "";
/******/
/******/
/******/    // Load entry module and return exports
/******/    return __webpack_require__(__webpack_require__.s = 0);
/******/ })
/************************************************************************/
/******/ ({

/***/ 0:
/*!**********************************!*\
  !*** multi ./src/main.server.ts ***!
  \**********************************/
/*! no static exports found */
/***/ (function(module, exports, __webpack_require__) {

module.exports = __webpack_require__(/*! D:\Xampp\hosts\my-project\src\main.server.ts */"D:\\Xampp\\hosts\\my-project\\src\\main.server.ts");


/***/ }),

/***/ "D:\\Xampp\\hosts\\my-project\\src\\main.server.ts":
/*!**************************************************************************!*\
  !*** external "D:\\Xampp\\hosts\\my-project\\src\\main.server.ts" ***!
  \**************************************************************************/
/*! no static exports found */
/***/ (function(module, exports) {

module.exports = require("D:\\Xampp\\hosts\\my-project\\src\\main.server.ts");

/***/ })

/******/ })));

I built this with this configuration on angular.json

"server": {
          "builder": "@angular-devkit/build-angular:server",
          "options": {
            "outputPath": "dist/server",
            "main": "src/main.server.ts",
            "tsConfig": "src/tsconfig.server.json",
            "sourceMap": false,
            "stylePreprocessorOptions": {
              "includePaths": [
                "./src/scss"
              ]
            }
          },
          "configurations": {
            "production": {
              "fileReplacements": [
                {
                  "replace": "src/environments/environment.ts",
                  "with": "src/environments/environment.prod.ts"
                }
              ]
            }
          }
        }

My server.ts file

// These are important and needed before anything else
import 'zone.js/dist/zone-node';
import 'reflect-metadata';

import { enableProdMode } from '@angular/core';
var expressStaticGzip = require('express-static-gzip');
import * as express from 'express';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();
// Express server
const app = express();
const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist');

// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';
import { registerLocaleData } from '@angular/common';

var locales = require('./locales.json');

var defaultLocale;
locales.forEach(locale => {
  if(locale.default === true) {
    defaultLocale = locale;
  }
});


// HTML engine using a wrapper to get the correct ngExpressEngine by locale id
app.engine('html', (filePath, options, callback) => {
  options.engine(filePath, { req: options.req, res: options.res }, callback);
});

app.set('view engine', 'html');
app.set('views', join(DIST_FOLDER, 'browser'));

app.route('/sitemap.xml')
  .get((req, res) => {
    res.redirect(301, 'another_domain/sitemap');
  });

// Server static files from /browser
app.get('*.*', expressStaticGzip(join(DIST_FOLDER, 'browser'), {
  enableBrotli: true,
  orderPreference: ['br']
}));

// Locale endpoints
locales.forEach(locale => {
  if(locale.default !== true) {
    app.get(`${locale.baseHref}(/*)?`, (req, res) => {
      let { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(`./dist/server${locale.baseHref}/main`);
      res.render(join(DIST_FOLDER, 'browser', locale.baseHref.substr(1), 'index.html'), { req, res, engine: ngExpressEngine({
          bootstrap: AppServerModuleNgFactory,
          providers: [
            provideModuleMap(LAZY_MODULE_MAP)
          ]
        }) });
    });
  }
});

locales.forEach(locale => {
  registerLocaleData(require(`@angular/common/locales/${locale.id}`).default, locale.id);
});

// Redirect to default locale keeping requested path
app.get('*', (req, res) => {
  let { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require(`./dist/server${defaultLocale.baseHref}/main`);
  res.render(join(DIST_FOLDER, 'browser', defaultLocale.baseHref.substr(1), 'index.html'), { req, res, engine: ngExpressEngine({
      bootstrap: AppServerModuleNgFactory,
      providers: [
        provideModuleMap(LAZY_MODULE_MAP)
      ]
    }) });
  // res.redirect(`${defaultLocale.baseHref ? defaultLocale.baseHref : '/'}${req.url}`.replace(/\/+/g, '/'));
});

// Start up the Node server
app.listen(PORT, () => {
  console.log(`Node server listening on http://localhost:${PORT}`);
});

What modules are related to this issue?

- [ ] aspnetcore-engine
- [ ] common
- [*] express-engine
- [ ] hapi-engine
- [*] module-map-ngfactory-loader

Minimal reproduction with instructions:

I don't know, all works, but broken when update npm packages.

Environment:

Angular CLI: 7.3.5
Node: 10.12.0
OS: win32 x64
Angular: 7.2.8
... animations, common, compiler, compiler-cli, core, forms
... http, language-service, platform-browser
... platform-browser-dynamic, platform-server, router
... service-worker

Package Version

@angular-devkit/architect 0.13.5
@angular-devkit/build-angular 0.13.5
@angular-devkit/build-optimizer 0.13.5
@angular-devkit/build-webpack 0.13.5
@angular-devkit/core 7.3.5
@angular-devkit/schematics 7.3.5
@angular/cli 7.3.5
@angular/pwa 0.13.5
@ngtools/webpack 7.3.5
@schematics/angular 7.3.5
@schematics/update 0.13.5
rxjs 6.4.0
typescript 3.2.4
webpack 4.29.0

```

Is there anything else we should know?

I didn't change my code, only update packages.
Changelog of packages (old works correctly):
Old:
"@angular/animations": "~7.2.7",
"@angular/common": "~7.2.7",
"@angular/compiler": "~7.2.7",
"@angular/core": "~7.2.7",
"@angular/forms": "~7.2.7",
"@angular/http": "~7.2.7",
"@angular/platform-browser": "~7.2.7",
"@angular/platform-browser-dynamic": "~7.2.7",
"@angular/platform-server": "^7.2.7",
"@angular/pwa": "^0.11.3",
"@angular/router": "~7.2.7",
"@angular/service-worker": "~7.2.7",
"@nguniversal/express-engine": "^7.0.2",
"@nguniversal/module-map-ngfactory-loader": "^7.0.2",
"bootstrap": "^4.1.3",
"core-js": "^2.6.1",
New:
"@angular/animations": "~7.2.8",
"@angular/common": "~7.2.8",
"@angular/compiler": "~7.2.8",
"@angular/core": "~7.2.8",
"@angular/forms": "~7.2.8",
"@angular/http": "~7.2.8",
"@angular/platform-browser": "~7.2.8",
"@angular/platform-browser-dynamic": "~7.2.8",
"@angular/platform-server": "^7.2.8",
"@angular/pwa": "^0.13.5",
"@angular/router": "~7.2.8",
"@angular/service-worker": "~7.2.8",
"@nguniversal/express-engine": "^7.1.1",
"@nguniversal/module-map-ngfactory-loader": "^7.1.1",
"bootstrap": "^4.3.1",
"core-js": "^2.6.5",

Most helpful comment

this happens even in empty project
you can reproduce just by using

ng new test-ssr
cd test-ssr
ng add @nguniversal/express-engine --clientProject test-ssr
npm run build:ssr
npm run serve:ssr

All 5 comments

i try to commect all code in server.ts and console.log variable AppServerModuleNgFactory from /dist/server/main.js, it returns undefined.

Update: i update all packages manually and detect, that problem appears when i updated @angular-devkit/build-angular (from "~0.10.0" to 0.13.5)

this happens even in empty project
you can reproduce just by using

ng new test-ssr
cd test-ssr
ng add @nguniversal/express-engine --clientProject test-ssr
npm run build:ssr
npm run serve:ssr

Hi all, this is being addressed in https://github.com/angular/angular-cli/pull/13868

This issue has been automatically locked due to inactivity.
Please file a new issue if you are encountering a similar or related problem.

Read more about our automatic conversation locking policy.

_This action has been performed automatically by a bot._

Was this page helpful?
0 / 5 - 0 ratings

Related issues

ahmedwerpx picture ahmedwerpx  路  4Comments

mmeylan picture mmeylan  路  4Comments

jeffwhelpley picture jeffwhelpley  路  6Comments

benrondeau picture benrondeau  路  5Comments

PatrickJS picture PatrickJS  路  5Comments