aniftyco / kubit

Full stack web framework for Node.js

Home Page:https://kubitjs.com/

Geek Repo:Geek Repo

Github PK Tool:Github PK Tool

View Render Manager

joshmanders opened this issue · comments

Right now the view component just supports Edge templates, but we want to abstract it into a manager pattern to support other rendering methods.

This is because Kubit being a traditional MVC backend framework written in JavaScript/TypeScript we're in a unique position to support other view layer renderers such as a React or Vue or even Svelte renderer allowing us to bridge the backend and frontend in truly cohesive ways that neither the modern JavaScript based frontend nor traditional backend frameworks ever fathomed.

First we'll add support for using Vue Single File Components (SFC) as a template renderer to return the string contents directly to the browser, but ultimately the end goal is to support full SSR and client side rehydration of modern frameworks like Nuxt, Remix, and Astro, utilizing the Astro Island architecture for client rehydration by using the defer keyword on a <script setup> tag.

So take the following example code

resources/views/components/Greeter.vue:

<script setup defer lang="ts">
import { ref, onMounted } from 'vue'

const { name = 'World' } = defineProps<{ name?: string }>();

onMounted(() => {
  setTimeout(() => ref.value.innerText = `I'm Batman!`, 1000)
});
</script>

<template>
<h1 ref="greeter">Hello, {{ name }}</h1>
</template>

<style scoped>
.h1 { color: red }
</style>

Then you had this page view

resources/views/pages/home.vue:

<script setup lang="ts">
import Greeter from '../components/Greeter';

const { name } = defineProps<{ name: string }>();
</script>

<template>
  <Greeter :name="name" />
</template>

And you called it in your controller or route handler like so

return view.render('pages/home', { name: 'Josh' });

What would happen here is we would detect that the view home maps to resources/views/pages/home.vue and specifically see the file extension is .vue and it would then render this view using the Vue Renderer. So that would render the home.vue page, which would see that it imports Greeter component. Render the static html string server side, and generate a manifest to load what JavaScript in the browser because the <script startup defer> in the Greeter would tell the Renderer that it has client interactivity and thus needs to inject the necessary JavaScript for that component to hydrate and render client side, which after 1 second would change the contents from "Hello, Josh" to "I'm Batman!".