Unable to use plugin in deployed app (Aurelia 2-Beta 15)

I am testing a simple scenario of creating a plugin, publishing it on nuget, and using it in app.
I used the default starter CLI app and plugin templates with typescript and webpack.
App works on webpack’s dev server, and hello-world form plugin is displayed.
When I build and deploy the app on nginx, I get AUR0016:InterfaceSymbol.
DI is not working with the plugin elements.
I tried different module formats and targets on plugin (web, node, commonjs, umd) to no avail.
In order to avoid multiple instances, plugin is using aurelia as a dev dependency, and is not packing it. I have checked with analyzer.
The plugin that I have created using rollup (no html elements, services only) works fine.
I can create a repro solution if needed.

Hi @zeko77! I have updated the release notes with a migration guide. Can you please re-check if that helps? If it does not help, please share a repro.

Thank you for a fast response.
I have already refactored the code to be Beta15 compliant according to guide:

  1. No more decorators in consturctors, switched to resolve().
  2. No more @bindable
  3. I only use Aurelia decorators.

The code compiles and runs fine within a plugin (dev-app part).
I publish the plugin and use it in the app.
When I run the app using webpack-dev-server, it works. DI successfully resolves the plugin.
When I build the app and deploy it, only then it does not.
It gives me AUR0016 error that has to do with the DI.

I assume that there might be a minor difference between the development and bundling/deployment configuration. However, I cannot be certain without seeing some code. If it is possible, please share a reproduction.

1 Like

Here is the repro:

Thanks for the repro. I understand the issue now. It is how the plugin is bundled. The plugin bundle consists the aurelia dependencies. You can verify that when you add the following to your webpack configuration.

    optimization: {
      concatenateModules: false,
    },

It looks like this

That is the reason, you are getting this error. The IEventAggregator used by your custom element is a different one (from the bundle) than that in your app.

I would suggest to not bundle your plugin at all. We did the same at work (w/o convention though).

Thank you. I suspected as much.
I intentionally left the default plugin settings, as using DI in plugins is a common thing. So in order not to bundle anything with the plugin, I moved all dependencies of a plugin to dev dependencies. Node modules is excluded by nodeExternals, but some css related artifacts still remain.
Anyways, there are no aurelia related modules bundled.


I still get the error.
Any pointers on how to configure webpack in this case would be greatly appreciated.

@Sayan751, thanks for the migration guide.

If I understand the the guide correctly, this is no longer possible?

import { IRouter, IRouteableComponent } from '@aurelia/router-lite';

export class MyComponent {
  public constructor(@IRouter private readonly router: IRouter) { }
}

(from router-lite docs)

Furthermore, should the official Stackblitz template (when creating a new github issue) be updated to support decorators again?

UPDATE:
Sorry, I’ve just seen your pull request regarding the docs (docs: update decorator usage by Sayan751 · Pull Request #1949 · aurelia/aurelia · GitHub)

@zeko77 I think that webpack for the plugin is not a good fit. You probably need rollup to create a bundle. At least that’s what is done for the @aurelia/X packages. Have a look at the au2 repo for the rollup configuration.
cc: @bigopon @huochunpeng

@elitastic Thanks for pointing out the starter templates. I will update those.

1 Like

Thank you. Will try and do that.
A working plugin template that utilizes DI would be great.
Will share if I succeed.

Agreed, Webpack is too much for plugin setup. While working on adding Vite support to our skeleton, I am also moving plugin template from webpack to vite (which uses rollup).

But there is some gap in our vite support, we need to work through that. It will take some time before we can ship official Vite based plugin skeleton.

1 Like

I made progress with vite and rollup.
Started with: Aurelia app - conventions - Vite - StackBlitz
Aurelia is stripped, and plugin with the DI shows up on deployed nginx server.
Alas, the decorators like @watch are not working with vite.

The issue is indeed different webpack bundling for production and development.
Dev bundle consistently uses aurelia.mjs packages everywhere, leading to correct behaviour of having a single container.
Production bundle includes both cjs and mjs versions of aurelia, leading to separate containers for app and the plugin.


Plugin’s output is in webpack is “umd” , as modules are still experimental.
Issue will be resolved with functioning vite/rollup based plugin template that outputs mjs for plugin.

And the solution is to add aurelia production aliases in webpack.config.js.
They should point to ../../esm/index.mjs, so:

 alias: production ? {
        // add your production aliases here
        ...getAureliaProdAliases()
      } : {
        ...getAureliaDevAliases()
        // add your development aliases here
      }
    },

and

function getAureliaProdAliases() {
  return [
    'aurelia',
    'fetch-client',
    'kernel',
    'metadata',
    'platform',
    'platform-browser',
    'route-recognizer',
    'router',
    'router-lite',
    'runtime',
    'runtime-html',
    'testing',
    'state',
    'ui-virtualization'
  ].reduce((map, pkg) => {
    const name = pkg === 'aurelia' ? pkg : `@aurelia/${pkg}`;
    try {
      const packageLocation = require.resolve(name);
      map[name] = path.resolve(packageLocation, `../../esm/index.mjs`);
    } catch {/**/ }
    return map;
  }, {});
}

As I would like to avoid bundling the aurelia dependencies altogether when bundling the plugin, I have added the aurelia dependencies to the externals in webpack config.

    externals: [
      // Skip npm dependencies in plugin build.
      production && nodeExternals(),
+     production && /^(aurelia)$/i,
+     production && /^(@aurelia\/.+)$/i,
    ].filter(p => p),

This seems to work for me.

I do the same. The issue does not lie within the plugin.
The plugin is bundled without any dependencies and compiled as umd library.
The issue is within the app consuming the umd plugin.
When you build the consuming app, webpack includes the mjs version of aurelia (used by the app), and cjs aurelia (used by the plugin).
Using the dev aliases for development build overrides this, and only mjs version of aurelia is used.
The same needs to be done for the production build, otherwise you end up with DI unable to resolve dependencies used in the plugin.

Sorry for the confusion. Misread your earlier post.

1 Like