single-spa / single-spa.js.org

Home Page:https://single-spa.js.org/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

Add more example repos for using Vite as the bundler

AustinZhu opened this issue · comments

Hello, we are a developer team from Japan. Recently we are evaluating the usage of Vite in developing our single-spa based Web application.

However, there is only one example on your website, and that one is written in JavaScript. So my colleague (credits to @YHhaoareyou) made some example repos using Vite and TypeScript.

TypeScript&React
TypeScript&Vue
root-config

Please consider adding them to the documentation page. It might help people who love both single-spa and Vite!

Thank you for sharing these! I've noticed an uptick in questions from people in the Slack channel with regards to Vite, and am interested in improving support for it. These examples could be included in the Community Examples section.

However, one concern that I have that no one else has been able to give me a good answer to is how this should interop with the current single-spa Recommended Setup. Using import maps allows us to have many advanced features that would be lost without it. But as I currently understand it, Vite for development uses all ES modules which don't interop with SystemJS without an ESM extra (and even then, with limitations; see also systemjs/systemjs#2187 and systemjs/systemjs#2013). For production, bundles are created using the output configuration (usually system) so it is a completely different module format. I've been conversing about it in the Slack workspace with others and that difference between dev/prod is the biggest hangup. At least for me due to what little I know about some best practices.

In an ideal world ESM would just work with import maps (as it is a spec that is still being adopted/implemented by browsers). In order to have that today, es-module-shims is an option and would enable an all-ESM setup that matches the current Recommended Setup. I've been ideating about this but haven't yet had any time to dedicate to actually exploring/implementing something like this. By way of information, es-module-shim is also authored by the same person as SystemJS.

commented

Thank you for your kind response and comments!

In the project we are actually working on now, I guess we just made it to use es-module-shims with single-spa in development, and we even migrated our root-config from webpack to vite as well, but we haven't tested it in production.

I haven't made the same changes in the example repos shared above. After I update those example repos, I will create a PR so that you can consider including it in single-spa.org's Community Examples section.

For now, if you would like to, you can refer to the project we are actually working on. And also I am sharing at the end of this comment the key changes for adopting es-module-shims in our project.

We are still not sure if this a preferred solution and if this even matches what you mentioned in your comment, and we would like to know if you have other suggestions.


Key changes for adopting es-module-shims are shared below.

index.html of our Root-config (root/src/index.html):

<script async src="https://ga.jspm.io/npm:es-module-shims@1.5.4/dist/es-module-shims.js"></script>
...
<script type="importmap-shim" defer>
    {
      "imports": {
        "@wasedatime/root-config": "//localhost:9000/wasedatime-root-config.ts",
        "@wasedatime/syllabus": "//localhost:8080/wasedatime-syllabus.ts",
        "@wasedatime/campus": "//localhost:8081/wasedatime-campus.ts",
        "@wasedatime/career": "//localhost:8082/wasedatime-career.ts"
      }
    }
</script>
...
<template id="single-spa-layout">
    <single-spa-router>
      <div id="layout">
        <div id="nav"></div>
        <main>
          <route path="courses">
            <application name="@wasedatime/syllabus"></application>
          </route>
          <route path="campus">
            <application name="@wasedatime/campus"></application>
          </route>
          <route path="career">
            <application name="@wasedatime/career"></application>
          </route>
          <route default>
            <application name="@wasedatime/root-config"></application>
          </route>
        </main>
      </div>
    </single-spa-router>
  </template>

Entrypoint of our Root-config (root/src/wasedatime-root-config.ts):

...
const routes = constructRoutes(document.querySelector("#single-spa-layout"));
const applications = constructApplications({
  routes,
  loadApp: ({ name }) => import(
    /* @vite-ignore */
    // @ts-ignore
    name
  ),
});
const layoutEngine = constructLayoutEngine({ routes, applications });
...

This is fantastic! thank you so much for sharing! I'll be looking for some time to refine/document this setup so that it aligns/mirrors the single-spa Recommended Setup as much as possible. I'm currently working on single-spa-react 18 changes so it'll be a while, but I'm really hoping to get some time allocated at work (somehow) to dedicate to this.