Aurelia 2 bundling portions of application

With 2.0.0-alpha.15 when trying to lazy-load route with

@route({
  routes: [
    { path: '', component: () => import('./modules/portal/portal-page') },
    { path: 'login', component: () => import('./modules/login/login-page') },
  ]
})

it does not work - the modules are separated in different js files, but a blank page is shown and no HTTP requests are made to load the modules.

What is the correct way to implement lazy-loading in v2?

Its depends on how you created your bundles. Can you tell us the bundler and config you have?

I have created the app through “npx makes aurelia” as stated in the docs, then selecting the default typescript option - so the bundler should be webpack. Here is the config:

/* eslint-disable @typescript-eslint/no-var-requires */
const path = require('path');
const HtmlWebpackPlugin = require('html-webpack-plugin');
const {BundleAnalyzerPlugin} = require('webpack-bundle-analyzer');

const cssLoader = 'css-loader';


const postcssLoader = {
  loader: 'postcss-loader',
  options: {
    postcssOptions: {
      plugins: ['autoprefixer']
    }
  }
};

module.exports = function(env, { analyze }) {
  const production = env.production || process.env.NODE_ENV === 'production';
  return {
    target: 'web',
    mode: production ? 'production' : 'development',
    devtool: production ? undefined : 'eval-cheap-source-map',
    entry: {
      entry: './src/main.ts'
    },
    output: {
      path: path.resolve(__dirname, 'dist'),
      filename: production ? '[name].[contenthash].bundle.js' : '[name].bundle.js'
    },
    resolve: {
      extensions: ['.ts', '.js'],
      modules: [path.resolve(__dirname, 'src'), 'node_modules']
    },
    devServer: {
      historyApiFallback: true,
      open: !process.env.CI,
      port: 9000
    },
    module: {
      rules: [
        { test: /\.(png|gif|jpg|cur)$/i, loader: 'url-loader', options: { limit: 8192 } },
        { test: /\.woff2(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff2' } },
        { test: /\.woff(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'url-loader', options: { limit: 10000, mimetype: 'application/font-woff' } },
        { test: /\.(ttf|eot|svg|otf)(\?v=[0-9]\.[0-9]\.[0-9])?$/i, loader: 'file-loader' },
        { test: /\.css$/i, use: [ 'style-loader', cssLoader, postcssLoader ] },
        { test: /\.ts$/i, use: ['ts-loader', '@aurelia/webpack-loader'], exclude: /node_modules/ },
        { test: /[/\\]src[/\\].+\.html$/i, use: '@aurelia/webpack-loader', exclude: /node_modules/ }
      ]
    },
    plugins: [
      new HtmlWebpackPlugin({ template: 'index.html' }),
      analyze && new BundleAnalyzerPlugin()
    ].filter(p => p)
  }
}

(that was auto-generated by the CLI)

Basically, I haven’t changed anything on the sample project, besides registering the RouterConfiguration like:

Aurelia
  .register(RouterConfiguration)
  .app(MyApp)
  .start();

and adding the routes

import { route } from 'aurelia';

@route({
  routes: [
    { id: 'portal', path: '', component: () => import('./modules/portal/portal-page'), title: 'Home' },
    { id: 'login', path: 'login', component: () => import('./modules/login/login-page'), title: 'Sign in' },
  ]
})
export class MyApp {
  public message = 'Hello Main App!';
}

If I import the routes with

@route({
  routes: [
    { id: 'portal', path: '', component: import('./modules/portal/portal-page'), title: 'Home' },
    { id: 'login', path: 'login', component: import('./modules/login/login-page'), title: 'Sign in' },
  ]
})

then everything works, but all routes will load eagerly, which is something I’m trying to avoid as the application we are evaluating to migrate from Angular to Aurelia have a lot of routes and the startup time will be too much if we eagerly load them all at startup.

1 Like
@route({
  routes: [
    { id: 'portal', path: '', component: () => import('./modules/portal/portal-page'), title: 'Home' },
    { id: 'login', path: 'login', component: () => import('./modules/login/login-page'), title: 'Sign in' },
  ]
})

This should be supported. If it’s not working then it’s probably a bug somewhere in the router, at least I believe so.