I am working on a new project which is just a page builder prototype idea for my company and I wanted to be able to allow users to create their own components and even header/footer replacement components if the user wants that level of control.
I have done some research into async components but this does not look to fit my cause (but I could be wrong) and also dynamic components using the
<component is="example" /> tag which I am using currently. I have a few ideas but I would really like to get some suggestions or feedback on my plan.
So in a nutshell, the app itself is a page builder built using Vue.JS, as part of the builder, you will get various pre-built components, the standard components a page builder would need, but I would like to add support for users to create their own components so they can add stuff specific to their needs. Solutions I have seen use PHP to apply components in and then render them in differently, but with my solution it is all built as a PWA/SPA within VueJS using the Vue CLI. Now the backend that is in use is Node.JS which is a REST API. The admin panel is where a user can create a Vue single file component and then saving it will send it to Node and store it.
So my question is how would you approach this problem?
In my head the way I was thinking of making it work, is for custom components, I will have a JSON object that contains the local registry of components, if a component is not defined in the local registry, then I must ask the server for the component, and my current idea is that to solve the issue, on save of the file, I shall pre-compile the component into a JS file with automatic registration with Vue and then save a link to that file against the object containing the custom component, when the front-end requests the component, I shall respond with the JS path, and make the application create a script tag, insert that JS file path, and once loaded, then initialise the component so it can be used.
Now this method I think would work, but I fear that the time it takes to download and execute the JS file and then render it into the page, could take a while, especially on slow connections which would overall affect page load, as I will need to wait for all custom components, there could me many, to load in before I can render the user created page with the custom components, otherwise I would get errors and that is where it could get slow, now I have seen I could use something like async components, but that looks to be through Vue router? which of course because none of this is hardcoded, I feel this would not work how I am hoping.
The next issue with the above is that if a user was to create a custom Header/Footer, and use that, then the SPA must be able to have that readily available because page contents you can get away with as long as it’s not too long, but a header, is something that should be there instantly.
The alternative solution, is to dynamically update a JS file that would import the additional components a user has created and then pre-compile the whole SPA with the custom components, but I feel this is a work around and not a clean way of doing it.
To note the dynamic page structure is a JSON tree of components, think of a VERY high level DOM defining the Vue component, any options and settings, including classes, attributes, and additional data that has been defined by the user. All requests will be cached against localStorage with expiry times to try and stop unnecessary network requests.
If you have any feedback on the above two ideas, and which one you would suggest is better or even a better suggestion, I am all ears, I have been pondering this for a while and I don’t want to make any changes just yet until I have a definitive answer that I know is worth a shot, because it MUST be possible, I just am not sure on which one is better, personally I am leaning towards idea 2, as I am writing this because it seems more logical and should not affect performance, as much as I don’t like the idea of the backend having write access to the frontend files, I think it’s the most plausible way of doing it out of the two.