Best way to structure a large multi-SPA solution?

We have about ~90 Durandal SPAs, all running in a custom build harness with a shared grunt build chain and shared knockout components. I’m currently looking into the right way to start moving some of them to Aurelia.

What is the recommended approach for having multiple Aurelia SPAs in one solution (I mean solution in a project folder structure sense, not a Visual Studio sense) ? I’m looking to keep the components as Knockout components, to allow for their use across both our Durandal and Aurelia SPAs.

1 Like

Something like this you are wanting?

  • Root Project
    • aurelia_project
    • node_modules
    • apps
      • site1
        • index.html
        • src
      • site2
      • site3
1 Like

That is pretty much what I’m thinking, but the current project has this structure:

  • Root Project
    • assets
      • scripts
      • css
    • components
    • node_modules
    • SinglePageApps
      • Durandal_SPA1
      • Durandal_SPA2

This structure is what I am leaning towards:

  • Root Project
    • assets
      • scripts
      • css
    • components
    • node_modules
    • AureliaApps
      • aurelia_project (aurelia-cli deps)
      • apps
        • Aurelia_SPA1
        • Aurelia_SPA2
      • node_modules
    • SinglePageApps
      • Durandal_SPA1
      • Durandal_SPA2
1 Like

This may not be exactly what you are looking for. However, this is one package https://github.com/CanopyTax/single-spa, which enables running multiple SPAs side-by-side. This basically provides a framework to conditionally bootstrap a particular SPA app. This is valid if every one of your app can work alone isolation.

Another approach is to have your apps as aurelia plugin and create a “hosting” that registers those app as plugin. With this approach, the route table defined in the main hosting app only points to the components of the child app which in turn sets the route table for one single child app.

Hope this helps.

1 Like

I think that he wanting to switch out what app is built and deployed dynamically which I would think would happen by something like this

WARNING ALL PSEUDO B

Root Project

  • assets
    • scripts
    • css
  • components
  • node_modules
  • AureliaApps
    • aurelia_project (aurelia-cli deps)
    • main.(ts|js)
    • apps
      • Aurelia_SPA1
      • Aurelia_SPA2
    • node_modules
  • SinglePageApps
    • Durandal_SPA1
    • Durandal_SPA2

Now chain a task to your build process that switches out the application root in main to the application that you are looking to build/deploy

import { Aurelia } from 'aurelia-framework';

export async function configure(aurelia) {
  aurelia.use
    .standardConfiguration()
    .developmentLogging();

  await aurelia.start();

//Dynamically switch out the root using task by passing in this value dynamically
  await aurelia.setRoot('./app/Aurelia_SPA1/app', document.body);
//   await aurelia.setRoot(#app#,  document.body);
}

scripts :{
build: gulp build; au build
}

var argv = require('yargs').argv;
gulp.task ('build', function () {
    gulp.src (["./main.ts"])
        .pipe (replace (/setRoot\((.*),/g, argv.app)
        .pipe (gulp.dest ('./'))
});
npm build -- --app ./apps/Aurelia_SPA1/app
1 Like

@Sayan751 not quite what I am attempting to do, I (usually) only run one SPA at a time.

@brandonseydel in my Durandal SPAs I currently have an ASPX page which hosts the SPA, and dynamically loads the SPA based on the page route. I use grunt to build all the SPAs on the build server.

Your example is pretty much what I have running locally now with Aurelia, so good to see someone else confirming this. :+1:

3 Likes