Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(vue-server): server/client convention #9

Merged
merged 11 commits into from
May 12, 2024
12 changes: 9 additions & 3 deletions vue-server/src/demo/entry-browser.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,15 @@ import "./style.css";
import { tinyassert } from "@hiogawa/utils";
import { createSSRApp, defineComponent, provide, readonly, ref } from "vue";
import { type SerializeResult, deserialize } from "../serialize";
import * as referenceMap from "./routes/_client";
import { createReferenceMap } from "./integrations/client-reference/runtime";

function main() {
async function main() {
if (window.location.search.includes("__nojs")) {
return;
}

const initResult: SerializeResult = (globalThis as any).__serialized;
const referenceMap = await createReferenceMap(initResult.referenceIds);

const Root = defineComponent(() => {
const serialized = ref(initResult);
Expand All @@ -22,7 +23,12 @@ function main() {
url.searchParams.set("__serialize", "");
const res = await fetch(url);
tinyassert(res.ok);
serialized.value = await res.json();
const result: SerializeResult = await res.json();
Object.assign(
referenceMap,
await createReferenceMap(result.referenceIds),
);
serialized.value = result;
isLoading.value = false;
});

Expand Down
19 changes: 3 additions & 16 deletions vue-server/src/demo/entry-server.tsx
Original file line number Diff line number Diff line change
@@ -1,8 +1,7 @@
import type { ViteDevServer } from "vite";
import { createSSRApp, defineComponent } from "vue";
import { renderToString } from "vue/server-renderer";
import { deserialize, serialize } from "../serialize";
import * as referenceMap from "./routes/_client";
import { createReferenceMap } from "./integrations/client-reference/runtime";
import Layout from "./routes/layout";

export async function handler(request: Request) {
Expand All @@ -21,10 +20,11 @@ export async function handler(request: Request) {
});
}

const referenceMap = await createReferenceMap(result.referenceIds);
const Root = () => deserialize(result.data, referenceMap);
const app = createSSRApp(Root);
const ssrHtml = await renderToString(app);
let html = await importHtmlTemplate();
let html = (await import("virtual:index-html" as string)).default as string;
html = html.replace("<body>", () => `<div id="root">${ssrHtml}</div>`);
html = html.replace(
"<head>",
Expand Down Expand Up @@ -68,19 +68,6 @@ const Router = defineComponent<{ url: URL }>(
},
);

declare let __vite_server: ViteDevServer;

async function importHtmlTemplate() {
let html: string;
if (import.meta.env.DEV) {
html = (await import("/index.html?raw")).default;
html = await __vite_server.transformIndexHtml("/", html);
} else {
html = (await import("/dist/client/index.html?raw")).default;
}
return html;
}

// https://github.com/remix-run/remix/blob/7f30f0bc976f0b97a020e81be33f90f68d4e527a/packages/remix-server-runtime/markup.ts#L7-L16
function escpaeScriptString(s: string) {
return s.replace(ESCAPE_REGEX, (s) => ESCAPE_LOOKUP[s as "&"]);
Expand Down
19 changes: 19 additions & 0 deletions vue-server/src/demo/integrations/client-reference/runtime.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
import type { ReferenceMap } from "../../../serialize";

export async function createReferenceMap(ids: string[]): Promise<ReferenceMap> {
return Object.fromEntries(
await Promise.all(ids.map(async (id) => [id, await resolveReference(id)])),
);
}

async function resolveReference(id: string) {
const [file, name] = id.split("#");
let mod: any;
if (import.meta.env.DEV) {
mod = await import(/* @vite-ignore */ file);
} else {
const mods = await import("virtual:client-references" as string);
mod = await mods.default[file]();
}
return mod[name];
}
18 changes: 2 additions & 16 deletions vue-server/src/demo/routes/_client.tsx
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
"use client";

import { tinyassert } from "@hiogawa/utils";
import { defineComponent, inject, onMounted, ref } from "vue";
import { registerClientReference } from "../../serialize";

export const ClientCounter = defineComponent(() => {
const count = ref(0);
Expand Down Expand Up @@ -105,18 +106,3 @@ export const Hydrated = defineComponent(() => {
});
return () => <span>{`[mounted: ${mounted.value}]`}</span>;
});

// TODO: transform
registerClientReference(ClientCounter, "ClientCounter");
registerClientReference(ClientNested, "ClientNested");
registerClientReference(Link, "Link");
registerClientReference(Form, "Form");
registerClientReference(GlobalProgress, "GlobalProgress");
registerClientReference(Hydrated, "Hydrated");

import ClientSfc from "./_client-sfc.vue";
import ClientSlot from "./_slot.vue";
registerClientReference(ClientSfc, "ClientSfc");
registerClientReference(ClientSlot, "ClientSlot");

export { ClientSfc, ClientSlot };
3 changes: 2 additions & 1 deletion vue-server/src/demo/routes/page.tsx
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import { defineComponent } from "vue";
import { ClientCounter, ClientNested, ClientSfc } from "./_client";
import { ClientCounter, ClientNested } from "./_client";
import ClientSfc from "./_client-sfc.vue";

export default defineComponent(async () => {
return () => (
Expand Down
2 changes: 1 addition & 1 deletion vue-server/src/demo/routes/sfc/page.server.vue
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
<script setup lang="ts">
import { ClientSlot } from "../_client";
import ServerSlot from "../_slot.server.vue";
import ClientSlot from "../_slot.vue";
</script>

<template>
Expand Down
Loading