Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Angular 5 upgrade can't get lazy loading to work #1936

Closed
Bjeaurn opened this issue Dec 8, 2017 · 52 comments
Closed

Angular 5 upgrade can't get lazy loading to work #1936

Bjeaurn opened this issue Dec 8, 2017 · 52 comments

Comments

@Bjeaurn
Copy link

Bjeaurn commented Dec 8, 2017

Note: for support questions, please use one of these channels: Chat: AngularClass.slack or Twitter: @AngularClass

  • I'm submitting a ...
    [x] bug report
    [ ] feature request
    [ ] question about the decisions made in the repository

  • What is the current behavior?
    I've managed to upgrade most of the repository to reflect this one, and get a compiling built out of it. When I try to get lazyloading to work in the way it used to, I run into multiple issues that break the app.

  • If the current behavior is a bug, please provide the steps to reproduce and if possible a minimal demo of the problem
    package.json

dependencies: [
    "@angular/animations": "^5.0.5",
    "@angular/common": "^5.0.5",
    "@angular/compiler": "^5.0.5",
    "@angular/core": "^5.0.5",
    "@angular/forms": "^5.0.5",
    "@angular/http": "^5.0.5",
    "@angular/platform-browser": "^5.0.5",
    "@angular/platform-browser-dynamic": "^5.0.5",
    "@angular/platform-server": "^5.0.5",
    "@angular/router": "^5.0.5",
    "@angularclass/hmr": "^2.1.3",
    "@angularclass/hmr-loader": "~3.0.2",
    ............
],
devDependencies: [
   "@angular-devkit/build-optimizer": "^0.0.32",
    "@angular/compiler-cli": "^5.0.5",
    "@ngtools/webpack": "^1.8.0",
    .......
]

webpack.common.config

const webpack = require('webpack');
const helpers = require('./helpers');

/*
 * Webpack Plugins
 */
