2

I'm facing an issue after angular 5 migration with lazy loading. In my webpack.config I'm using angular-router-loader but there is no error in console when I'm running in JIT mode and lazy modules never load.

When I run the app with ngTools for AOT compilation it works and I can see the generated chucks.

I already tried many solutions but the chucks aren't generated and when I navigate to lazyload route there is no error in console, it just won't load.

Console logs

// app.module
@NgModule({
 imports: [
    BrowserModule,
    MainPageModule,
    RouterModule.forRoot(appRoutes, {
      useHash: true,
      // preloadingStrategy: PreloadAllModules
    })
  ]
});

// app.routing
import { Routes } from '@angular/router';
import { MainPageComponent } from './main_page/main.page.component';

    export const appRoutes: Routes = [
      { path: '', component: MainPageComponent },
      { path: 'dashboard', loadChildren: './_dashboard/dashboard.module#DashboardModule' },
      { path: 'lazyload', loadChildren: './lazyload/lazy.module#LazyModule' }
    ];


/** 
 * webpack.config
*/
const path = require('path');
const webpack = require('webpack');

const { AngularCompilerPlugin } = require('@ngtools/webpack');

// Webpack Plugins
const CommonsChunkPlugin = require('webpack/lib/optimize/CommonsChunkPlugin');
const autoprefixer = require('autoprefixer');
const cssnano = require('cssnano');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const ExtractTextPlugin = require('extract-text-webpack-plugin');
const FaviconsWebpackPlugin = require('favicons-webpack-plugin');
const DashboardPlugin = require('webpack-dashboard/plugin');
const CheckerPlugin = require('awesome-typescript-loader').CheckerPlugin;
// const CompressionPlugin = require("compression-webpack-plugin");
const UglifyJsPlugin = require('webpack/lib/optimize/UglifyJsPlugin');

//Configurations
const optimizationConfig = require('./opt.config.json');
const tsLintConfig = require('./tslint.json');

/**
 * Env
 * Get npm lifecycle event to identify the environment
 */
const ENV = process.env.npm_lifecycle_event;
const isTestWatch = ENV === 'test-watch';
const isTest = ENV === 'test' || isTestWatch;
const isProd = ENV === 'build';
const isAOTWatch = ENV.includes('aot');
console.log('======== Running in mode: ' + (isAOTWatch || isProd ? 'AOT' : 'JIT'));

