Best way to manage multiple 'mini SPAs'

I’ve been developing a large Aurelia app for some time and love the framework. It’s being built via the CLI with webpack as a ‘standard’ single page app.

After a recent company merger we’ve decided that the new partner company will start developing in Aurelia for new functionality to take advantage of the component suite that we’ve already built up to get standard styling and functionality between components.

Our new partners currently cannot move to developing everything as a SPA as there are security mechanisms that are dependent on full page refreshes that we cannot overcome at the moment, so we are looking to implement new functionality as mini SPA’s on each new page.

The long term goal will be for the entire application to be a SPA, but it will take time to get there.

In the meanwhile, I’m wondering what the best approach for building and bundling each of the mini SPA’s, so that we can take advantage of the components that we’ve already written. Is there any way we could structure the webpack or CLI bundler builds to cater for this scenario?
Would I need to have a build for each mini-SPA?

The source code for both applications will be in separate folders, so multiple webpack configs would be possible.

3 Likes

While this may be possible now, I’m almost certain I saw mention that it would be easy to do in Aurelia v2. I suggest reading the latest Aurelia v2 blog post.

1 Like

Will all the mini SPAs be built at the same time? If so, it sounds simple to me. If not, then there needs to be a way to tell the mini SPAs where/how to load the Aurelia core modules

1 Like

Yes, they will all be built at the same time both locally and in the build server.
At the moment I’m considering having just one build so that Aurelia, vendor chunks and shared components etc. can leverage better caching.

Then each server rendered page would pass in the root file to use for that mini spa.

Are there other/better options?

1 Like

I’m not sure what would be the better option. What you got there is statically declared entry points for your app. You can also dynamically switch the right entry bundle at runtime. something like this in your main:

export function configure(aurelia: Aurelia) {
  // standard stuff
  aurelia.globalResources([
    // some conditional resources
    useGrid
      ? PLATFORM.moduleName('path/to/grid', /* make sure this one is same across references */ 'grid-bundle')
      : null
  ].filter(Boolean))

  let entryBundle: string;
  switch (getPageName()) {
    case 'login': entryBundle = PLATFORM.moduleName('path/to/login/form', 'login-form-bundle');
    ....
  }
  aurelia.setRoot(entryBundle, document.querySelector('#app-root'))
}

You can also leverage aurelia script, if it’s the legacy environments that you need to support. You can have a look here Aurelia Script - Isn't it supposed to be dead simple?

If you run those mini SPA’s in same-origin iframes then you should be able to run multiple standalone v1 apps simultaneously without issues. This goes for pretty much anything though. Same-origin iframes give you the benefit of realm isolation (meaning e.g. array observation patching the Array prototype can’t get messed up by multiple initializations) while still allowing you to share non-serializable state.

1 Like