Integrating an Aurelia app inside of a preexisting Handlebars/Webpack application

I’m trying to insert a brand new Aurelia app inside of a large, preexisting application that uses Handlebars and Webpack (it processes .template files with handlebars-loader).

I’ve never tried to bootstrap an Aurelia app from “deep” within another application before and need some help on how to configure Webpack.

Currently I’m bootstrapping the application with this code copy and pasted from the “Manual Bootstrapping with Webpack” code block here.

bootstrap(async aurelia => {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();
  await aurelia.start();
  await aurelia.setRoot(PLATFORM.moduleName('app'), document.querySelector('.deeply-nested-element-on-preexisting-page'));
}).catch(err => console.error(err));

My app.js and app.html files are “siblings” with the file containing the above call to bootstrap (i.e. they’re all in the same directory /src/client).

Then in my webpack.config.js, I import

const { AureliaPlugin } = require('aurelia-webpack-plugin');

and use it in

plugins: [
  new AureliaPlugin(),
  ...

I believe my problem is in how to tell Webpack where the entry point to the Aurelia applicaiton is. Currently (before I added any Aurelia into the project), Webpack is using

entry: {
  index: './src/client/index.js'
}

to start the preexisting Handlebars application.

Based on the example Webpack config, I tried

entry: {
  app: ['aurelia-bootstrapper'],
  index: './src/client/index.js'
}

but when I run Webpack, that results in:

throw new Error('Can't figure out a normalized module name for ${realModule.rawRequest}, please call PLATFORM.moduleName() somewhere to help.');

Error: Can't figure out a normalized module name for ./src/client/index.js, please call PLATFORM.moduleName() somewhere to help.

It seems as though Aurelia Webpack Plugin is trying to consume the preexisting, non-Aurelia entry point.

I should mention that the file where I’m calling bootstrap() from is not src/client/index.js. It’s another file that runs only after the element that’s used in setRoot() has been added to the DOM.

Anyone know how to handle this situation?

EDIT: After reading the Aurelia Webpack Plugin wiki, I modified my config to:

plugins: [
  new AureliaPlugin({
    aureliaApp: undefined,
    entry: 'app',
  }),
  ...

but continue to get the same exact error.

1 Like

When initialize your application inside another app, it is important to control the entry point yourself. In your webpack configure, instead of having:

  entry: {
    app: ['aurelia-bootstrapper']
  }

do:

  entry: {
    app: ['your-real-app-entry.js']
  }

and in your-real-app-entry.js, it would look like this:

import 'aurelia-polyfills';
import { initialize } from 'aurelia-pal-browser';
import { Aurelia } from 'aurelia-framework';

initialize();

const aurelia = new Aurelia();
aurelia
  .use
  .standardConfiguration()
  .developmentLoggin()
  .plugin('....');

aurelia
  .start()
  .then(() =>
    aurelia.setRoot(PLATFORM.moduleName('...'), document.querySelector('aurelia-sub-app'));
  )
  .then(() => {
    console.log('app started');
  });

Thanks! I actually ended up doing it the other way around and got it to work by using 'aurelia-bootstrapper' as the single entry point, and simply putting an import 'my-real-app-entry.js' at the top of app.ts.

1 Like