Multiple SPA Entry Points with a Single Codebase

  • I have an existing Vue.js codebase that is growing long in the tooth and I’m looking at Quasar as a possible replacement for something that will help me build and replace the existing functionality with minimal disruption while improving the overall maintainability.

    For the moment, at least, I need the SPA build mode, and I ultimately only care about the generated JavaScript, because the generated JS will be served by a Phoenix (Elixir) app.

    One of my apps has about 30% of the functionality of the other, but shares 90% of the Vue.js components and style of the other. (One is a customer view, the other is an administrative view; the administrative view is much richer.)

    Has anyone done this with Quasar? I found a post on multiple entry points, but the answers really didn’t make sense to me.

    Quasar looks really impressive, and I think it would be quick for me to port over the functionality that I have…but I must generate multiple JS entry points (served by two different Phoenix endpoints).

  • Well, the methods in the post you mentioned still stands. If it is a single big app just with some different starting points, then I still think that solutions with reverse proxy or vue router are adequate.

    However - if in your case the “multiple entry” means in reality also “BIG duplication of code”, then that is another problem. As for now, there are at least two viable solutions:

    1. keep your shared code in git submodules:
      It works VERY well when such a code is changed more often, or it is not specifically something which works as a module (for example - shared data). In extreme situation you can have multiple Quasar projects with almost everything in the shared git submodules.

    2. use package manager npm/yarn and encapsulate your shared code in their own package. This package DOES NOT need to be public! You can use package.json features and import your package from your own git repository (even private) or even from file system. The possibilities are huge. The only drawback is that every change in this package needs some more operations to propagate to your main app but the big win is, that it is much more testable and verifiable (because of this encapsulation). Another positive option is that you can have your own private npm registry.

  • It’s two separate apps. One is for customers (reached with one URL) and one is for employees/admins (reached with another URL). They are looking at the same data. They are using (mostly) the same Vue components. They are using different Vue routers (because the routes for employees are not valid for customers).

    There are some differences in some components, but a simple application of vue router or a reverse proxy is insufficient—some routes are never to be hit by the customer application. If they are, a programming error could trivially show things that are not intended to be seen by customers. (More: the employee app is served in ways that require the use of a VPN or other trusted network.)

    So, I already have two different routes representing two different apps built from 90% the same code. What I don’t want to do is maintain two different codebases. I already have this in place with Rollup (and previously with Brunch), and it’s not any harder with Webpack excepting the miasma of Webpack configuration to begin with.

    I like what I see with Quasar, but I don’t see a way to do what I need in the codebase that I already have. Git submodules and packages aren’t the answer; this is already well-organized code for building (just not so much for extending). I think you had some good ideas for extending, but I was hoping that there had been some progress toward this in the last six months.

    To your list, I would also add that it would be nice to have something like quasar build --dev --watch --stdin (similar to the watch mode for Webpack itself, since that’s what Phoenix uses by default).

  • @halostatue yeah, existing codebase can be nasty, but if I were in your shoes, than definitely I would create TWO quasar projects with at least three repositories. From what you write, in spite of code similarities, the domains for them are quite different. For example your customer app probably will drift to some kind of PWA instead of SPA, while your employee/admin, vpn guarde, local app, probably will drift to be some kind of desktop electron app. I dont think that there will be more viable solutions than multiple projects, git submodules for shared code, private npm registry etc. I may be wrong, but you do not have a problem with distribution, deployment. You are worrying about code base maintenance and future enhancements. There is a saying that every bigger system reflects the organizational structure known and used to his designers 🙂 I have a hunch, that this could be relevant in your situation.

  • Neither of these will be moving from SPA to PWA or Electron apps at any point in the future; we have bespoke customer apps that do things that neither of the web applications do. The majority of the app is our Elixir application, providing GraphQL and RESTful APIs to four different client applications (Android, iOS, Customer Web, and Employee Web).

    What I have is a problem with maintenance of the Vue.js app because it was built in part by a team who was learning Vue.js and Elixir at the same time and chose some poor directions in the first place, and then have had to grow it since then with a variety of engineers.

    I did open (a now closed) issue, #6936 raising this question, and it’s pretty easy to add a second entry point to the Webpack config, but I think that your suggestion of returning an array of configs is better in the long run because that would allow the generation of multiple .quasar/client-entry.js files for each actual entry point.

    We’re not looking at having this served by anything except the Elixir application (we have all of our CSP, IP whitelisting, and other server security code there; we would need to replicate that in any other system).

    I’m looking at Quasar or Vuetify as easy ways to handle some of the structure and design, and while Quasar looks really good, I think I’ll need to look at Vuetify for what I need because it doesn’t require a different way of thinking. I’m not saying I won’t look at Quasar in the future, because it’s pretty impressive. But it’s definitely not something that looks like it can currently slot into an existing project cleanly.

  • Admin

    @halostatue Since you’re adding a custom entry point, if you want to be similar with .quasar/client-entry.js then just copy it into your /src/<…> somewhere and set that as your extra entry point…

    Also, if you’re looking into embedding Quasar into an existing project, you might also want to check out the UMD version of Quasar.

  • When is .quasar/client-entry.js regenerated, so that it’s clear when I should update things? I’m not looking at using Quasar as a UMD, because I’ve already got a solid build and delivery process. I’m mostly looking at what’s required to do what I need to build multiple entry points with Quasar.

Log in to reply