No NgModule metadata found for 'AppModule' Error in Angular 5 server-side rendering with --env.prod

no ngmodule metadata found for 'appmodule'. angular 6
no ngmodule metadata found for 'appmodule angular 8
error in no ngmodule metadata found for angular 7
error in no ngmodule metadata found for 'appmodule'. angular 7
no ngmodule metadata found for 'undefined' angular 8
error in no ngmodule metadata found for 'appmodule'. ionic 4
error in no ngmodule metadata found for 'appmodule'. angular 6
error in no ngmodule metadata found for lazy loading

I'm trying to upgrade an ASP.NET Core + Angular 4 SPA project from .NET Core 2.0.0/Angular4 to .NET Core 2.0.3/Angular5. I managed to get everything working properly except for the server-side rendering in a production environment, i/e when I publish the app:

An unhandled exception has occurred: No NgModule metadata found for 'AppModule'. Error: No NgModule metadata found for 'AppModule'.

The issue only happens when both of these two conditions are met:

  • Webpack builds the packages using the --env.prod switch
  • The Index.cshtml view file contains the asp-prerender-module parameter, just like in the following example:

    <app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>

If I remove the switch and/or the parameter, the problem disappears (together with SSR).

There's a bunch of other info I can give:

  • It's not something related to IIS, it happens at Kestrel-level.
  • It's not related to the web server machine because I can even reproduce it with locally by manually launching Webpack with the --end.prod switch right before a Debug or Release run.
  • It doesn't seem to have anything to do with the source code, as I can reproduce it even with a single-component sample app with very basic AppModule files and trivial code.
  • The project was running perfectly fine with .NET Core 2.0.0 and Angular 4.3.x.
  • The only major thing I changed in the webpack.config.js file is replacing the AotPlugin with the new, Angular5-specific AngularCompilerPlugin provided by the @ngtools/webpack package: I think that might as well be the cause, as the --env.prod switch makes use of that AOT compiler instead of the JIT one. That, or something related to the .NET SpaServices package - maybe not on-par with the new Angular5 and/or the new AoT compiler?

Sadly, I can't revert to the former AotPlugin because it throws errors as well - which is perfectly understandable, as it's not meant to be used with Angular5.

Software Versions

  • .NET Core 2.0.3
  • Angular 5.0.2
  • @ngtools/webpack 1.8.2 (also tried with 1.8.1 - same outcome)
  • WebPack 2.6.1 (also tried with 2.5.6 - same outcome)

webpack.config.js

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AotPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: [ '.js', '.ts' ] },
        output: {
            filename: '[name].js',
            publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                { test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
                { test: /\.html$/, use: 'html-loader?minimize=false' },
                { test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' }
            ]
        },
        plugins: [new CheckerPlugin()]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = './wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig, {
        entry: { 'main-client': './ClientApp/boot.browser.ts' },
        output: { path: path.join(__dirname, clientBundleOutputDir) },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
            new webpack.optimize.UglifyJsPlugin(),
            new AotPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app.module.browser#AppModule'),
                exclude: ['./**/*.server.ts']
            })
        ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        resolve: { mainFields: ['main'] },
        entry: { 'main-server': './ClientApp/boot.server.ts' },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./ClientApp/dist/vendor-manifest.json'),
                sourceType: 'commonjs2',
                name: './vendor'
            })
        ].concat(isDevBuild ? [] : [
            // Plugins that apply in production builds only
            new AotPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app.module.server#AppModule'),
                exclude: ['./**/*.browser.ts']
            })
        ]),
        output: {
            libraryTarget: 'commonjs',
            path: path.join(__dirname, './ClientApp/dist')
        },
        target: 'node',
        devtool: 'inline-source-map'
    });

    return [clientBundleConfig, serverBundleConfig];
};

The @ngtool/webpack configuration for Angular 5 is somewhat different form Angular 2/4. So, I've changed the webpack.config.js as following,

