angular: Angular 8 and unversal lazy-loading error TypeError: Cannot read property 'call' of undefined

🐞 bug report

Affected Package

The issue is caused by package @nguniversal @angular

Is this a regression?

Yes, the previous version in which this bug was not present was: Angular 7

Description

This error appears in server-side rendering

🔬 Minimal Reproduction

I think we can reproduce this error with minimal project using lazy-loader and universal with angular 8. I made the mistake of switching to “lazy-loading” and “angular 8” at the same time.

🔥 Exception or Error



ERROR Error: Uncaught (in promise): TypeError: Cannot read property 'call' of undefined
TypeError: Cannot read property 'call' of undefined
    at __webpack_require__ (dist/server.js:138240:30)
    at Function.requireEnsure [as e] (dist/server.js:138259:25)
    at ɵ0 (dist/server.js:140556:38)
    at RouterConfigLoader.loadModuleFactory (dist/server.js:220632:39)
    at RouterConfigLoader.load (dist/server.js:220617:35)
    at MergeMapSubscriber.project (dist/server.js:219620:47)
    at MergeMapSubscriber._tryNext (dist/server.js:37067:27)
    at MergeMapSubscriber._next (dist/server.js:37057:18)
    at MergeMapSubscriber.Subscriber.next (dist/server.js:33616:18)
    at Observable._subscribe (dist/server.js:35628:24)
    at resolvePromise (dist/server.js:1008:31)
    at resolvePromise (dist/server.js:965:17)
    at dist/server.js:1069:17
    at ZoneDelegate.invokeTask (dist/server.js:579:31)
    at Object.onInvokeTask (dist/server.js:28551:33)
    at ZoneDelegate.invokeTask (dist/server.js:578:60)
    at Zone.runTask (dist/server.js:351:47)
    at drainMicroTaskQueue (dist/server.js:757:35)
    at ZoneTask.invokeTask (dist/server.js:658:21)
    at Server.ZoneTask.invoke (dist/server.js:643:48) {
  rejection: TypeError: Cannot read property 'call' of undefined
      at __webpack_require__ (dist/server.js:138240:30)
      at Function.requireEnsure [as e] (dist/server.js:138259:25)
      at ɵ0 (dist/server.js:140556:38)
      at RouterConfigLoader.loadModuleFactory (dist/server.js:220632:39)
      at RouterConfigLoader.load (dist/server.js:220617:35)
      at MergeMapSubscriber.project (dist/server.js:219620:47)
      at MergeMapSubscriber._tryNext (dist/server.js:37067:27)
      at MergeMapSubscriber._next (dist/server.js:37057:18)
      at MergeMapSubscriber.Subscriber.next (dist/server.js:33616:18)
      at Observable._subscribe (dist/server.js:35628:24),
  promise: ZoneAwarePromise [Promise] {
    __zone_symbol__state: 0,
    __zone_symbol__value: TypeError: Cannot read property 'call' of undefined
        at __webpack_require__ (dist/server.js:138240:30)
        at Function.requireEnsure [as e] (dist/server.js:138259:25)
        at ɵ0 (dist/server.js:140556:38)
        at RouterConfigLoader.loadModuleFactory (dist/server.js:220632:39)
        at RouterConfigLoader.load (dist/server.js:220617:35)
        at MergeMapSubscriber.project (dist/server.js:219620:47)
        at MergeMapSubscriber._tryNext (dist/server.js:37067:27)
        at MergeMapSubscriber._next (dist/server.js:37057:18)
        at MergeMapSubscriber.Subscriber.next (dist/server.js:33616:18)
        at Observable._subscribe (dist/server.js:35628:24)
  },
  zone: Zone {
    _parent: Zone {
      _parent: null,
      _name: '<root>',
      _properties: {},
      _zoneDelegate: [ZoneDelegate]
    },
    _name: 'angular',
    _properties: { isAngularZone: true },
    _zoneDelegate: ZoneDelegate {
      _taskCounts: [Object],
      zone: [Circular],
      _parentDelegate: [ZoneDelegate],
      _forkZS: null,
      _forkDlgt: null,
      _forkCurrZone: [Zone],
      _interceptZS: null,
      _interceptDlgt: null,
      _interceptCurrZone: [Zone],
      _invokeZS: [Object],
      _invokeDlgt: [ZoneDelegate],
      _invokeCurrZone: [Circular],
      _handleErrorZS: [Object],
      _handleErrorDlgt: [ZoneDelegate],
      _handleErrorCurrZone: [Circular],
      _scheduleTaskZS: [Object],
      _scheduleTaskDlgt: [ZoneDelegate],
      _scheduleTaskCurrZone: [Circular],
      _invokeTaskZS: [Object],
      _invokeTaskDlgt: [ZoneDelegate],
      _invokeTaskCurrZone: [Circular],
      _cancelTaskZS: [Object],
      _cancelTaskDlgt: [ZoneDelegate],
      _cancelTaskCurrZone: [Circular],
      _hasTaskZS: [Object],
      _hasTaskDlgt: [ZoneDelegate],
      _hasTaskDlgtOwner: [Circular],
      _hasTaskCurrZone: [Circular]
    }
  },
  task: ZoneTask {
    _zone: Zone {
      _parent: [Zone],
      _name: 'angular',
      _properties: [Object],
      _zoneDelegate: [ZoneDelegate]
    },
    runCount: 0,
    _zoneDelegates: null,
    _state: 'notScheduled',
    type: 'microTask',
    source: 'Promise.then',
    data: ZoneAwarePromise [Promise] {
      __zone_symbol__state: 0,
      __zone_symbol__value: TypeError: Cannot read property 'call' of undefined
          at __webpack_require__ (dist/server.js:138240:30)
          at Function.requireEnsure [as e] (dist/server.js:138259:25)
          at ɵ0 (dist/server.js:140556:38)
          at RouterConfigLoader.loadModuleFactory (dist/server.js:220632:39)
          at RouterConfigLoader.load (dist/server.js:220617:35)
          at MergeMapSubscriber.project (dist/server.js:219620:47)
          at MergeMapSubscriber._tryNext (dist/server.js:37067:27)
          at MergeMapSubscriber._next (dist/server.js:37057:18)
          at MergeMapSubscriber.Subscriber.next (dist/server.js:33616:18)
          at Observable._subscribe (dist/server.js:35628:24)
    },
    scheduleFn: undefined,
    cancelFn: undefined,
    callback: [Function],
    invoke: [Function]
  }
}

