17 Nov 2020Vue website builder

Vue website builder

Building a UI that allows creating and/or editing web pages is a task I took up at least once at every job I had. It always adds complexity — not only to the web page itself but also by requiring additional back end for HTML rendering. Today this complexity is already there in a form of modern UI libraries and build tools.

We will create an application that allows users to build simple web pages from preexisting parts.

For clarity the web pages that are the end product of the whole process will be referred to as Pages and their elements as Modules.

The goals

Non-goals

The plan

System composed of 3 parts:

Component Library(-ies)
Set of Vue components that accept custom data via props. Built in a way that allows loading them via HTTP.
User Interface
A Vue based web app. A view where components can be put together into a Page and filled with data. Think Guttenberg.
Exporter
A Node server. This will export Pages as standalone web pages.

Basic assumptions

After in depth analysis in search of possible problem areas I decided on a set of prerequisites:

Modules in Component Libraries must adhere to a standard
Editable props must be identifiable and accessible for UI to inject data.
UI and Exporter need a shared protocol
It has to fully express what the Page is. Data validation on both ends will greatly reduce hard to find bugs.
UI and Exporter need to have access to the identical component libraries
UI will fetch modules in UMD form via HTTP. Exporter can do the same or install whole library in requested version.
CLs, UI and Exporter need to share dependencies
We don't want to embed external libraries into CL modules.
Firstly this would ship external libraries (with their dependencies), eg. a third party gallery component, inside imported component and take away the chance for optimizing the package size in exporter.
Secondly, in case the module creation is outsourced we need to control what libraries are being used.

Summary

In the next 3 posts I will describe specific elements of this system, both in depth and in insolation. I am going to explain how assumptions above were expressed in the code. I will finish the whole series with another overview — how the design of the whole system influenced each of its parts, and what was done to avoid coupling the code too tightly.