skip to Main Content

I want to create a single page application using either React, Vue or Sveltekit ( other suggestions for tools that get the job done are welcome! ). This SPA will be embedded inside an iframe provided by an external system. The SPA calculates a dynamic table based on a configuration file. The configuration file tells the SPA which cell renderer to use for each column cell.

There are many cell renderers provided by default but there are some customized cell renderers only a few customers want to use ( and willing to pay for it ) . I don’t want to have a directory e.g. /renderers/core and /renderers/custom and later contains a highly customized component like RainbowCellRendererForCustomerFoo

I would prefer a separate repository ( or Monorepo ) for each cell renderer and consume them in the SPA. But I don’t want to install all the custom renderers via npm because I only want to ship the necessary ones. During configuration ( before running the CI pipeline ) we know

  • which cell renderers are needed
  • everything is using the same technology, Vite + e.g. Sveltekit

So we have 1 – n bundles of cell renderers and want to create a bundle for the main app. Is it possible that this main app is able to consume the cell renderer bundles during runtime? If not, is it possible to "inject" the cell renderer bundle into the main app bundle inside the CI pipeline?

  • I don’t know if it’s important that the main app and each cell renderer share the same app instance
  • I want to pass through props to the components and if possible also communicate with the cell renderers ( via function props, events, … ) because some of them might provide some action buttons for example

I think I’m looking for something like a plugin system. I don’t know if web components might help, never tried them. I hope this is more a Vite based question, regardless of the web framework.

I thought about "merging" the custom cell renderers into the main app during bundle time. I think the only way to do that is to install the components inside the CI pipeline and hope that Vite picks them up, although they aren’t used inside the main code.

Do you have any ideas? Please let me know if you need any more information!

2

Answers


  1. Chosen as BEST ANSWER

    I think I solved it for my case but I will have to publish each customized component library to our private npm registry.

    For the sake of simplicity I will show example code using VueJs and the component library https://github.com/tailwindlabs/heroicons

    I created a new Vue app and replaced the code inside App.vue with

    <script setup lang="ts">
    import { ref, onMounted, defineAsyncComponent } from "vue";
    
    const myComponent = ref<unknown>(null);
    
    onMounted(async () => {
      myComponent.value = defineAsyncComponent(async () => {
        const components = await import("@heroicons/vue/24/solid"); // library path coming from configuration file
    
        return components['CheckIcon']; // target component name coming from configuration file
      });
    })
    </script>
    
    <template>
      <div>See component below:</div>
      <component v-if="myComponent" :is="myComponent"></component>
      <div v-else>-</div>
    </template>
    

    Please keep in mind that this is just an example. The paths and component names are coming from a configuration file. So this code would not build during development.

    Inside the CI pipeline I just have to make sure I install all the required component libraries ( @heroicons/vue for this case ) before building the application and providing a distribution ( e.g. by reading configuration input and looping through it ).


  2. You can implement the plugin system using webpack module federation. WMF allows you to connect remote bundles during the runtime of the main app. It doesn’t depend on any framework, so you can use the one you want. Moreover, WMF has the repo that illustrates how it can be used with different frameworks (and Vite support)

    Login or Signup to reply.
Please signup or login to give your own answer.
Back To Top
Search