Create special DI registration instance based on environment variable with webpack

I have code that looks like this in an older project. it works great. I’m now using webpack and I made the changes to the the module path to be PLATFORM.moduleName(). I can see the correct module get loaded, but when I go to use IModule in the application it’s not the correct instance. IModule is a stubbed out class that the mock and real version extend.

function configureContainer(aurelia) {
let moduleId = environment.mock ? "mockModule": "realModule"
         aurelia.loader.loadModule(moduleId).then(module => {
        aurelia.container.registerSingleton(IModule, module.MyModule);

How can I do something like this with webpack? It’s as if my registration is being overwritten later on.

1 Like

Mind you are using a promise, try return the promise so configureContainer knows it needs to wait on it.

Somehow when you return configureContainer (your method?) in configure (aurelia convention), needs to return the promise as well.

1 Like

My real implementation actually has this method in an async method that is awaited during aurelia config. I actually reverted back to this thinking i was doing something wrong. I copied this from my old project as an example. I’m not sure what is difference is between the webpack project and my old cli project using requirejs.

1 Like

The aurelia-loader-webpack definitely behaves differently as webpack is not a dynamic loader.

You can try static typing, it will end up with bigger shipping bundle, but doesn’t hurt I guess.

import {MyModule as MyModuleMock} from 'mockModule';
import {MyModule} from 'realModule';

function configureContainer(aurelia) {
    IModule, environment.mock ? MyModuleMock : MyModule

Of course I just made a simple test and it works fine…

1 Like

This is what works

/// <reference types="aurelia-loader-webpack/src/webpack-hot-interface"/>
// we want font-awesome to load as soon as possible to show the fa-spinner
import { Aurelia } from 'aurelia-framework'
import environment from './environment';
import { PLATFORM } from 'aurelia-pal';
import * as Bluebird from 'bluebird';
import { IDataAdapter } from 'IDataAdapter';

// remove out if you don't want a Promise polyfill (remove also from webpack.config.js)
Bluebird.config({ warnings: { wForgottenReturn: false } });

export async function configure(aurelia: Aurelia) {
  // let aureliaConfiguration = new AureliaConfiguration();
  // aureliaConfiguration.configure(aurelia);

 await configureContainer(aurelia); 


  // Uncomment the line below to enable animation.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-animator-css'));
  // if the css animator is enabled, add swap-order="after" to all router-view elements

  // Anyone wanting to use HTMLImports to load views, will need to install the following plugin.
  // aurelia.use.plugin(PLATFORM.moduleName('aurelia-html-import-template-loader'));

  aurelia.use.developmentLogging(environment.debug ? 'debug' : 'warn');

  if (environment.testing) {

  return aurelia.start().then(() => aurelia.setRoot(PLATFORM.moduleName('app')));

async function configureContainer(aurelia: Aurelia) {
  let mock = true;
  let mPath = mock? PLATFORM.moduleName("mockDataAdapter") : PLATFORM.moduleName("dataAdapter");

  let module = await aurelia.loader.loadModule(mPath);
  aurelia.container.registerSingleton(IDataAdapter, module.DataAdapter);
1 Like

Update to my issue. My code is esentially exactly the way this is. I can grab the proper instance from the container if i do aurelia.containter.get(IDataAdapter) right after registration, but when I actually get it in a view model I want to use it in, it’s grabbing the actual IDataAdapter which is a stubbed out class that I’m using like an interface

UPDATE: It was because I somehow had a copy of an old class which was the one I was actually importing :frowning:

1 Like