🌍 Your Environment

Angular Version:




Angular CLI: 8.0.3
Node: 12.3.1
OS: linux x64
Angular: 8.0.1
... animations, cdk, common, compiler, compiler-cli, core, forms
... language-service, material, material-moment-adapter
... platform-browser, platform-browser-dynamic, platform-server
... router, service-worker

Package                                    Version
--------------------------------------------------------------------
@angular-devkit/architect                  0.800.3
@angular-devkit/build-angular              0.800.3
@angular-devkit/build-optimizer            0.800.3
@angular-devkit/build-webpack              0.800.3
@angular-devkit/core                       8.0.3
@angular-devkit/schematics                 8.0.3
@angular/cli                               8.0.3
@angular/pwa                               0.800.3
@ngtools/webpack                           8.0.3
@nguniversal/aspnetcore-engine             7.1.1
@nguniversal/common                        7.1.1
@nguniversal/express-engine                7.0.2
@nguniversal/module-map-ngfactory-loader   7.0.2
@schematics/angular                        8.0.3
@schematics/update                         0.800.3
rxjs                                       6.5.2
typescript                                 3.4.5
webpack                                    4.30.0

Anything else relevant?

🌍 server.ts


import 'zone.js/dist/zone-node';
import 'reflect-metadata';
import { enableProdMode } from '@angular/core';
// Express Engine
import { ngExpressEngine } from '@nguniversal/express-engine';
// Import module map for lazy loading
import { provideModuleMap } from '@nguniversal/module-map-ngfactory-loader';

import * as express from 'express';
import * as cookieparser from 'cookie-parser';
import { join } from 'path';

// Faster server renders w/ Prod mode (dev mode never needed)
enableProdMode();

