Skip to content
This repository has been archived by the owner on Nov 22, 2024. It is now read-only.

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

Closed
dmitriytretyakov opened this issue Mar 7, 2019 · 5 comments · Fixed by angular/angular-cli#13868

Comments

@dmitriytretyakov
Copy link

dmitriytretyakov commented Mar 7, 2019

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",
@dmitriytretyakov
Copy link
Author

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

@dmitriytretyakov
Copy link
Author

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)

@robertisaacBBN
Copy link

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

@alan-agius4
Copy link
Collaborator

Hi all, this is being addressed in angular/angular-cli#13868

vikerman pushed a commit to angular/angular-cli that referenced this issue Mar 11, 2019
…indows in server config

This changes fixes `Error: You must pass in a NgModule or NgModuleFactory to be bootstrapped`.

At the moment the check for absolute path is not correct for windows.

Fixes #13865 and fixes angular/universal#1139
vikerman pushed a commit to angular/angular-cli that referenced this issue Mar 11, 2019
…indows in server config

This changes fixes `Error: You must pass in a NgModule or NgModuleFactory to be bootstrapped`.

At the moment the check for absolute path is not correct for windows.

Fixes #13865 and fixes angular/universal#1139
@angular-automatic-lock-bot
Copy link

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.

@angular-automatic-lock-bot angular-automatic-lock-bot bot locked and limited conversation to collaborators Sep 4, 2019
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
None yet
Projects
None yet
Development

Successfully merging a pull request may close this issue.

3 participants