feat: Update build scripts and configurations for client and server environments

This commit is contained in:
2026-01-05 22:54:49 +07:00
parent 0042fd1951
commit 92608b52e2
5 changed files with 34 additions and 23 deletions

View File

@@ -3,7 +3,7 @@
"type": "module", "type": "module",
"scripts": { "scripts": {
"dev": "vite", "dev": "vite",
"build": "vite build", "build": "vite build && bun build dist/server/index.js --target bun --outdir dist",
"preview": "vite preview", "preview": "vite preview",
"deploy": "wrangler deploy", "deploy": "wrangler deploy",
"cf-typegen": "wrangler types --env-interface CloudflareBindings" "cf-typegen": "wrangler types --env-interface CloudflareBindings"

View File

@@ -26,7 +26,7 @@ export function clientFirstBuild(): Plugin {
config.builder.buildApp = async (builder) => { config.builder.buildApp = async (builder) => {
const clientEnvironment = builder.environments.client; const clientEnvironment = builder.environments.client;
const workerEnvironments = Object.keys(builder.environments) const workerEnvironments = Object.keys(builder.environments)
.filter((name) => name !== "client") .filter((name) => name !== "client" && name !== "ssr")
.map((name) => builder.environments[name]); .map((name) => builder.environments[name]);
// console.log('Client First Build Plugin: Starting builds...', workerEnvironments) // console.log('Client First Build Plugin: Starting builds...', workerEnvironments)
// Client build first // Client build first
@@ -112,7 +112,6 @@ export default function ssrPlugin(): Plugin[] {
resolveId(id, importer, options) { resolveId(id, importer, options) {
if (!id.startsWith('@httpClientAdapter')) return if (!id.startsWith('@httpClientAdapter')) return
const pwd = process.cwd() const pwd = process.cwd()
console.log('Resolving httpClientAdapter in', pwd, 'for', {id, importer, options})
return path.resolve( return path.resolve(
__dirname, __dirname,
options?.ssr options?.ssr
@@ -136,7 +135,8 @@ export default function ssrPlugin(): Plugin[] {
const clientBuild = viteConfig.environments.client.build; const clientBuild = viteConfig.environments.client.build;
clientBuild.manifest = true; clientBuild.manifest = true;
clientBuild.rollupOptions = clientBuild.rollupOptions || {}; clientBuild.rollupOptions = clientBuild.rollupOptions || {};
clientBuild.rollupOptions.input = "src/client.ts"; // clientBuild.rollupOptions.input = "src/client.ts";
// clientBuild.outDir = "dist/client";
if (!viteConfig.environments.ssr) { if (!viteConfig.environments.ssr) {
const manifestPath = path.join(clientBuild.outDir as string, '.vite/manifest.json') const manifestPath = path.join(clientBuild.outDir as string, '.vite/manifest.json')
try { try {

View File

@@ -9,13 +9,16 @@ import { cors } from "hono/cors";
import { jwtRpc, rpcServer } from './api/rpc'; import { jwtRpc, rpcServer } from './api/rpc';
import isMobile from 'is-mobile'; import isMobile from 'is-mobile';
import { useAuthStore } from './stores/auth'; import { useAuthStore } from './stores/auth';
import { serveStatic } from "hono/bun"; // import { serveStatic } from "hono/bun";
import { serveStatic } from "hono/serve-static";
import { cssContent } from './lib/primeCssContent'; import { cssContent } from './lib/primeCssContent';
import { styleTags } from './lib/primePassthrough'; import { styleTags } from './lib/primePassthrough';
// @ts-ignore // @ts-ignore
import Base from '@primevue/core/base'; import Base from '@primevue/core/base';
const app = new Hono() const app = new Hono()
const defaultNames = ['primitive', 'semantic', 'global', 'base', 'ripple-directive'] const defaultNames = ['primitive', 'semantic', 'global', 'base', 'ripple-directive']
const isDev = import.meta.env.DEV;
console.log("process.versions?.bun:", (process as any).versions?.bun);
// app.use(renderer) // app.use(renderer)
app.use('*', contextStorage()); app.use('*', contextStorage());
app.use(cors(), async (c, next) => { app.use(cors(), async (c, next) => {
@@ -27,7 +30,12 @@ app.use(cors(), async (c, next) => {
c.set("isMobile", isMobile({ ua })); c.set("isMobile", isMobile({ ua }));
await next(); await next();
}, rpcServer); }, rpcServer);
app.use(serveStatic({ root: "./public" })) if (!isDev) {
if ((process as any).versions?.bun) {
const { serveStatic } = await import("hono/bun");
app.use(serveStatic({ root: "./dist/client" }))
}
}
app.get("/.well-known/*", (c) => { app.get("/.well-known/*", (c) => {
return c.json({ ok: true }); return c.json({ ok: true });
}); });

View File

@@ -1,8 +1,8 @@
<template> <template>
<div class="w-full"> <div class="w-full">
<Toast />
<Form v-slot="$form" :resolver="resolver" :initialValues="initialValues" @submit="onFormSubmit" <Form v-slot="$form" :resolver="resolver" :initialValues="initialValues" @submit="onFormSubmit"
class="flex flex-col gap-4 w-full"> class="flex flex-col gap-4 w-full">
<Message v-if="auth.error" severity="error">Failed to sign in. Please check your credentials or try again later.</Message>
<div class="flex flex-col gap-1"> <div class="flex flex-col gap-1">
<label for="email" class="text-sm font-medium text-gray-700">Email or Username</label> <label for="email" class="text-sm font-medium text-gray-700">Email or Username</label>
<InputText name="email" type="text" placeholder="admin or user@example.com" fluid <InputText name="email" type="text" placeholder="admin or user@example.com" fluid
@@ -75,23 +75,18 @@ import { Form, type FormSubmitEvent } from '@primevue/forms';
import { zodResolver } from '@primevue/forms/resolvers/zod'; import { zodResolver } from '@primevue/forms/resolvers/zod';
import { z } from 'zod'; import { z } from 'zod';
import { useAuthStore } from '@/stores/auth'; import { useAuthStore } from '@/stores/auth';
import Toast from 'primevue/toast';
import { useToast } from "primevue/usetoast";
const t = useToast();
const auth = useAuthStore(); const auth = useAuthStore();
// const $form = Form.useFormContext(); // const $form = Form.useFormContext();
watch(() => auth.error, (newError) => {
if (newError) {
t.add({ severity: 'error', summary: String(auth.error), detail: newError, life: 5000 });
}
});
const initialValues = reactive({ const initialValues = reactive({
email: '', email: '',
password: '', password: '',
rememberMe: false rememberMe: false
}); });
watch(() => initialValues, (newValues) => {
auth.error = null;
// console.log('Form values changed:', newValues);
});
const resolver = zodResolver( const resolver = zodResolver(
z.object({ z.object({
email: z.string().min(1, { message: 'Email or username is required.' }), email: z.string().min(1, { message: 'Email or username is required.' }),

View File

@@ -40,16 +40,24 @@ export default defineConfig((env) => {
// cloudflare(), // cloudflare(),
], ],
environments: { environments: {
ssr: { client: {
build: { build: {
outDir: "dist/server", outDir: "dist/client",
copyPublicDir: false, rollupOptions: {
rollupOptions: { input: { index: "/src/client.ts" },
input: { index: "/src/index.tsx" }, },
}
},
server: {
build: {
outDir: "dist/server",
copyPublicDir: false,
rollupOptions: {
input: { index: "/src/index.tsx" },
},
}, },
}, },
}, },
},
resolve: { resolve: {
alias: { alias: {
"@": path.resolve(__dirname, "./src"), "@": path.resolve(__dirname, "./src"),