// Express server
const app = express();
app.use(cookieparser());

import * as xhr2 from 'xhr2';
xhr2.prototype._restrictedHeaders.cookie = false;

const PORT = process.env.PORT || 4000;
const DIST_FOLDER = join(process.cwd(), 'dist/browser');

// * NOTE :: leave this as require() since this file is built Dynamically from webpack
const { AppServerModuleNgFactory, LAZY_MODULE_MAP } = require('./dist/server/main');

// Our Universal express-engine (found @ https://github.com/angular/universal/tree/master/modules/express-engine)
app.engine('html', ngExpressEngine({
    bootstrap: AppServerModuleNgFactory,
    providers: [
        provideModuleMap(LAZY_MODULE_MAP)
    ]
}));

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

// Example Express Rest API endpoints
// app.get('/api/**', (req, res) => { });
// Server static files from /browser
app.get('*.*', express.static(DIST_FOLDER, {
    maxAge: '1y'
}));

// All regular routes use the Universal engine
app.get('*', (req, res) =>
{
    res.render('index', { req, res });
});

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

🌍 main.server.ts


import { enableProdMode } from '@angular/core';

import { environment } from './environments/environment';

if (environment.production) {
  enableProdMode();
}

export { AppServerModule } from './app/app.server.module';

🌍 webpack.server.config


onst path = require('path');
const webpack = require('webpack');

module.exports = {
    mode: 'none',
    entry: {
        // This is our Express server for Dynamic universal
        server: './server.ts'
    },
    target: 'node',
    resolve: { extensions: ['.ts', '.js'] },
    optimization: {
        minimize: false
    },
    output: {
        // Puts the output at the root of the dist folder
        path: path.join(__dirname, 'dist'),
        filename: '[name].js'
    },
    module: {
        rules: [
            { test: /\.ts$/, loader: 'ts-loader' },
            {
                // Mark files inside `@angular/core` as using SystemJS style dynamic imports.
                // Removing this will cause deprecation warnings to appear.
                test: /(\\|\/)@angular(\\|\/)core(\\|\/).+\.js$/,
                parser: { system: true },
            },
        ]
    },
    plugins: [/*
        new webpack.ContextReplacementPlugin(
            // fixes WARNING Critical dependency: the request of a dependency is an expression
            /(.+)?angular(\\|\/)core(.+)?/,
            path.join(__dirname, 'src'), // location of your src
            {} // a map of your routes
        ),
        new webpack.ContextReplacementPlugin(
            // fixes WARNING Critical dependency: the request of a dependency is an expression
            /(.+)?express(\\|\/)(.+)?/,
            path.join(__dirname, 'src'),
            {}
        )*/
    ]
};

🌍 app.server.module.ts



import { NgModule } from '@angular/core';

import { ServerModule, ServerTransferStateModule } from ‘@angular/platform-server’; import { ModuleMapLoaderModule } from ‘@nguniversal/module-map-ngfactory-loader’;

import { AppModule } from ‘./app.module’; import { AppComponent } from ‘@component/app.component’;

@NgModule({ imports: [ AppModule, ServerModule, ServerTransferStateModule, ModuleMapLoaderModule ], bootstrap: [AppComponent], }) export class AppServerModule {}

Thank you

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Reactions: 4
  • Comments: 15 (2 by maintainers)

Commits related to this issue

Most upvoted comments

I had the same issue and it was solved when I added "module": “commonjs” in tsconfig.server.json.

yes - The upgrade guide at https://github.com/angular/universal/blob/master/docs/v8-upgrade-guide.md addresses this exact issue. Please follow the instructions there to upgrade.

@ponkys Cheers mate! Adding "module": "commonjs"in tsconfig.server.json solved the issue for me too.

+1, reproduced in a very simple repo at the linked commit, no fix to offer though: https://github.com/Manningham/homepage-angular/commit/2dead1c636dbf7d8613bab2c182bc14742afb05a

I confirm that the issue appears when using lazy-load. When loadChildren: function is replaced by loadChildren: string, which (I think) disables lazy-loading, we don’t have this issue.