const path = require('path');
const webpack = require('webpack');
const merge = require('webpack-merge');
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: { modules: false },
        context: __dirname,
        resolve: { extensions: [ '.js', '.ts' ] },
        output: {
            filename: '[name].js',
            publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                { test: /\.ts$/, include: /ClientApp/, use: isDevBuild ? ['awesome-typescript-loader?silent=true', 'angular2-template-loader'] : '@ngtools/webpack' },
                { test: /\.html$/, use: 'html-loader?minimize=false' },
                { test: /\.css$/, use: [ 'to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize' ] },
                { test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000' },
                {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js)$/,
                    loader: '@ngtools/webpack',
                    options: {
                        tsConfigPath: '/tsconfig.json',
                    }
                }
            ]
        },
        plugins: [new CheckerPlugin()]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = './wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig, {
        entry: { 'main-client': './ClientApp/boot.browser.ts' },
        output: { path: path.join(__dirname, clientBundleOutputDir) },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new webpack.SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
                new webpack.optimize.UglifyJsPlugin(),
                new AngularCompilerPlugin({
                    tsConfigPath: './tsconfig.json',
                    entryModule: path.join(__dirname, 'ClientApp/app/app.module.browser#AppModule'),
                    exclude: ['./**/*.server.ts']
                })
        ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        resolve: { mainFields: ['main'] },
        entry: { 'main-server': './ClientApp/boot.server.ts' },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./ClientApp/dist/vendor-manifest.json'),
                sourceType: 'commonjs2',
                name: './vendor'
            })
        ].concat(isDevBuild ? [] : [
            // Plugins that apply in production builds only
            new AngularCompilerPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app.module.server#AppModule'),
                exclude: ['./**/*.browser.ts']
            })
        ]),
        output: {
            libraryTarget: 'commonjs',
            path: path.join(__dirname, './ClientApp/dist')
        },
        target: 'node',
        devtool: 'inline-source-map'
    });

    return [clientBundleConfig, serverBundleConfig];
};

And here is my package.json file,

   {
  "dependencies": {
    "@angular/animations": "^5.0.2",
    "@angular/cdk": "^5.0.0-rc0",
    "@angular/cli": "^1.6.0-beta.2",
    "@angular/common": "^5.0.2",
    "@angular/compiler": "^5.0.2",
    "@angular/compiler-cli": "^5.0.2",
    "@angular/core": "^5.0.2",
    "@angular/forms": "^5.0.2",
    "@angular/http": "^5.0.2",
    "@angular/material": "^5.0.0-rc0",
    "@angular/platform-browser": "^5.0.2",
    "@angular/platform-browser-dynamic": "^5.0.2",
    "@angular/platform-server": "^5.0.2",
    "@angular/router": "^5.0.2",
    "@ngtools/webpack": "^1.8.3",
    "@types/webpack-env": "^1.13.2",
    "angular2-template-loader": "0.6.2",
    "aspnet-prerendering": "^3.0.1",
    "aspnet-webpack": "^2.0.1",
    "awesome-typescript-loader": "^3.4.0",
    "bootstrap": "3.3.7",
    "css": "2.2.1",
    "css-loader": "^0.28.7",
    "es6-shim": "0.35.3",
    "event-source-polyfill": "0.0.12",
    "expose-loader": "0.7.4",
    "extract-text-webpack-plugin": "^3.0.2",
    "file-loader": "^1.1.5",
    "html-loader": "^0.5.1",
    "isomorphic-fetch": "2.2.1",
    "jquery": "3.2.1",
    "json-loader": "^0.5.7",
    "preboot": "^5.1.7",
    "raw-loader": "0.5.1",
    "reflect-metadata": "0.1.10",
    "request": "^2.83.0",
    "rxjs": "^5.5.2",
    "style-loader": "^0.19.0",
    "to-string-loader": "1.1.5",
    "typescript": "^2.6.1",
    "url-loader": "^0.6.2",
    "webpack": "^3.8.1",
    "webpack-hot-middleware": "^2.20.0",
    "webpack-merge": "^4.1.1",
    "zone.js": "^0.8.18"
  },
  "devDependencies": {
    "@types/chai": "^4.0.5",
    "@types/jasmine": "^2.8.2",
    "@types/node": "^8.0.53",
    "chai": "^4.1.2",
    "jasmine-core": "2.8.0",
    "karma": "1.7.1",
    "karma-chai": "0.1.0",
    "karma-chrome-launcher": "2.2.0",
    "karma-cli": "1.0.1",
    "karma-jasmine": "1.1.0",
    "karma-webpack": "2.0.6"
  },
  "name": "aspnetcoreangularspa",
  "private": true,
  "scripts": {
    "test": "karma start ClientApp/test/karma.conf.js"
  },
  "version": "0.0.0"
}

