Aurelia 1 and webpack module federation plugin, different package.json names

Hi everyone, I am using Aurelia 1 and Webpack’s module federation plugin, trying to achieve component and vendor sharing between a host and a remote application.
I ran into a really strange problem recently. The sharing of the modules works perfectly fine when I am having the same name in the package.json file of the remote as well as the host app. But apparently, having a different name of the host than the one of the remote app in the package.json files breaks everything. The remote is loaded fine, but the host app cannot render anything from the remote. All of the shared bundles from the remote are loaded properly in the host though. In the host app I get this error:

TypeError: Cannot read properties of undefined (reading 'call')
    at Function.__webpack_require__ (app.bundle.js:430)
    at async Module.configure (main.ts:11)
    at async Promise.all (:3003/index 0)

And the line in the app.bundle.js it refers to:

// Execute the module function
__webpack_modules__[moduleId].call(module.exports, module, module.exports, __webpack_require__);

Webpack config of the remote app:


/**
 * @returns {import('webpack').Configuration}
 */
module.exports = ({ mode = 'development' }) => ({
  entry: {
    app: ['./src/entryPoint']
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: "http://localhost:3004/",
    clean: true
  },
  resolve: {
    extensions: ['.ts', '.js'],
    modules: ['src', 'node_modules']
  },
  mode: 'development',
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 3004
  },
  module: {
    rules: [
      { test: /\.html$/i, loader: 'html-loader' },
      { test: /\.ts$/, loader: "ts-loader" },
    ]
  },
  plugins: [
    new AureliaPlugin({
      features: {
        svg: false
      },
      noWebpackLoader: true,
    }),
    new ModuleFederationPlugin({
      name: 'app2',
      library: {
        type: 'var',
        name: 'app2'
      },
      filename: 'remoteEntry.js',
      exposes: {
        './superFunction': './src/sharedModules/superFunction',
        './mySharedComponent': './src/resources/index'
      },
    }),
    new HtmlWebpackPlugin({
      template: 'index.ejs'
    })
  ]
});

Webpack config of the host:


/**
 * @returns {import('webpack').Configuration}
 */
module.exports = ({ mode = 'development' }) => ({
  entry: {
    // app: ['aurelia-bootstrapper']
    app: ['./src/entryPoint']
  },
  output: {
    filename: '[name].bundle.js',
    path: path.resolve(__dirname, 'dist'),
    publicPath: "http://localhost:3003/",
    clean: true
  },
  resolve: {
    extensions: ['.ts', '.js'],
    modules: ['src', 'node_modules']
  },
  mode: 'development',
  devServer: {
    contentBase: path.join(__dirname, 'dist'),
    port: 3003
  },
  module: {
    rules: [
      { test: /\.html$/i, loader: 'html-loader' },
      { test: /\.ts$/, loader: "ts-loader" },
    ]
  },
  plugins: [
    new AureliaPlugin({
      features: {
        svg: false
      },
      noWebpackLoader: true,
    }),
    new ModuleFederationPlugin({
      name: "app1",
      library: {
        type: 'var',
        name: 'app1'
      },
      remotes: {
        app2: "app2"
      },
    }),
    new HtmlWebpackPlugin({
      template: 'index.html',
      excludeChunks: ["app"],
    })
  ]
});

The shared component from the remote app looks like this:

import { bindable, inlineView, customElement } from 'aurelia-framework';
@inlineView(`<template>
  <h2>\${message}</h2>
</template>`)
@customElement('my-shared-component')
export class MySharedComponent {
    @bindable message = '** My message **';
    created() {
      console.log("created");
    }
}

And it is shared through the remote’s index.ts file like this:

import {FrameworkConfiguration} from 'aurelia-framework';
import { MySharedComponent } from '../sharedModules/mySharedComponent';
export function configure(config: FrameworkConfiguration): void {
  config.globalResources([MySharedComponent]);
}

It is imported in the host app through its main.ts file:

import {Aurelia} from 'aurelia-framework';
import {PLATFORM} from 'aurelia-pal';
declare global {
  interface Window {
    app2Url: string;
  }
}
window.app2Url = 'http://localhost:3004';
export async function configure(aurelia: Aurelia): Promise<void> {
  await Promise.resolve();

  // Import of shared component from the remote
  // @ts-ignore
  const comp = await import('app2/mySharedComponent');

  aurelia.use
    .standardConfiguration()
    .feature(PLATFORM.moduleName('resources/index'));
  aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));
}

And the index.ts from where the feature config in this previous file is loaded:

import {FrameworkConfiguration} from 'aurelia-framework';

export function configure(config: FrameworkConfiguration): void {
  config.globalResources([]);
}

When debugging the start of the host app, I can see that for some weird reason there is a mix up in this feature config of the main.ts in the host app, at the line from the previous file:

aurelia.use
    .standardConfiguration()
    **.feature(PLATFORM.moduleName('resources/index'));**

The index.ts of the remote app (from which I register mySharedComponent as a global resource) is injected as a feature in the host app and not the index.ts file from the host app itself as it is supposed to.

Once again, this error happens only if I have different names in the package.json files of the remote and the host app. If they have the same name everything works just fine.

Has anyone tried to use Webpack’s ModuleFederationPlugin with Aurelia 1 and has encountered this problem? If so could you explain how to fix this? Thank you very much.