Setup for Client and Server in Separate Projects #1406
-
Hi, In many Vike/Vue examples, the Vue client and Node/Express server are part of the same project. However, our setup involves separate projects for the Vue client and Node/Express server, each with its own Here's how I understand the integration should work:
My confusion lies in the following:
Is there an example or boilerplate showing this kind of client-server separation for a Vike/Vue project? Any guidance or best practices would be greatly appreciated. Thanks, |
Beta Was this translation helpful? Give feedback.
Replies: 3 comments 5 replies
-
Vite doesn't support splitting a It's difficult to guide you without know more about your app. From what you wrote, it seems that the question is whether you want to pre-render or not, see https://vike.dev/pre-rendering. |
Beta Was this translation helpful? Give feedback.
-
@brillout sorry, after thinking more about this I think it is more clear: This is the folder structure:
So the client/server is the SSR server and is in the same project/vite.config.js. The server is just a REST API server and won't have anything to do with vue/vite/vike. Based on the above structure we have this 3 requirements:1. client > src > App.vue:
2. client > src > Login.vue:
3. client > src > Page.vue:
Does this make sense? |
Beta Was this translation helpful? Give feedback.
-
Honestly you're thinking too much about it, I use fastify and this is how my server/index.ts file is // This file isn't processed by Vite, see https://github.com/vikejs/vike/issues/562
// Consequently:
// - When changing this file, you needed to manually restart your server for your changes to take effect.
// - To use your environment variables defined in your .env files, you need to install dotenv, see https://vike.dev/env
// - To use your path aliases defined in your vite.config.js, you need to tell Node.js about them, see https://vike.dev/path-aliases
// If you want Vite to process your server code then use one of these:
// - vavite (https://github.com/cyco130/vavite)
// - See vavite + Vike examples at https://github.com/cyco130/vavite/tree/main/examples
// - vite-node (https://github.com/antfu/vite-node)
// - HatTip (https://github.com/hattipjs/hattip)
// - You can use Bati (https://batijs.dev/) to scaffold a Vike + HatTip app. Note that Bati generates apps that use the V1 design (https://vike.dev/migration/v1-design) and Vike packages (https://vike.dev/vike-packages)
import Fastify from "fastify";
import autoLoad from "@fastify/autoload";
import { renderPage } from "vike/server";
import { root, __dirname } from "./root.js";
import { join } from "path";
const isProduction = process.env.NODE_ENV === "production";
const production = { logger: true };
const development = {
logger: {
transport: {
target: "pino-pretty",
options: {
translateTime: "HH:MM:ss Z",
ignore: "pid,hostname",
},
},
},
};
export const instance = Fastify(isProduction ? production : development);
async function buildServer() {
// fastify autoload routes and plugins
instance.register(autoLoad, { dir: join(__dirname, "plugins") });
await instance.register(import("@fastify/compress"), { global: true });
instance.register(autoLoad, { dir: join(__dirname, "routes") });
if (isProduction) {
await instance.register(import("@fastify/static"), {
root: root + "/dist/client/assets",
prefix: "/assets/",
});
await instance.register(import("@fastify/static"), {
root: root + "/dist/client",
decorateReply: false,
wildcard: false,
});
}
else {
const vite = await import("vite");
const viteDevMiddleware = (
await vite.createServer({ server: { middlewareMode: true } })
).middlewares;
// this is middleware for vite's dev servert
instance.addHook("onRequest", async (request, reply) => {
const next = () =>
new Promise<void>((resolve) => {
viteDevMiddleware(request.raw, reply.raw, () => resolve());
});
await next();
});
}
instance.get("/server-route", (req, res) => {
res.send({ hello: "World" });
});
instance.get("*", async (request, reply) => {
const pageContextInit = {
urlOriginal: request.raw.url || "",
headersOriginal: request.headers,
// unhead: createHead, hello: "world",
decorator: {
canvike: request.server.canvike,
server_routes: Object.fromEntries(request.server.routes),
pinia: request.server.pinia,
},
fastify: {
reply
}
};
const pageContext = await renderPage(pageContextInit);
const { httpResponse } = pageContext;
if (!httpResponse) return reply.callNotFound();
const { statusCode, headers } = httpResponse;
headers.forEach(([name, value]) => reply.raw.setHeader(name, value));
reply.status(statusCode);
httpResponse.pipe(reply.raw);
return reply;
});
// await instance.ready();
return instance;
}
async function main() {
const fastify = await buildServer();
const port = (process.env.PORT || (isProduction ? 3006 : 3000)) as number;
// const port = await getPort({ port: +__port, portRange: [3000, 3100] })
fastify.listen({ port: port }, function (err, address) {
if (err) {
fastify.log.error(err);
process.exit(1);
}
});
}
main(); This is my server folder structure
This is my import { FastifyPluginAsync } from 'fastify'
const root: FastifyPluginAsync = async (fastify, opts): Promise<void> => {
fastify.get('/ping', async (request, reply) => {
return reply.code(200).send({ ok: true })
})
}
export default root; I have my rest api handled with vike and my ssr still runs. |
Beta Was this translation helpful? Give feedback.
I'd recommend using vike-vue as it inclued a built-in
ssr
toggle.