If you still having problems running the solution, please have a look at this repository for a working solution.

Hope it helps :)

Angular 6 upgrade: ERROR in No NgModule metadata found for , Angular 6 upgrade: ERROR in No NgModule metadata found for 'AppModule' #​24123. Closed. Airblader opened this issue on May 25, 2018 · 34 comments. I have a problem with an Angular 2 app that I am building. I have been exercising my copy/paste skills from various locations, and have eliminated all of the build errors, but when I launch it in the


As others suggested, the temporary solution is to remove the SSR (Server Side Rendering). That means opening the Home/Index.cshtml file and change

<app asp-prerender-module="ClientApp/dist/main-server">Loading...</app>

to

<app>Loading...</app>

"No NgModule metadata found for 'AppModule'" after Upgrade to , "No NgModule metadata found for 'AppModule'" after Upgrade to Angular 5.1.0 and AngularCli 1.6.0 #8798. Closed. evolkmann opened this  evolkmann changed the title "No NgModule metadata found for 'AppModule'" after Upgrade to 5.1.0 "No NgModule metadata found for 'AppModule'" after Upgrade to Angular 5.1.0 and AngularCli 1.6.0 Dec 8, 2017


I found your Issue while searching for a solution to my problem described here: https://github.com/aspnet/JavaScriptServices/issues/1388 So i tried your webpack-config and also tried to run the app from the repository, but when i do "dotnet publish" and then run the app i get this error:

Microsoft.AspNetCore.Diagnostics.ExceptionHandlerMiddleware[0]
      An unhandled exception has occurred: No NgModule metadata found for 'AppModule'.
      Error: No NgModule metadata found for 'AppModule'.
    at NgModuleResolver.module.exports.NgModuleResolver.resolve

Angular – All Possible Solutions for 'No NgModule' – Stack 24/7, The error "No NgModule metadata found for 'AppModule'" could be caused by various reason: Moving Angular project folder. Upgrading  Closing as no reproduction was provided, and the original issue seems related to running ngcc and then compiling with View Engine. alxhub closed this Dec 5, 2019 This comment has been minimized.


solution from mak0t0san working for me and ssr still working (angular 5.2.0),

  1. update ngtoolwebpack to 1.10.2
  2. typescript 2.6.2

and change webpack.config.js with that

const path = require('path');
const webpack = require('webpack');
const { DllReferencePlugin, SourceMapDevToolPlugin} = require('webpack');
const merge = require('webpack-merge');
const {AngularCompilerPlugin, PLATFORM} = require('@ngtools/webpack');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const UglifyJsPlugin = require('uglifyjs-webpack-plugin');

