Webpack 4 and multiple entry points

I’m looking to convert our Electron app from jspm/Systemjs to Webpack. We’ve recently converted to a monorepo so that we can release parts of our app as npm modules and ideally we’d like all module resolution to go through node_modules rather than the crazy hybrid combination we’re currently using.

As a bonus of using Webpack, we’re hoping to be able to define multiple entry points. With this we can more easily bundle for multiple windows. Depending on the functionality required in a window, we would just point the window at the correct entry point. I’m guessing for this we will have to define a Aurelia app for each entry point?

Specifically, I’ve been trying to combine the webpack config from Github Desktop with the one in the latest skeleton. The Github Desktop webpack config is ideal as it bundles the entire node_modules while taking care of native .node modules. Does the aurelia-webpack-plugin support multiple entry points?

The Github Desktop app uses react so can define the entry points like this:

  entry: { renderer: path.resolve(__dirname, 'src/ui/index') },
  target: 'electron-renderer',

The aurelia-webpack-plugin seems to require pointing at the bootstrapper:

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

Is there any way round this or am I going to have to wait for Aurelia to support Webpack without the need for aurelia-webpack-plugin?

From @jods4

It should work. Off the top of my head there are 2 options to tweak:
aureliaApp is the name of your main module that Aurelia gets from the HTML attribute.
AureliaPlugin options · aurelia/webpack-plugin Wiki · GitHub
With multiple entry points, they each have their own or are managed in another way, so you should set it to undefined.
I recommend managing the entry point by passing it explicitely to Aurelia setRoot, wrapped in moduleName.
GitHub
aurelia/webpack-plugin
webpack-plugin - A plugin for webpack that enables bundling Aurelia applications.

entry is your entry point(s). The plugin needs it to perform some magic, explained here:
AureliaPlugin options · aurelia/webpack-plugin Wiki · GitHub
You want to pass an array of entry point names here.
GitHub
aurelia/webpack-plugin
webpack-plugin - A plugin for webpack that enables bundling Aurelia applications.

Should be good to go.
I see the word “monorepo” in Discord, that might be more tricky (there’s an open issue about it).

Thanks, I’ll give this a go.

We’re using yarn workspaces but can probably get everything working using nohoist for now.

1 Like

8 months on and I’ve finally migrated our app to Webpack!

This evening I’ve started attempting to add extra entry points like this:

entry: {
    'main-window': ['./src/init', './src/main-window'],
    'file-view': ['./src/init', './src/file-view']
  }
// snip
   new AureliaPlugin({
     aureliaApp: undefined,
     features: { polyfills: 'none' }
   }),

init.ts is simply:

import 'reflect-metadata';
import { initialize } from 'aurelia-pal-browser';
initialize();

And then Aurelia is being manually bootstrapped a bit like:

import { bootstrap } from 'aurelia-bootstrapper';
import { Aurelia } from 'aurelia-framework';
import { App } from './app';
import environment from './environment';

bootstrap(async (aurelia: Aurelia) => {
  aurelia.use.standardConfiguration();

  if (environment.debug) {
    aurelia.use.developmentLogging();
  }

  await aurelia.start();
  return aurelia.setRoot(App, document.body);
});

Webpack splits this up nicely with a common chunk and two entry points.

Unfortunately, whichever entry point is listed second gives the following error at runtime:

No PLATFORM.Loader is defined and there is neither a System API (ES6) or a Require API (AMD) globally available to load your app.

I’m guessing this is because the plugin is only adding the loader to the first entry point.

To get around this, I manually add the loader:

entry: {
    'main-window': [
       './src/init', 
       require.resolve('aurelia-webpack-plugin/runtime/pal-loader-entry')
       './src/main-window'
    ],
    'file-view': [
      './src/init', 
      require.resolve('aurelia-webpack-plugin/runtime/pal-loader-entry')
      './src/file-view'
    ]
  }
// snip
   new AureliaPlugin({
     aureliaApp: undefined,
     features: { polyfills: 'none' },
     noWebpackLoader: true // < ensure the loader doesn't get added twice
   }),

…and it appears to be working!

1 Like

That’s tremendous faith. :smile:

1 Like

:rofl:

Yeah, that should have read “finally got around to migrating”. The actual work took about 4-5 days and most of that was learning Webpack.

When I have some spare time, everything I’ve learned will go back into this skeleton, which I’ll expand to better represent a serious app.

2 Likes

one also can get around it by adding //import 'aurelia-loader-webpack'; // manually initialize the loader before importing PLATFORM in your entry files

or

new AureliaPlugin({
 entry: ['main-window', 'file-view'],
...
2 Likes