Skip to content
This repository was archived by the owner on Jan 29, 2026. It is now read-only.

Commit 9b9ed1c

Browse files
committed
update to working state
1 parent b6efc13 commit 9b9ed1c

9 files changed

Lines changed: 84 additions & 88 deletions

File tree

examples/vue-router-ssr/package.json

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,12 @@
33
"private": true,
44
"type": "module",
55
"scripts": {
6-
"dev": "vite dev",
76
"build": "vite build",
8-
"preview": "NITRO_HOST=127.0.0.1 node .output/server/index.mjs"
7+
"dev": "vite dev",
8+
"preview": "vite preview"
99
},
1010
"devDependencies": {
11-
"@hiogawa/vite-plugin-fullstack": "0.0.2",
11+
"@hiogawa/vite-plugin-fullstack": "0.0.3",
1212
"@vitejs/plugin-vue": "^6.0.1",
1313
"nitro": "npm:nitro-nightly",
1414
"unhead": "^2.0.17",

examples/vue-router-ssr/server.ts

Lines changed: 0 additions & 1 deletion
This file was deleted.

examples/vue-router-ssr/src/framework/entry.client.ts renamed to examples/vue-router-ssr/src/entry-client.ts

Lines changed: 2 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,14 +1,10 @@
11
import { createSSRApp } from "vue";
22
import { RouterView, createRouter, createWebHistory } from "vue-router";
3-
import { routes } from "../routes";
3+
import { routes } from "./routes";
44

55
async function main() {
66
const app = createSSRApp(RouterView);
7-
8-
const router = createRouter({
9-
history: createWebHistory(),
10-
routes,
11-
});
7+
const router = createRouter({ history: createWebHistory(), routes });
128
app.use(router);
139

1410
await router.isReady();
Lines changed: 27 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -1,29 +1,24 @@
1-
import { mergeAssets } from "@hiogawa/vite-plugin-fullstack/runtime";
2-
import { createHead, transformHtmlTemplate } from "unhead/server";
31
import { createSSRApp } from "vue";
4-
import { RouterView, createMemoryHistory, createRouter } from "vue-router";
52
import { renderToString } from "vue/server-renderer";
6-
import { routes } from "../routes";
7-
import clientEntry from "./entry.client.ts?assets=client";
3+
import { RouterView, createMemoryHistory, createRouter } from "vue-router";
4+
5+
import { mergeAssets } from "@hiogawa/vite-plugin-fullstack/runtime";
6+
import { createHead, transformHtmlTemplate } from "unhead/server";
7+
8+
import { routes } from "./routes";
9+
import clientEntry from "./entry-client.ts?assets=client";
810

911
async function handler(request: Request): Promise<Response> {
10-
// setup app
1112
const app = createSSRApp(RouterView);
12-
13-
// setup vue-router
14-
// https://github.com/nuxt/nuxt/blob/766806c8d90015873f86c3f103b09803bd214258/packages/nuxt/src/pages/runtime/plugins/router.ts
15-
const router = createRouter({
16-
history: createMemoryHistory(),
17-
routes,
18-
});
13+
const router = createRouter({ history: createMemoryHistory(), routes });
1914
app.use(router);
2015

2116
const url = new URL(request.url);
2217
const href = url.href.slice(url.origin.length);
18+
2319
await router.push(href);
2420
await router.isReady();
2521

26-
// collect assets from current route
2722
const assets = mergeAssets(
2823
clientEntry,
2924
...(await Promise.all(
@@ -33,7 +28,9 @@ async function handler(request: Request): Promise<Response> {
3328
.map((fn) => fn!().then((m) => m.default)),
3429
)),
3530
);
31+
3632
const head = createHead();
33+
3734
head.push({
3835
link: [
3936
...assets.css.map((attrs) => ({ rel: "stylesheet", ...attrs })),
@@ -42,36 +39,34 @@ async function handler(request: Request): Promise<Response> {
4239
script: [{ type: "module", src: clientEntry.entry }],
4340
});
4441

45-
// SSR
46-
const ssrStream = await renderToString(app);
42+
const renderedApp = await renderToString(app);
43+
44+
const html = await transformHtmlTemplate(head, htmlTemplate(renderedApp));
45+
46+
return new Response(html, {
47+
headers: { "Content-Type": "text/html;charset=utf-8" },
48+
});
49+
}
4750

48-
// inject to HTML shell with head tags
49-
let htmlStream = `\
50-
<!DOCTYPE html>
51+
function htmlTemplate(body: string): string {
52+
return /* html */ `\<!DOCTYPE html>
5153
<html lang="en">
5254
<head>
5355
<meta charset="UTF-8" />
5456
<meta name="viewport" content="width=device-width, initial-scale=1.0" />
5557
<title>Vue Router Custom Framework</title>
5658
</head>
5759
<body>
58-
<div id="root">${ssrStream}</div>
60+
<div id="root">${body}</div>
5961
</body>
60-
</html>
61-
`;
62-
htmlStream = await transformHtmlTemplate(head, htmlStream);
63-
64-
return new Response(htmlStream, {
65-
headers: {
66-
"Content-Type": "text/html;charset=utf-8",
67-
},
68-
});
62+
</html>`;
6963
}
7064

7165
export default {
7266
fetch: handler,
7367
};
7468

75-
if (import.meta.hot) {
76-
import.meta.hot.accept();
77-
}
69+
// TODO
70+
// if (import.meta.hot) {
71+
// import.meta.hot.accept();
72+
// }

examples/vue-router-ssr/src/routes.ts

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
import type { RouteRecordRaw } from "vue-router";
22

3-
// custom framework may employ fs router convention to reduce boilerplace.
43
export const routes: RouteRecordRaw[] = [
54
{
65
path: "/",
File renamed without changes.
Lines changed: 21 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
import fullstack from "@hiogawa/vite-plugin-fullstack";
1+
import { assetsPlugin } from "@hiogawa/vite-plugin-fullstack";
22
import vue from "@vitejs/plugin-vue";
33
import { defineConfig, type Plugin } from "vite";
44
import devtoolsJson from "vite-plugin-devtools-json";
@@ -9,32 +9,25 @@ export default defineConfig((_env) => ({
99
plugins: [
1010
patchVueExclude(vue(), /\?assets/),
1111
devtoolsJson(),
12+
patchAssets(assetsPlugin()),
1213
nitro(),
13-
// NOTE: fullstack needs to come after nitro since
14-
// it uses `buildApp` to output assets manifest file.
15-
fullstack({ serverHandler: false, serverEnvironments: ["nitro"] }),
1614
],
1715
environments: {
1816
client: {
1917
build: {
20-
rollupOptions: {
21-
// NOTE:
22-
// fullstack plugin's client entry discovery is not supported
23-
// since Nitro build order is `client` environment -> `nitro` environment.
24-
input: "./src/framework/entry.client.ts",
25-
},
18+
rollupOptions: { input: "./src/entry-client.ts" },
2619
},
2720
},
28-
nitro: {
21+
ssr: {
2922
build: {
30-
// TODO: Nitro doesn't set this up?
31-
outDir: ".output/server",
23+
rollupOptions: { input: "./src/entry-server.ts" },
24+
outDir: ".nitro/vite/services/ssr",
3225
},
3326
},
3427
},
3528
}));
3629

37-
// workaround https://github.com/vitejs/vite-plugin-vue/issues/677
30+
// Workaround https://github.com/vitejs/vite-plugin-vue/issues/677
3831
function patchVueExclude(plugin: Plugin, exclude: RegExp) {
3932
const original = (plugin.transform as any).handler;
4033
(plugin.transform as any).handler = function (this: any, ...args: any[]) {
@@ -43,3 +36,17 @@ function patchVueExclude(plugin: Plugin, exclude: RegExp) {
4336
};
4437
return plugin;
4538
}
39+
40+
// Ensure order: Client => SSR => [manifest] => Nitro
41+
function patchAssets(plugin: any[]): any {
42+
const assetsPlugin = plugin.find((p) => p.name === "fullstack:assets") as any;
43+
44+
const buildAppHook = assetsPlugin.buildApp.handler;
45+
assetsPlugin.buildApp = async (builder: any) => {
46+
await builder.build(builder.environments.client);
47+
await builder.build(builder.environments.ssr);
48+
await buildAppHook(builder);
49+
};
50+
51+
return plugin;
52+
}

package.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@
1111
"lint:fix": "automd && prettier -w ."
1212
},
1313
"resolutions": {
14-
"nitro": "npm:nitro-nightly@3.0.1-20251015-103211-44b2f091",
14+
"nitro": "npm:nitro-nightly@3.0.1-20251015-114932-a0f52cc9",
1515
"vite": "^7.1.0"
1616
},
1717
"devDependencies": {

pnpm-lock.yaml

Lines changed: 30 additions & 30 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)