module.exports = function makeWebpackConfig() {
    /**
     * Config
     * Reference: http://webpack.github.io/docs/configuration.html
     * This is the object where all configuration gets set
     */
    let config = {};

    /**
     * Devtool
     * Reference: http://webpack.github.io/docs/configuration.html#devtool
     * Type of sourcemap to use per build type
     */
    if (isProd) {
        config.devtool = 'source-map';
    }
    else if (isTest) {
        config.devtool = 'inline-source-map';
    }
    else {
        config.devtool = 'eval-source-map';
    }

    /**
     * Entry
     * Reference: http://webpack.github.io/docs/configuration.html#entry
     */
    if (!isTest) {
        /**
         * Entry
         * Reference: http://webpack.github.io/docs/configuration.html#entry
         */
        config.entry = isTest ? {} : {
            'app': './src/config/main.ts', // Our angular app
            'polyfills': './src/config/polyfills.ts',
            'vendor': './src/config/vendor.ts'
        };
    }

    /**
     * Output
     * Reference: http://webpack.github.io/docs/configuration.html#output
     */
    config.output = isTest ? {} : {
        path: root('__build__'),
        publicPath: isProd ? '/' : 'http://localhost:9000/',
        filename: isProd ? 'js/[name].[hash].js' : 'js/[name].js',
        sourceMapFilename: isProd ? 'js/[name].[hash].js.map' : 'js/[name].js.map',
        chunkFilename: isProd ? '[id].[hash].chunk.js' : '[id].chunk.js'
    };

    /**
     * Resolve
     * Reference: http://webpack.github.io/docs/configuration.html#resolve
     */
    config.resolve = {
        // Only discover files that have those extensions
        extensions: ['.ts', '.js', '.json', '.css', '.scss', '.html']
    };

    let atlOptions = '';
    if (isTest && !isTestWatch) {
        // awesome-typescript-loader needs to output inlineSourceMap for code coverage to work with source maps.
        atlOptions = 'inlineSourceMap=true&sourceMap=false';
    }

    /**
     * Loaders
     * Reference: http://webpack.github.io/docs/configuration.html#module-loaders
     * List: http://webpack.github.io/docs/list-of-loaders.html
     * This handles most of the magic responsible for converting modules
     */
    config.module = {
        rules: [
            {
                test: /(?:\.ngfactory\.js|\.ngstyle\.js|\.ts)$/,
                loaders: isProd || isAOTWatch ? ['@ngtools/webpack'] : [
                        '@angularclass/hmr-loader',
                        'awesome-typescript-loader?inlineSourceMap=true&sourceMap=false',
                        'angular2-template-loader',                        
                        'angular-router-loader'
                    ]
            },
            // Support for *.json files.
            {
                test: /\.json$/,
                loader: 'json-loader'
            },

            // Load fonts
            {
                test: /\.woff(2)?(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "url-loader?mimetype=application/font-woff&name=./font/[hash].[ext]"
            },

            {
                test: /\.(ttf|eot|svg)(\?v=[0-9]\.[0-9]\.[0-9])?$/,
                loader: "file-loader?name=./fonts/[hash].[ext]"
            },

            // Load images
            {
                test: /\.(jpe?g|png|gif|ico)$/,
                loader: "file-loader?name=./image/[hash].[ext]"
            },

            // SASS or SCSS loaded in src/app/_common
            {
                test: /\.css$/,
                include: [root('src', 'app', '_common', 'plugins'), root('src', 'app', '_common', 'styles')],
                loader: isTest ? 'null-loader' : ExtractTextPlugin.extract({ fallback: 'style-loader', use: ['css-loader'] })
            },

            // SASS or SCSS loaded in all components
            {
                test: /\.(scss|sass)$/,
                exclude: [root('src', 'app', '_common', 'plugins'), root('src', 'app', '_common', 'styles')],
                loader: 'raw-loader!postcss-loader!sass-loader'
            },

            // Support for .html as raw text
            {
                test: /\.html$/,
                loader: 'raw-loader',
                exclude: root('src', 'config')
            }
        ]
    };
    if (isTest && !isTestWatch) {
        // instrument only testing sources with Istanbul, covers ts files
        config.module.rules.push({
            test: /\.ts$/,
            enforce: 'post',
            include: path.resolve('src'),
            loader: 'istanbul-instrumenter-loader',
            exclude: [/\.spec\.ts$/, /\.e2e\.ts$/, /node_modules/]
        });
    }

    if (!isTest || !isTestWatch) {
        // tslint support
        config.module.rules.push({
            test: /\.ts$/,
            enforce: 'pre',
            loader: 'tslint-loader'
        });
    }

    /**
     * Plugins
     * Reference: http://webpack.github.io/docs/configuration.html#plugins
     * List: http://webpack.github.io/docs/list-of-plugins.html
     */
    config.plugins = [
        // Define env letiables to help with builds
        // Reference: https://webpack.github.io/docs/list-of-plugins.html#defineplugin
        new webpack.DefinePlugin({
            // Environment helpers
            'process.env': {
                ENV: JSON.stringify(ENV)
            }
        }),

        // Workaround needed for angular 2 angular/angular#11580
        /*  new webpack.ContextReplacementPlugin(
              // The (\\|\/) piece accounts for path separators in *nix and Windows
              /angular(\\|\/)core(\\|\/)(esm(\\|\/)src|src)(\\|\/)linker/,
              root('./src') // location of your src
          ),*/

        // Tslint configuration for webpack 2
        new webpack.LoaderOptionsPlugin({
            options: {
                /**
                 * Apply the tslint loader as pre/postLoader
                 * Reference: https://github.com/wbuchwalter/tslint-loader
                 */
                tslint: tsLintConfig,

                /**
                 * Sass
                 * Reference: https://github.com/jtangelder/sass-loader
                 * Transforms .scss files to .css
                 */
                sassLoader: {},

                /**
                 * PostCSS
                 * Reference: https://github.com/postcss/autoprefixer-core
                 * Add vendor prefixes to your css
                 */
                postcss: [
                    autoprefixer(optimizationConfig.autoprefixer),
                    cssnano(optimizationConfig.cssnano)
                ]
            }
        })
    ];
    if (isProd || isAOTWatch) {
        config.plugins.push(
            new AngularCompilerPlugin({
                tsConfigPath: './tsconfig.json',
                entryModule: root('src/app/app.module#AppModule')
            })
        );
    } else {
        config.plugins.push(
            new webpack.ContextReplacementPlugin(
                /angular(\\|\/)core/,
                path.resolve('./src')
            )
        );
    }

    if (!isTest && !isProd) {
        config.plugins.push(new DashboardPlugin());
    }

    if (!isTest && !isTestWatch) {
        config.plugins.push(
            new CheckerPlugin(),

            // Generate common chunks if necessary
            // Reference: https://webpack.github.io/docs/code-splitting.html
            // Reference: https://webpack.github.io/docs/list-of-plugins.html#commonschunkplugin
            new CommonsChunkPlugin({
                name: ['vendor', 'polyfills']
            }),

            // Inject script and link tags into html files
            // Reference: https://github.com/ampedandwired/html-webpack-plugin
            new HtmlWebpackPlugin({
                template: './src/config/index.html',
                chunksSortMode: 'dependency'
            }),

            // Extract css files
            // Reference: https://github.com/webpack/extract-text-webpack-plugin
            // Disabled when in test mode or not in build mode
            new ExtractTextPlugin({
                filename: 'css/[name].[hash].css',
                disable: !isProd
            }),

            // Support favicons generation
            // Reference: https://github.com/jantimon/favicons-webpack-plugin
            new FaviconsWebpackPlugin({
                logo: './src/config/favicon.png',
                title: 'Glow Portal',
                prefix: 'favicon/',
                icons: {
                    android: false,
                    appleIcon: false,
                    appleStartup: false,
                    coast: false,
                    favicons: true,
                    firefox: false,
                    opengraph: false,
                    twitter: false,
                    yandex: false,
                    windows: false
                }
            }),

            // Module (value) is loaded when the identifier (key) is used as free letiable in a module.
            // Reference: https://webpack.github.io/docs/list-of-plugins.html#provideplugin
            new webpack.ProvidePlugin({
                jQuery: 'jquery',
                $: 'jquery',
                jquery: 'jquery',
                moment: 'moment',
                svgPanZoom: 'svg-pan-zoom'
            })
        );
    }


    // Add build specific plugins
    if (isProd) {
        config.plugins.push(
            // Reference: http://webpack.github.io/docs/list-of-plugins.html#noerrorsplugin
            // Only emit files when there are no errors
            new webpack.NoEmitOnErrorsPlugin(),

            // Reference: http://webpack.github.io/docs/list-of-plugins.html#uglifyjsplugin
            // Minify all javascript, switch loaders to minimizing mode
            new UglifyJsPlugin(optimizationConfig.uglifyjs)

            // Reference: https://recordnotfound.com/compression-webpack-plugin-webpack-76201
            // Prepare compressed versions of assets to serve them with Content-Encoding
            /*new CompressionPlugin({
             asset: "[path].gz[query]",
             algorithm: "gzip",
             test: /\.js$|\.css$|\.html$/,
             threshold: 10240
             })*/
        );
    }

    /**
     * Dev server configuration
     * Reference: http://webpack.github.io/docs/configuration.html#devserver
     * Reference: http://webpack.github.io/docs/webpack-dev-server.html
     */
    config.devServer = {
        contentBase: './__build__',
        historyApiFallback: true,
        stats: 'minimal',
        watchOptions: {
            aggregateTimeout: 300,
            poll: 1000
        }
    };

    return config;
}();

// Helper functions
function root(args) {
    args = Array.prototype.slice.call(arguments, 0);
    return path.join.apply(path, [__dirname].concat(args));
}

0

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.