module.exports = (env) => {
    // Configuration in common to both client-side and server-side bundles
    const isDevBuild = !(env && env.prod);
    const sharedConfig = {
        stats: {modules: false},
        context: __dirname,
        resolve: {extensions: ['.js', '.ts']},
        output: {
            filename: '[name].js',
            chunkFilename:'[id].chunk.js',
            publicPath: 'dist/' // Webpack dev middleware, if enabled, handles requests for this URL prefix
        },
        module: {
            rules: [
                {test: /\.html$/, use: 'html-loader?minimize=false'},
                {test: /\.css$/, use: ['to-string-loader', isDevBuild ? 'css-loader' : 'css-loader?minimize']},
                {test: /\.(png|jpg|jpeg|gif|svg)$/, use: 'url-loader?limit=25000'},
                {
                    test: /\.(scss)$/,
                    use: [{
                        loader: 'style-loader', // inject CSS to page
                    }, {
                        loader: 'css-loader', // translates CSS into CommonJS modules
                    }, {
                        loader: 'postcss-loader', // Run post css actions
                        options: {
                            plugins: function () { // post css plugins, can be exported to postcss.config.js
                                return [
                                    require('precss'),
                                    require('autoprefixer')
                                ];
                            }
                        }
                    }, {
                        loader: 'sass-loader' // compiles Sass to CSS
                    }]
                }
            ]
        },
        plugins: [new CheckerPlugin()]
    };

    // Configuration for client-side bundle suitable for running in browsers
    const clientBundleOutputDir = './wwwroot/dist';
    const clientBundleConfig = merge(sharedConfig, {
        module:{
            rules:[
                {
                    test: /\.ts$/,
                    use: ['@ngtools/webpack']
                },
            ]
        },
        entry: {'main-client': './ClientApp/boot.browser.ts'},
        output: {path: path.join(__dirname, clientBundleOutputDir)},
        plugins: [
            new DllReferencePlugin({
                context: __dirname,
                manifest: require('./wwwroot/dist/vendor-manifest.json')
            }),
            new AngularCompilerPlugin({
                "mainPath": path.join(__dirname, 'ClientApp/boot.browser.ts'),
                platform: PLATFORM.Browser,
                tsConfigPath: './tsconfig.json',
                entryModule: path.join(__dirname, 'ClientApp/app/app.browser.module#AppModule'),
                sourceMap: true
            })
        ].concat(isDevBuild ? [
            // Plugins that apply in development builds only
            new SourceMapDevToolPlugin({
                filename: '[file].map', // Remove this line if you prefer inline source maps
                moduleFilenameTemplate: path.relative(clientBundleOutputDir, '[resourcePath]') // Point sourcemap entries to the original file locations on disk
            })
        ] : [
            // Plugins that apply in production builds only
          new UglifyJsPlugin({
                sourceMap: true
            })
        ])
    });

    // Configuration for server-side (prerendering) bundle suitable for running in Node
    const serverBundleConfig = merge(sharedConfig, {
        module:{
          rules:[
              { test: /\.ts$/, use: ['awesome-typescript-loader?silent=true', 'angular2-template-loader', 'angular2-router-loader'] },
          ]
        },
        resolve: { mainFields: ['main'] },
        entry: { 'main-server': './ClientApp/boot.server.ts' },
        plugins: [
            new webpack.DllReferencePlugin({
                context: __dirname,
                manifest: require('./ClientApp/dist/vendor-manifest.json'),
                sourceType: 'commonjs2',
                name: './vendor'
            })
        ],
        output: {
            libraryTarget: 'commonjs',
            path: path.join(__dirname, './ClientApp/dist')
        },
        target: 'node',
        devtool: 'inline-source-map'
    });


    return [clientBundleConfig, serverBundleConfig];
};

No NgModule metadata found for 'AppModule' when trying t , When trying to serve admin-pro from IntelliJ - or issue ng serve from command line respectively - I get the error message 'No NgModule metadata found for  Topic: No NgModule metadata found for 'AppModule' when trying to start admin-pro in IntelliJ fixed it Kybeidos pro asked a year ago 0 0


As written at the @MMiebach's link:

Angular 5 includes breaking changes (versus Angular 4) meaning that the code for server-side rendering has to be very different.

Luckily, Microsoft released their new SPA project template for Angular 5. It can be installed with

dotnet new --install Microsoft.DotNet.Web.Spa.ProjectTemplates::2.0.0

After that command dotnet new angular will use the 5th Angular instead of 4th.

By default, server-side rendering is not turned on, but there are instructions how to do it in Docs by MS.

Getting "No NgModule metadata found for 'class{}'." with custom , JIT everything works fine in the browser. Running it with AOT I get following error: Uncaught Error: No NgModule metadata found for 'class{}'. Angular: ERROR in No NgModule metadata found for 'AppModule' When trying to run an angular app I was getting the error: ERROR in No NgModule metadata found for 'AppModule'.


Angular: ERROR in No NgModule metadata found for, ERROR in No NgModule metadata found for 'AppModule'. The error could possibly be becuase of following reasons: There is a statement of the  And when I start the project, I get: ERROR in No NgModule metadata found for 'AppModule'. Damian Gemza staff commented 2 years ago


Error: No NgModule metadata found for 'AppModule', I'm using the groceries demo app ( from NS). – Android. I must say that if I run : tns run android , - I do get it all OK : The problem has started  NgModules help organize an application into cohesive blocks of functionality. An NgModule is a class adorned with the @NgModule decorator function. @NgModule takes a metadata object that tells Angular how to compile and run module code. It identifies the module's own components, directives, and pipes, making some of them public so external


No NgModule metadata found for 'CustomerComponent', I'm Getting Error as No NgModule metadata found for 'CustomerComponent'. when I click on CustLink Master <a [routerLink]="['Supplier/Add']">Supplier</a> <​a  An NgModule is a class marked by the @NgModule decorator. @ NgModule takes a metadata object that describes how to compile a component's template and how to create an injector at runtime. It identifies the module's own components, directives, and pipes, making some of them public, through the exports property, so that external components can