// problem with copy-webpack-plugin
var ExtractTextPlugin = require('extract-text-webpack-plugin');
const AssetsPlugin = require('assets-webpack-plugin');
const NormalModuleReplacementPlugin = require('webpack/lib/NormalModuleReplacementPlugin');
const ContextReplacementPlugin = require('webpack/lib/ContextReplacementPlugin');
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const CopyWebpackPlugin = require('copy-webpack-plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
const HtmlElementsPlugin = require('./html-elements-plugin');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const InlineManifestWebpackPlugin = require('inline-manifest-webpack-plugin');
const LoaderOptionsPlugin = require('webpack/lib/LoaderOptionsPlugin');
const ScriptExtHtmlWebpackPlugin = require('script-ext-html-webpack-plugin');
// const ngcWebpack = require('ngc-webpack'); --> Replaced by @ngtools/webpack
const AngularCompilerPlugin = require('@ngtools/webpack').AngularCompilerPlugin;
const MergeJsonWebpackPlugin = require('merge-jsons-webpack-plugin');
const WriteFilePlugin = require('write-file-webpack-plugin');
/*
 * Webpack Constants
 */
const HMR = helpers.hasProcessFlag('hot');
const AOT = process.env.BUILD_AOT || helpers.hasNpmFlag('aot');

/*
 * Webpack configuration
 *
 * See: http://webpack.github.io/docs/configuration.html#cli
 */
module.exports = function (options) {

  const METADATA = {
    baseUrl: '/',
    title: options.title,
    isDevServer: helpers.isWebpackDevServer(),
    HMR: HMR
  };

  console.log('webpack common - METADATA.title: ', METADATA.title);

    const isProd = options.env === 'production';

    return {

        /**
         * Cache generated modules and chunks to improve performance for multiple incremental builds.
         * This is enabled by default in watch mode.
         * You can pass false to disable it.
         *
         * See: http://webpack.github.io/docs/configuration.html#cache
         */
        //cache: false,

        /**
         * The entry point for the bundle
         * Our Angular.js app
         *
         * See: http://webpack.github.io/docs/configuration.html#entry
         */
        entry: {

            'polyfills': './src/polyfills.browser.ts',
            'main':      AOT ? './src/main.browser.aot.ts' :
                './src/main.browser.ts'

        },

        /**
         * Options affecting the resolving of modules.
         *
         * See: http://webpack.github.io/docs/configuration.html#resolve
         */
        resolve: {

            /**
             * An array of extensions that should be used to resolve modules.
             *
             * See: http://webpack.github.io/docs/configuration.html#resolve-extensions
             */
            extensions: ['.ts', '.js', '.json'],

            /**
             * An array of directory names to be resolved to the current directory
             */
            modules: [helpers.root('src'), helpers.root('node_modules')],

            alias: {
                'jquery': __dirname + '/../node_modules/jquery/dist/jquery.js'
            }

        },

        /**
         * Options affecting the normal modules.
         *
         * See: http://webpack.github.io/docs/configuration.html#module
         */
        module: {

            rules: [

                 // ...ngcWebpackConfig.loaders,
                {
                    test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                    loaders:
                        ['@ngtools/webpack', 'angular-router-loader?genDir=compiled&aot=false']
                },
                /**
                 * Json loader support for *.json files.
                 *
                 * See: https://github.com/webpack/json-loader
                 */
                {
                    test: /\.json$/,
                    use: 'json-loader'
                },
                
                /**
                 * To string and css loader support for *.css files (from Angular components)
                 * Returns file content as string
                 *
                 */
                {
                    test: /\.css$/,
                    use: ['to-string-loader', 'css-loader'],
                    exclude: [helpers.root('src', 'styles')]
                },

                /**
                 * To string and sass loader support for *.scss files (from Angular components)
                 * Returns compiled css content as string
                 *
                 */
                {
                    test: /\.scss$/,
                    include: helpers.root('src', 'app'),
                    use: ['raw-loader', 'sass-loader']
                    // use: ['to-string-loader', 'css-loader', 'sass-loader'],
                    // exclude: [helpers.root('src', 'styles')]
                },

                /**
                 * Raw loader support for *.html
                 * Returns file content as string
                 *
                 * See: https://github.com/webpack/raw-loader
                 */
                {
                    test: /\.html$/,
                    use: 'raw-loader',
                    exclude: [helpers.root('src/index.html')]
                },

                /**
                 * File loader for supporting images, for example, in CSS files.
                 */
                {
                    test: /\.(jpg|png|gif)$/,
                    use: 'file-loader'
                },

                /* See https://github.com/gowravshekar/font-awesome-webpack
                 */
                { test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "url-loader?limit=10000&mimetype=application/font-woff" },
                { test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/, loader: "file-loader" }

            ],

        },

        /**
         * Add additional plugins to the compiler.
         *
         * See: http://webpack.github.io/docs/configuration.html#plugins
         */
        plugins: [

            new webpack.ProvidePlugin({
                jQuery: 'jquery',
                $: 'jquery',
                jquery: 'jquery'
            }),

            new AssetsPlugin({
                path: helpers.root('dist'),
                filename: 'webpack-assets.json',
                prettyPrint: true
            }),

            /**
             * Plugin: ForkCheckerPlugin
             * Description: Do type checking in a separate process, so webpack don't need to wait.
             *
             * See: https://github.com/s-panferov/awesome-typescript-loader#forkchecker-boolean-defaultfalse
             */
            new CheckerPlugin(),
            /**
             * Plugin: CommonsChunkPlugin
             * Description: Shares common code between the pages.
             * It identifies common modules and put them into a commons chunk.
             *
             * See: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
             * See: https://github.com/webpack/docs/wiki/optimization#multi-page-app
             */
            new CommonsChunkPlugin({
                name: 'polyfills',
                chunks: ['polyfills']
            }),
            /**
             * This enables tree shaking of the vendor modules
             */
            new CommonsChunkPlugin({
                name: 'vendor',
                chunks: ['main'],
                minChunks: module => /node_modules/.test(module.resource)
            }),
            /**
             * Specify the correct order the scripts will be injected in
             */
            new CommonsChunkPlugin({
                name: ['polyfills', 'vendor'].reverse()
            }),
            new CommonsChunkPlugin({
                name: ['manifest'],
                minChunks: Infinity,
            }),

            /**
             * Plugin: ContextReplacementPlugin
             * Description: Provides context to Angular's use of System.import
             *
             * See: https://webpack.github.io/docs/list-of-plugins.html#contextreplacementplugin
             * See: https://github.com/angular/angular/issues/11580
             */
            new ContextReplacementPlugin(
                /**
                 * The (\\|\/) piece accounts for path separators in *nix and Windows
                 */
                /angular(\\|\/)core(\\|\/)@angular/,
                helpers.root('src'), // location of your src
                {
                    /**
                     * Your Angular Async Route paths relative to this root directory
                     */
                }
            ),

            /**
             * Plugin: HtmlWebpackPlugin
             * Description: Simplifies creation of HTML files to serve your webpack bundles.
             * This is especially useful for webpack bundles that include a hash in the filename
             * which changes every compilation.
             *
             * See: https://github.com/ampedandwired/html-webpack-plugin
             */
            new HtmlWebpackPlugin({
                template: 'src/index.html',
                title: METADATA.title,
                chunksSortMode: 'dependency',
                metadata: METADATA,
                inject: 'head'
            }),

            /**
             * Plugin: ScriptExtHtmlWebpackPlugin
             * Description: Enhances html-webpack-plugin functionality
             * with different deployment options for your scripts including:
             *
             * See: https://github.com/numical/script-ext-html-webpack-plugin
             */
            new ScriptExtHtmlWebpackPlugin({
                defaultAttribute: 'defer'
            }),

            /**
             * Plugin: HtmlElementsPlugin
             * Description: Generate html tags based on javascript maps.
             *
             * If a publicPath is set in the webpack output configuration, it will be automatically added to
             * href attributes, you can disable that by adding a "=href": false property.
             * You can also enable it to other attribute by settings "=attName": true.
             *
             * The configuration supplied is map between a location (key) and an element definition object (value)
             * The location (key) is then exported to the template under then htmlElements property in webpack configuration.
             *
             * Example:
             *  Adding this plugin configuration
             *  new HtmlElementsPlugin({
       *    headTags: { ... }
       *  })
             *
             *  Means we can use it in the template like this:
             *  <%= webpackConfig.htmlElements.headTags %>
             *
             * Dependencies: HtmlWebpackPlugin
             */
            new HtmlElementsPlugin({
                headTags: require('./head-config.common')
            }),

            /**
             * Plugin LoaderOptionsPlugin (experimental)
             *
             * See: https://gist.github.com/sokra/27b24881210b56bbaff7
             */
            new LoaderOptionsPlugin({}),

            // new ngcWebpack.NgcWebpackPlugin(ngcWebpackConfig.plugin),

            new AngularCompilerPlugin({
                tsConfigPath: METADATA.tsConfigPath,
                // entryModule: entryModule,
                mainPath: entry.main,
                sourceMap: true,
                skipCodeGeneration: true,

            }),

            /**
             * Plugin: InlineManifestWebpackPlugin
             * Inline Webpack's manifest.js in index.html
             *
             * https://github.com/szrenwei/inline-manifest-webpack-plugin
             */
            new InlineManifestWebpackPlugin(),


                /**
                 * Plugin: CopyWebpackPlugin
                 * Description: Copy files and directories in webpack.
                 *
                 * Copies project static assets.
                 *
                 * See: https://www.npmjs.com/package/copy-webpack-plugin
                 */
                new CopyWebpackPlugin([
                        { from: 'src/assets', to: '.' },
                        { from: 'src/meta'}
                    ],
                    isProd ? { ignore: [ 'mock-data/**/*' ] } : undefined
                )
            ],

        /**
         * Include polyfills or mocks for various node stuff
         * Description: Node configuration
         *
         * See: https://webpack.github.io/docs/configuration.html#node
         */
        node: {
            global: true,
            crypto: 'empty',
            process: true,
            module: false,
            clearImmediate: false,
            setImmediate: false
        }

    };
}

app.routes, being loaded through app.module using RootModule.forRoot(appRoutes)

import { Routes } from '@angular/router';
import { PATH_NO_CONTENT } from '../error/error.routes';

export const APP_ROUTES: Routes = [
    { path: 'help', loadChildren: '../help/help.module#HelpModule'},
    { path: 'error', loadChildren: '../error/error.module#ErrorModule'},
    { path: 'demo', loadChildren: '../demo/demo.module#DemoModule' },
    { path: '**', redirectTo: 'error/' + PATH_NO_CONTENT }
];

This one gives me the Error: Cannot find module '../demo/demo.module'.

If I switch the lazy loading loadChildren: to loadChildren: () => HelpModule, it doesn't compile.

  • What is the expected behavior?
    Lazy loading to work, given either of the two solutions.

  • Please tell us about your environment:

  • Angular version: 5.0.5,
  • Browser: all.
  • Other information (e.g. detailed explanation, stacktraces, related issues, suggestions how to fix, links for us to have context, eg. stackoverflow, gitter, etc)

I'll add as I go...

@WillooWisp
Copy link

I experience similar problems, where lazy loading fails when loading angular application.

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 8, 2017

@WillooWisp do you have your app compiling properly through webpack?

What I did in order to get it to work is change the routes to:

{ path: 'help', loadChildren: () => HelpModule }

That causes a compile error, but when you trigger a recompile it works fine. Does this work for you?

To clarify; I'm stuck at this exact point myself, but at least this way I got to see if the app worked fine after the lazyloading issue was fixed. Would like to see if the same works for you, cause we may have a bug in the way Lazyloading modules are being loaded.

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 11, 2017

After some testing and comparing with other issues; I've got Lazyloading to work after disabling the DLL bundling (vendor & polyfills).

I'd like to get something comparable back again, that'll still be a bit of a puzzle. Anyone who got Lazyloading with separation of vendor and polyfills?

@WillooWisp
Copy link

@Bjeaurn Yes it works for me as well when I use a function (lambda expression) instead of a string for loadChildren. But is that the same thing, will it still be separated into its own chunk and get lazy loaded now when an import of the module exists in the app routing module?

@WillooWisp
Copy link

@Bjeaurn It is strange however that it actually works sometimes with the string syntax "login.module#LoginModule" when rebuilding with webpack and sometimes it does not. It always succeeds during build but sometimes failes during runtime load of modules.

@WillooWisp
Copy link

@Bjeaurn What exactly did you change or remove from the webpack configuration to disable the separation of vendor and polyfills in order to get it to work?

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 13, 2017

I didn't necessarily disable the separation, I simply removed the DllBundlesPlugin and all relevant instructions for it, and from there the regular lazyloading convention as described by Angular (e.g.: loadChildren: '../path/to/login.module#LoginModule') worked.

Seeing as the project was based upon this angular-starter and had grown over time, there we're still some artifacts from past times. I guess DllBundlesPlugin may have been one of them as I don't recall seeing it in this repo anymore either.

@WillooWisp
Copy link

I understand, but I no longer have that DllBundlesPlugin after merging in the latest changes from master in this repo, but still experience the lazy loading problems using the string/path syntax.

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 13, 2017

What's the error you receive when you try to use the Angular convention for lazyloading? And do you have the opportunity to share your webpack.common.js and webpack.dev.js?

@WillooWisp
Copy link

global.error-handler.ts:43 Error: Uncaught (in promise): Error: Cannot find module './login/login.module#LoginModule'.
Error: Cannot find module './login/login.module#LoginModule'.
at eval (eval at ./$$_lazy_route_resource lazy recursive (main.bundle.js:7), :5:9)

@WillooWisp
Copy link

WillooWisp commented Dec 13, 2017

The strange thing is that some modules work and some does not to lazy load with the string path syntax, but they did work to load this way before. And it varies from time to time when doing a rebuild.

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 18, 2017

I think the ./login/login.module#LoginModule' should be login/login.module#LoginModule. Think you only use relative paths when you need to go up the folder tree.

@Bjeaurn
Copy link
Author

Bjeaurn commented Dec 20, 2017

@WillooWisp Have you made any progress in this? If so, can you summarize the actions that helped you. Maybe link to any posts and/or comments that helped.

I think we can recommend this issue gets closed; as the main angular-starter by default works fine with AOT and Lazyloading, it's only in the upgrade progress where things break.

@johanchouquet
Copy link

I experienced the same issue (new project created with CLI 1.6.0 && Angular 5.1.1).

My routes were simple:

  • one redirect to a dashboard which in turn was lazy loaded => the string notation worked fine.
  • BUT: in my main component, I putted a routerLink directive on a link to another lazy-loaded route, and this was KO with the string notation. I tried the () => NamedModule, and this worked fine.

@johanchouquet
Copy link

One more thing: ng build works fine, but ng build --prod outputs "Error during template compile of 'AppModule'"

@WillooWisp
Copy link

@Bjeaurn Lazy loading still does not work as before, and I have made sure I have the correct webpack configuration according to latest on master. I have tried both with "./" and without it in the beginning of the string path to the module without success, so that does not work as it used to. Using the () => Module syntax works however, but is that the exact same thing? I mean will the behavior be the exact same thing regardless of how you import the lazy loaded module, that is importing the Module explicitly and lazy loading it with the () => Module syntax, compared to not importing the Module and using the string path syntax in loadChildren?

@WillooWisp
Copy link

@Bjeaurn I still get this also, "ERROR in TypeError: Cannot read property 'loadChildren' of undefined", upon first compilation using "start:hmr", but a recompile solves this. A little frustrating though, did you work this out?

@WillooWisp
Copy link

@Bjeaurn loadChildren with a function () => Module, does not work with AOT. And according to this, angular/angular-cli#4192, importing the Module that way breaks lazy loading from its own chunk.
For some reason lazy loading with string path syntax works for smaller projects, but not for larger ones, or it might be loading modules that in turn have lazy loaded modules in their routes and so on.

@WillooWisp
Copy link

I finally found the problem. I am using conditionals in my app module to include different routes depending on some variable, which has worked perfectly before, but doing that with latest configuration causes the chunks to not get generated for lazy loaded modules.

@Bjeaurn
Copy link
Author

Bjeaurn commented Jan 3, 2018

So to summarize, you are confirming that string path syntax is the way to go forward, according to Angular themselves, but that it doesn't scale well for larger projects? What are the implications of this? When will you run into this?

The chunks not getting generated properly is more of a Webpack issue in my opinion, although that heavily relies on @ngtools/webpack in the most recent version which does all the angular compilation. If chunking is the main thing that's failing for the default builds, then I suggest we find or open a related issue and post our findings and keep a reference in this topic.

@WillooWisp
Copy link

I can confirm that the string path syntax works fine as long as your imports, declarations and routes are static. If code contains conditionals, where some routes are added based on some condition, chunks will not be generated for those upon first compilation, using start:hmr or start:aot. Making any change affecting the main chunk will cause a recompile and chunks will be generated for the lazy loaded routes as well. If those routes in turn contain lazy loaded child routes a recompile must be triggered once again from this parent chunk.

It used to work fine with conditionals, both when it came to adding routes more dynamically, but also adding declarations and module imports based on some condition. This is also broken now, so declarations and imports added inside conditional statements are ignored unfortunately.

@gajdot
Copy link

gajdot commented Jan 18, 2018

Any update or workaround for this?

@geogramdotcom
Copy link

geogramdotcom commented Jan 21, 2018

I'm also having the same issue. App is getting quite large now and needs lazy loading to keep the initial load time down for the user. I've tried every syntax:

{path:'properties', loadChildren:'./components/properties/properties.module#PropertiesModule'} {path:'properties', loadChildren:'components/properties/properties.module#PropertiesModule'} {path:'properties', loadChildren: ()=> PropertiesModule }

Webpack compiles fine and app works for all of the root-UI and smaller components not using loadChildren, but when nav to '/properties' getting 404 inside the router-outlet

Angular CLI: 1.6.3
Node: 6.11.4
OS: linux x64
Angular: 5.2.0

Also I should note one of the '/properties' child links are using :id but even commenting out all these dynamic links the route never loads.

@Bjeaurn
Copy link
Author

Bjeaurn commented Jan 21, 2018

It’s unclear what exactly is causing this, but it seems to be related to the webpack config. Have you tried disabling a couple of plugins or starting over with a fresh one from the repo?

@WillooWisp
Copy link

Compare your webpack config with the one from this repo, make sure you do not have any significant changes. Then it should work as long as you do not have any conditional include of routes, modules or declarations in your code. Unfortunately conditionals do not work anymore, why I do not know.

@geogramdotcom
Copy link

geogramdotcom commented Jan 22, 2018

@Bjeaurn @WillooWisp ;

Thank you both. I was able to get the lazy loading to work by disabling all the Auth/Services out for conditional login routing and deleting the NodeModule folder and npm update. Need to do more testing to figure out a workaround. If conditionals truly don't work anymore then this completely kills any auth rules for apps. *NgIf still seems to work in the componentHTML files, so thats good.

@eyuel4
Copy link

eyuel4 commented Jan 31, 2018

Is there any clear solution on this yet? Am getting the same issue on my project.

@televic-education-ruben
Copy link

televic-education-ruben commented Jan 31, 2018

The new @ngtools/webpack package performs static analysis on an application during build time to locate all the lazy-loaded router paths. The static analysis can't handle conditionals in this case.
This is how you can solve it: https://blog.angularindepth.com/dynamically-loading-components-with-angular-cli-92a3c69bcd28. It's written for the angular CLI, but it's basically the same thing. I haven't tried it myself though.

@jdcrecur
Copy link

jdcrecur commented Jan 31, 2018

@Televic-Education this appears to be dynamic component loading only and not lazy loading modules.

https://stackoverflow.com/questions/48523411/angular-5-with-angular-cli-non-lazy-loading-modules-in-the-router

We hit this issue, or maybe a slight variation of it. The above is the original stackoverflow q raised.

In short, we want to use modules for pages and not components thus allowing good separation of concerns from redux to routing inc. component importing managed by the module that needs them etc etc. Only lazy loading modules everywhere works just fine, but lazy loading a module inside a module that was not lazy loaded breaks things and the said lazy loading throws an error saying the module cannot be found. I think we narrowed it down to the ang-cli tool simply not creating the chunk.

Here is the code https://github.com/jdcrecur/ang5ModuleRouting

The router that breaks is: https://github.com/jdcrecur/ang5ModuleRouting/blob/master/src/app/modules/layouts/authenticated/authenticated-layout-routing.module.ts

The module is referenced from the base of the app directory, but it doesn't make any difference how this is referenced, either by traversing up or not.

@82antu
Copy link

82antu commented Feb 6, 2018

Same issue here;

help is very appreciate

@jandresampaio
Copy link

Same here.
When using AOT, root app.module.ngfactory is loaded but when navigating to child lazy routes triggers that "cannot find module.ngfactory".

@Vladimex
Copy link

Same issue.
Help is very appreciate.

@kgish
Copy link

kgish commented Feb 18, 2018

There's a tool call npm-check which might help you update to the latest versions and ensure that the dependencies are correct.

@FARHANE
Copy link

FARHANE commented Feb 20, 2018

I have the same problem with angular cli 1.7.0.
I don't have any conditions for loading modules.

ERROR in TypeError: Cannot read property 'loadChildren' of undefined
 at _collectLoadChildren ( ...... \node_modules\@angular\compiler\bundles\compiler.umd.js:29034:21)
at listLazyRoutes (...\node_modules\@angular\compiler\bundles\compiler.umd.js:29009:49)
    at visitLazyRoute (...\node_modules\@angular\compiler\bundles\compiler.umd.js:31176:47)
    at AotCompiler.listLazyRoutes (...\node_modules\@angular\compiler\bundles\compiler.umd.js:31144:20)
    at AngularCompilerProgram.listLazyRoutes (...\node_modules\@angular\compiler-cli\src\transformers\program.js:156:30)
    at Function.NgTools_InternalApi_NG_2.listLazyRoutes (...\node_modules\@angular\compiler-cli\src\ngtools_api.js:44:36)
    at AngularCompilerPlugin._getLazyRoutesFromNgtools (...\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:263:66)
    at Promise.resolve.then.then (...\node_modules\@ngtools\webpack\src\angular_compiler_plugin.js:586:50)
    at <anonymous>
    at process._tickCallback (internal/process/next_tick.js:188:7)

@Bjeaurn
Copy link
Author

Bjeaurn commented Feb 20, 2018

Be advised that when you upgrade your versions, they will have to match as there is no backwards compatibility from the Angular team within minor versions between modules.

So you cannot have @angular/core at 5.2.5 and @angular/forms at 5.1.2, the same goes for @angular/compiler etcetera.

The only exception to this rule is @angular/angular-cli, as this is supposed to be installed globally and used to manage your angular installation and generation.

If you're using this repo, angular-starter, I'm quite sure there is no support for the angular-cli as of now by default.

@FARHANE
Copy link

FARHANE commented Feb 20, 2018

there is my config

"dependencies": {
    "@angular/animations": "^5.2.0",
    "@angular/cdk": "^5.2.1",
    "@angular/common": "^5.2.0",
    "@angular/compiler": "^5.2.0",
    "@angular/core": "^5.2.0",
    "@angular/forms": "^5.2.0",
    "@angular/http": "^5.2.0",
    "@angular/material": "^5.2.1",
    "@angular/material-moment-adapter": "^5.2.1",
    "@angular/platform-browser": "^5.2.0",
    "@angular/platform-browser-dynamic": "^5.2.0",
    "@angular/router": "^5.2.0",
    "angular-calendar": "^0.23.6",
    "core-js": "^2.4.1",
    "hammerjs": "^2.0.8",
    "moment": "^2.20.1",
    "orange-library": "^0.2.3",
    "rxjs": "^5.5.6",
    "zone.js": "^0.8.19"
  },
  "devDependencies": {
    "@angular/cli": "~1.7.0",
    "@angular/compiler-cli": "^5.2.0",
    "@angular/language-service": "^5.2.0",
    "@types/jasmine": "~2.8.3",
    "@types/jasminewd2": "~2.0.2",
    "@types/node": "~6.0.60",
    "codelyzer": "^4.0.1",
    "jasmine-core": "~2.8.0",
    "jasmine-spec-reporter": "~4.2.1",
    "karma": "~2.0.0",
    "karma-chrome-launcher": "~2.2.0",
    "karma-coverage-istanbul-reporter": "^1.2.1",
    "karma-jasmine": "~1.1.0",
    "karma-jasmine-html-reporter": "^0.2.2",
    "protractor": "~5.1.2",
    "ts-node": "~4.1.0",
    "tslint": "~5.9.1",
    "typescript": "~2.5.3"
  }

@jandresampaio
Copy link

I had this problem and the cause for mine was DLL plugin.
I solved this by:
-Removing webpack DLL plugin and including vendors imports file directly in the entry points:
entry: { 'polyfills': './ClientApp/polyfills.ts', 'vendor': './ClientApp/vendor.ts', 'main-client': isDevBuild ? './ClientApp/boot-client.ts': './ClientApp/boot-client-prod.ts' },

-Add common chunks configuration to plugins:
new webpack.optimize.CommonsChunkPlugin({ name: ['main-client', 'vendor', 'polyfills'] }),

I also noticed in other 'issues' that ContextReplacementPlugin could also be a cause for this.

I have some variables in my App module (are the inputs - address and port - for services) which are not known at compile time and that's not a problem for my configuration.

@Bjeaurn
Copy link
Author

Bjeaurn commented Feb 20, 2018

Looks good, except for @angular/material and @angular/cdk, however I doubt that they are causing the error you are having.

By the way, this is not a support forum; maybe we should move all of this to StackOverflow and make a tag for angular-starter, or consider moving your project to the ng-cli yourself.

In regards to @jandresampaio, this in a basic sense fixed it for me too; I just checked my current webpack.common to the new one in this repo and fixed my plugins. This resulted into removing the DllPlugin (and some others) that ultimately made it compile again.

Basically; check your webpack configurations. Try to download a new one and upgrade your package.json to match the used (and removed!) plugins by webpack. Yes, this does mean downloading the new webpack.configs and just running it; then seeing which plugins the compiler is missing.

After some trial and error, I got my lazy loading to work this way.

I suggest we close this thread and any other support request goes onto StackOverflow.

@SmartBitPixel
Copy link

I also face same issue:

ERROR in TypeError: Cannot read property 'loadChildren' of undefined
at _collectLoadChildren (..../node_modules/@angular/compiler/bundles/compiler.umd.js:29034:21)
at listLazyRoutes (..../node_modules/@angular/compiler/bundles/compiler.umd.js:29009:49)
at visitLazyRoute (..../node_modules/@angular/compiler/bundles/compiler.umd.js:31176:47)
at AotCompiler.listLazyRoutes (..../node_modules/@angular/compiler/bundles/compiler.umd.js:31144:20)
at AngularCompilerProgram.listLazyRoutes (..../node_modules/@angular/compiler-cli/src/transformers/program.js:156:30)
at Function.NgTools_InternalApi_NG_2.listLazyRoutes (..../node_modules/@angular/compiler-cli/src/ngtools_api.js:44:36)
at AngularCompilerPlugin._getLazyRoutesFromNgtools (..../node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:247:66)
at Promise.resolve.then.then (..../node_modules/@ngtools/webpack/src/angular_compiler_plugin.js:538:50)
at
at process._tickCallback (internal/process/next_tick.js:160:7)



Environment is:

15 "@angular-devkit/core": "0.0.29",
16 "@angular/animations": "^5.1.0",
17 "@angular/cdk": "^5.0.1",
18 "@angular/common": "^5.0.3",
19 "@angular/compiler": "^5.0.3",
20 "@angular/core": "^5.0.3",
21 "@angular/forms": "^5.0.3",
22 "@angular/http": "^5.0.3",
23 "@angular/material": "^5.0.1",
24 "@angular/platform-browser": "^5.0.3",
25 "@angular/platform-browser-dynamic": "^5.0.3",
26 "@angular/router": "^5.0.3",
27 "core-js": "^2.5.1",
28 "hammerjs": "^2.0.8",
29 "rxjs": "^5.5.2",
30 "zone.js": "^0.8.18"
31 },
32 "devDependencies": {
33 "@angular/cli": "1.5.4",
34 "@angular/compiler-cli": "^5.0.3",
35 "@angular/language-service": "^5.0.3",
36 "@types/jasmine": "~2.5.54",
37 "@types/jasminewd2": "~2.0.3",
38 "@types/node": "~6.0.92",
39 "codelyzer": "~3.2.2",

@Bjeaurn
Copy link
Author

Bjeaurn commented Feb 26, 2018

Not a support forum, do read the last post I made here: #1936 (comment)

Check your webpack configuration and refresh it if you're upgrading from an old version of this repo. You will need to check the plugins as well, as some of them have been deprecated.

@Bjeaurn Bjeaurn closed this as completed Feb 26, 2018
@FirassKoubaa
Copy link

finally how can manage it ? , i got the same issues

@Bjeaurn
Copy link
Author

Bjeaurn commented Mar 2, 2018

At least try to read?

#1936 (comment)
#1936 (comment)

Reminder: This is not a support forum.

@ErwinSanquer
Copy link

I had the same issue, and I didn't catch the warning on my terminal holding the ng serve. It seems that add a page while ng serve is running didn't allow to rebuild properly with the new page.
Relunching the ng serve allow to build correctly the webpack.

@michielcox
Copy link

+1

2 similar comments
@olegshestakov
Copy link

+1

@azizmatmati
Copy link

+1

@DhiaEddineSaidi
Copy link

in aot : the compiler is missing in the RouterConfigLoader.
is there any work around ??

@ccartas
Copy link

ccartas commented Apr 27, 2018

Indeed this was fixed for me using --aot flag but it's not a solution. It looks like when I modified the RouterConfig by adding a new lazy loaded module, everything didn't worked as expected.
How i got rid of my error?

  1. Check if your AppModule imports anything else but AppRouterModule (everything else should be lazy loaded)
  2. I've added in each of my router modules the following configuration:
  • Let's say i have 2 lazy loaded modules(A and B) and for each of them i got a router module:

Routes for Module A would look like this:
{
path: '',
pathMatch: 'full'',
redirectTo: 'contentA'
},
{
path: 'contentA',
component: ContentAComponent
}

Routes for Module B would look like this:
{
path: '',
pathMatch: 'full',
redirectTo: 'contentB'
},
{
path: 'contentB',
component: ContentBComponent
}

@immortalt
Copy link

+1

@Donovantxy
Copy link

I have the same issue loading

{
  path: 'child',
  loadChildren: '../node_modules/module-upgrade/src/app/app.module#UpgradeModule'
},

I the case up here the error is
Error: Could not resolve "../node_modules/module-upgrade/src...." from /Users/username/project/src/app/app/module.ts
and it works when I apply the method @Bjeaurn explained here

{
  path: 'child',
  loadChildren: UpgradeModule.getUpgradeModule
},

@karthikdeva
Copy link

I'm also facing same issue with router lazy loading module.
error

@ajay7868
Copy link

ajay7868 commented Oct 1, 2018

ERROR Error: Uncaught (in promise): Error: No NgModule metadata found for 'Component module'.( { path: 'purchaseOrders', loadChildren: '../purchase-order/purchase-order.module#PurchaseOrderModule' },
)
Error: No NgModule metadata found for 'Component module '.
any one have idea why is error occur . i am just upgrad version 4 to 5.2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests