mirror of
https://github.com/shishantbiswas/bknd.git
synced 2026-03-15 20:17:22 +00:00
Refactor Vite integration and update docs
Introduced a Vite adapter with "fresh" and "cached" modes, centralized dev server configuration, and streamlined the example setup. Updated documentation with detailed steps for Vite integration and revised the internal dev environment to align with the changes.
This commit is contained in:
14
app/src/adapter/vite/dev-server-config.ts
Normal file
14
app/src/adapter/vite/dev-server-config.ts
Normal file
@@ -0,0 +1,14 @@
|
|||||||
|
export const devServerConfig = {
|
||||||
|
entry: "./server.ts",
|
||||||
|
exclude: [
|
||||||
|
/.*\.tsx?($|\?)/,
|
||||||
|
/^(?!.*\/__admin).*\.(s?css|less)($|\?)/,
|
||||||
|
// exclude except /api
|
||||||
|
/^(?!.*\/api).*\.(ico|mp4|jpg|jpeg|svg|png|vtt|mp3|js)($|\?)/,
|
||||||
|
/^\/@.+$/,
|
||||||
|
/\/components.*?\.json.*/, // @todo: improve
|
||||||
|
/^\/(public|assets|static)\/.+/,
|
||||||
|
/^\/node_modules\/.*/
|
||||||
|
] as any,
|
||||||
|
injectClientScript: false
|
||||||
|
} as const;
|
||||||
@@ -2,8 +2,10 @@ import { serveStatic } from "@hono/node-server/serve-static";
|
|||||||
import { type DevServerOptions, default as honoViteDevServer } from "@hono/vite-dev-server";
|
import { type DevServerOptions, default as honoViteDevServer } from "@hono/vite-dev-server";
|
||||||
import { type RuntimeBkndConfig, createRuntimeApp } from "adapter";
|
import { type RuntimeBkndConfig, createRuntimeApp } from "adapter";
|
||||||
import type { App } from "bknd";
|
import type { App } from "bknd";
|
||||||
|
import { devServerConfig } from "./dev-server-config";
|
||||||
|
|
||||||
export type ViteBkndConfig<Env = any> = RuntimeBkndConfig<Env> & {
|
export type ViteBkndConfig<Env = any> = RuntimeBkndConfig<Env> & {
|
||||||
|
mode?: "cached" | "fresh";
|
||||||
setAdminHtml?: boolean;
|
setAdminHtml?: boolean;
|
||||||
forceDev?: boolean | { mainPath: string };
|
forceDev?: boolean | { mainPath: string };
|
||||||
html?: string;
|
html?: string;
|
||||||
@@ -29,6 +31,7 @@ async function createApp(config: ViteBkndConfig = {}, env?: any) {
|
|||||||
return await createRuntimeApp(
|
return await createRuntimeApp(
|
||||||
{
|
{
|
||||||
...config,
|
...config,
|
||||||
|
registerLocalMedia: true,
|
||||||
adminOptions:
|
adminOptions:
|
||||||
config.setAdminHtml === false
|
config.setAdminHtml === false
|
||||||
? undefined
|
? undefined
|
||||||
@@ -44,7 +47,7 @@ async function createApp(config: ViteBkndConfig = {}, env?: any) {
|
|||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
export function serveFresh(config: ViteBkndConfig = {}) {
|
export function serveFresh(config: Omit<ViteBkndConfig, "mode"> = {}) {
|
||||||
return {
|
return {
|
||||||
async fetch(request: Request, env: any, ctx: ExecutionContext) {
|
async fetch(request: Request, env: any, ctx: ExecutionContext) {
|
||||||
const app = await createApp(config, env);
|
const app = await createApp(config, env);
|
||||||
@@ -54,7 +57,7 @@ export function serveFresh(config: ViteBkndConfig = {}) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
let app: App;
|
let app: App;
|
||||||
export function serveCached(config: ViteBkndConfig = {}) {
|
export function serveCached(config: Omit<ViteBkndConfig, "mode"> = {}) {
|
||||||
return {
|
return {
|
||||||
async fetch(request: Request, env: any, ctx: ExecutionContext) {
|
async fetch(request: Request, env: any, ctx: ExecutionContext) {
|
||||||
if (!app) {
|
if (!app) {
|
||||||
@@ -66,20 +69,13 @@ export function serveCached(config: ViteBkndConfig = {}) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function serve({ mode, ...config }: ViteBkndConfig = {}) {
|
||||||
|
return mode === "fresh" ? serveFresh(config) : serveCached(config);
|
||||||
|
}
|
||||||
|
|
||||||
export function devServer(options: DevServerOptions) {
|
export function devServer(options: DevServerOptions) {
|
||||||
return honoViteDevServer({
|
return honoViteDevServer({
|
||||||
entry: "./server.ts",
|
...devServerConfig,
|
||||||
exclude: [
|
|
||||||
/.*\.tsx?($|\?)/,
|
|
||||||
/^(?!.*\/__admin).*\.(s?css|less)($|\?)/,
|
|
||||||
// exclude except /api
|
|
||||||
/^(?!.*\/api).*\.(ico|mp4|jpg|jpeg|svg|png|vtt|mp3|js)($|\?)/,
|
|
||||||
/^\/@.+$/,
|
|
||||||
/\/components.*?\.json.*/, // @todo: improve
|
|
||||||
/^\/(public|assets|static)\/.+/,
|
|
||||||
/^\/node_modules\/.*/
|
|
||||||
],
|
|
||||||
injectClientScript: false,
|
|
||||||
...options
|
...options
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,48 +1,29 @@
|
|||||||
import devServer from "@hono/vite-dev-server";
|
import devServer from "@hono/vite-dev-server";
|
||||||
import react from "@vitejs/plugin-react";
|
import react from "@vitejs/plugin-react";
|
||||||
import { defineConfig, loadEnv } from "vite";
|
import { defineConfig } from "vite";
|
||||||
import tsconfigPaths from "vite-tsconfig-paths";
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
import { devServerConfig } from "./src/adapter/vite/dev-server-config";
|
||||||
|
|
||||||
// https://vitejs.dev/config/
|
// https://vitejs.dev/config/
|
||||||
export default defineConfig(async () => {
|
export default defineConfig({
|
||||||
/**
|
define: {
|
||||||
* DEVELOPMENT MODE
|
__isDev: "1"
|
||||||
*/
|
},
|
||||||
if (process.env.NODE_ENV === "development") {
|
clearScreen: false,
|
||||||
return {
|
publicDir: "./src/admin/assets",
|
||||||
define: {
|
server: {
|
||||||
__isDev: "1"
|
host: true,
|
||||||
},
|
port: 28623,
|
||||||
clearScreen: false,
|
hmr: {
|
||||||
publicDir: "./src/admin/assets",
|
overlay: true
|
||||||
server: {
|
}
|
||||||
host: true,
|
},
|
||||||
port: 28623,
|
plugins: [
|
||||||
hmr: {
|
react(),
|
||||||
overlay: true
|
tsconfigPaths(),
|
||||||
}
|
devServer({
|
||||||
},
|
...devServerConfig,
|
||||||
plugins: [
|
entry: "./vite.dev.ts"
|
||||||
react(),
|
})
|
||||||
tsconfigPaths(),
|
]
|
||||||
devServer({
|
|
||||||
entry: "./vite.dev.ts",
|
|
||||||
exclude: [
|
|
||||||
// We need to override this option since the default setting doesn't fit
|
|
||||||
/.*\.tsx?($|\?)/,
|
|
||||||
/^(?!.*\/__admin).*\.(s?css|less)($|\?)/,
|
|
||||||
/^(?!.*\/api).*\.(svg|png)($|\?)/, // exclude except /api
|
|
||||||
/^\/@.+$/,
|
|
||||||
/^\/favicon\.ico$/,
|
|
||||||
/^\/(public|assets|static)\/.+/,
|
|
||||||
/^\/node_modules\/.*/
|
|
||||||
],
|
|
||||||
//injectClientScript: true
|
|
||||||
injectClientScript: false // This option is buggy, disable it and inject the code manually
|
|
||||||
})
|
|
||||||
]
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
throw new Error("Don't use vite for building in production");
|
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -1,10 +1,4 @@
|
|||||||
import { serveStatic } from "@hono/node-server/serve-static";
|
import { serve } from "./src/adapter/vite";
|
||||||
import { createClient } from "@libsql/client/node";
|
|
||||||
import { App, registries } from "./src";
|
|
||||||
import { LibsqlConnection } from "./src/data";
|
|
||||||
import { StorageLocalAdapter } from "./src/media/storage/adapters/StorageLocalAdapter";
|
|
||||||
|
|
||||||
registries.media.register("local", StorageLocalAdapter);
|
|
||||||
|
|
||||||
const credentials = {
|
const credentials = {
|
||||||
url: import.meta.env.VITE_DB_URL!,
|
url: import.meta.env.VITE_DB_URL!,
|
||||||
@@ -14,22 +8,10 @@ if (!credentials.url) {
|
|||||||
throw new Error("Missing VITE_DB_URL env variable. Add it to .env file");
|
throw new Error("Missing VITE_DB_URL env variable. Add it to .env file");
|
||||||
}
|
}
|
||||||
|
|
||||||
const connection = new LibsqlConnection(createClient(credentials));
|
export default serve({
|
||||||
|
connection: {
|
||||||
export default {
|
type: "libsql",
|
||||||
async fetch(request: Request) {
|
config: credentials
|
||||||
const app = App.create({ connection });
|
},
|
||||||
|
forceDev: true
|
||||||
app.emgr.onEvent(
|
});
|
||||||
App.Events.AppBuiltEvent,
|
|
||||||
async () => {
|
|
||||||
app.registerAdminController({ forceDev: true });
|
|
||||||
app.module.server.client.get("/assets/*", serveStatic({ root: "./" }));
|
|
||||||
},
|
|
||||||
"sync"
|
|
||||||
);
|
|
||||||
await app.build();
|
|
||||||
|
|
||||||
return app.fetch(request);
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|||||||
116
docs/integration/vite.mdx
Normal file
116
docs/integration/vite.mdx
Normal file
@@ -0,0 +1,116 @@
|
|||||||
|
---
|
||||||
|
title: 'Vite'
|
||||||
|
description: 'Run bknd inside Vite'
|
||||||
|
---
|
||||||
|
import InstallBknd from '/snippets/install-bknd.mdx';
|
||||||
|
|
||||||
|
Vite is a powerful toolkit to accelerate your local development.
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
Create a new vite project by following the [official guide](https://vite.dev/guide/#scaffolding-your-first-vite-project)
|
||||||
|
and then install bknd as a dependency:
|
||||||
|
<InstallBknd />
|
||||||
|
|
||||||
|
Additionally, install required dependencies:
|
||||||
|
```bash
|
||||||
|
npm install @hono/vite-dev-server
|
||||||
|
```
|
||||||
|
|
||||||
|
## Serve the API
|
||||||
|
To serve the **bknd** API, you first have to create a local server file for you vite environment.
|
||||||
|
Create a `server.ts` file:
|
||||||
|
```ts
|
||||||
|
import { serve } from "bknd/adapter/vite";
|
||||||
|
|
||||||
|
// the configuration given is optional
|
||||||
|
export default serve({
|
||||||
|
mode: "cached", // that's the default
|
||||||
|
connection: {
|
||||||
|
type: "libsql",
|
||||||
|
config: {
|
||||||
|
url: ":memory:"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
})
|
||||||
|
```
|
||||||
|
For more information about the connection object, refer to the [Setup](/setup/introduction) guide.
|
||||||
|
|
||||||
|
You can also run your vite server in `mode: "fresh"`, this will re-create the app on every fetch.
|
||||||
|
This is only useful for when working on the `bknd` repository directly.
|
||||||
|
|
||||||
|
Next, adjust your `vite.config.ts` to look like the following:
|
||||||
|
```ts
|
||||||
|
import { devServer } from "bknd/adapter/vite";
|
||||||
|
import react from "@vitejs/plugin-react";
|
||||||
|
import { defineConfig } from "vite";
|
||||||
|
import tsconfigPaths from "vite-tsconfig-paths";
|
||||||
|
|
||||||
|
// https://vitejs.dev/config/
|
||||||
|
export default defineConfig({
|
||||||
|
plugins: [
|
||||||
|
react(),
|
||||||
|
tsconfigPaths(),
|
||||||
|
devServer({
|
||||||
|
// point to your previously created server file
|
||||||
|
entry: "./server.ts"
|
||||||
|
})
|
||||||
|
]
|
||||||
|
});
|
||||||
|
```
|
||||||
|
|
||||||
|
Now you can start your application using `npm run dev`. Now opening http://localhost:5174/
|
||||||
|
looks like an empty project. That's because we only registered the API, head over to
|
||||||
|
http://localhost:5174/api/system/config to see **bknd** respond.
|
||||||
|
|
||||||
|
## Serve the Admin UI
|
||||||
|
After adding the API, you can easily add the Admin UI by simply returning it in your `App.tsx`.
|
||||||
|
Replace all of its content with the following:
|
||||||
|
|
||||||
|
```tsx
|
||||||
|
import { Admin } from "bknd/ui";
|
||||||
|
import "bknd/dist/styles.css";
|
||||||
|
|
||||||
|
export default function App() {
|
||||||
|
return <Admin withProvider />
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
Now http://localhost:5174/ should give you the Admin UI.
|
||||||
|
|
||||||
|
## Customizations
|
||||||
|
This is just the bare minimum and may not always fulfill your requirements. There are a few
|
||||||
|
options you can make use of to adjust it according to your setup.
|
||||||
|
|
||||||
|
### Use custom HTML to serve the Admin UI
|
||||||
|
There might be cases you want to be sure to be in control over the HTML that is being used.
|
||||||
|
`bknd` generates it automatically, but you use your own one as follows:
|
||||||
|
|
||||||
|
```ts server.ts
|
||||||
|
import { serve, addViteScript } from "bknd/adapter/vite";
|
||||||
|
import { readFile } from "node:fs/promises"
|
||||||
|
|
||||||
|
let html = await readFile("./index.html", "utf-8");
|
||||||
|
|
||||||
|
// add vite scripts
|
||||||
|
html = addViteScript(html);
|
||||||
|
|
||||||
|
// then add it as an option
|
||||||
|
export default serve({ html })
|
||||||
|
```
|
||||||
|
|
||||||
|
The vite scripts has to be added manually currently, as adding them automatically with
|
||||||
|
`@hono/vite-dev-server` is buggy. This may change in the future.
|
||||||
|
|
||||||
|
### Use a custom entry point
|
||||||
|
By default, the entry point `/src/main.tsx` is used and should fit most cases. If that's not you,
|
||||||
|
you can supply a different one like so:
|
||||||
|
```ts server.ts
|
||||||
|
import { serve } from "bknd/adapter/vite";
|
||||||
|
|
||||||
|
// the configuration given is optional
|
||||||
|
export default serve({
|
||||||
|
forceDev: {
|
||||||
|
mainPath: "/src/special.tsx"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
```
|
||||||
@@ -82,6 +82,15 @@ in the future, so stay tuned!
|
|||||||
</div>}
|
</div>}
|
||||||
href="/integration/node"
|
href="/integration/node"
|
||||||
/>
|
/>
|
||||||
|
<Card
|
||||||
|
title="Vite"
|
||||||
|
icon={<div className="text-primary-light">
|
||||||
|
<svg xmlns="http://www.w3.org/2000/svg" width="28" height="28" viewBox="0 0 24 24">
|
||||||
|
<rect width="24" height="24" fill="none"/><path fill="currentColor" d="m8.525 4.63l-5.132-.915a1.17 1.17 0 0 0-1.164.468a1.16 1.16 0 0 0-.07 1.28l8.901 15.58a1.182 1.182 0 0 0 2.057-.008l8.729-15.578c.49-.875-.262-1.917-1.242-1.739l-4.574.813l-.206.754l4.906-.871a.474.474 0 0 1 .498.697L12.5 20.689a.47.47 0 0 1-.5.234a.47.47 0 0 1-.326-.231L2.772 5.112a.474.474 0 0 1 .496-.7l5.133.916l.074.013z"/><path fill="currentColor" d="m15.097 5.26l.162-.593l-.6.107zm-5.88-.506l.513.09l-.542.427z"/><path fill="currentColor" d="m15.549 2.367l-6.1 1.26a.22.22 0 0 0-.126.077a.25.25 0 0 0-.055.142l-.375 6.685a.24.24 0 0 0 .079.194a.21.21 0 0 0 .195.05l1.698-.414c.16-.038.302.11.27.278l-.505 2.606c-.034.176.122.326.285.274l1.049-.336c.162-.052.319.098.284.274l-.801 4.093c-.05.257.272.396.407.177l.09-.147l4.97-10.464c.084-.175-.06-.375-.242-.338l-1.748.356c-.165.034-.304-.128-.258-.297l1.14-4.173c.047-.17-.093-.331-.257-.297"/>
|
||||||
|
</svg>
|
||||||
|
</div>}
|
||||||
|
href="/integration/vite"
|
||||||
|
/>
|
||||||
<Card
|
<Card
|
||||||
title="Docker"
|
title="Docker"
|
||||||
icon={<div className="text-primary-light">
|
icon={<div className="text-primary-light">
|
||||||
|
|||||||
@@ -89,6 +89,7 @@
|
|||||||
"integration/astro",
|
"integration/astro",
|
||||||
"integration/node",
|
"integration/node",
|
||||||
"integration/deno",
|
"integration/deno",
|
||||||
|
"integration/vite",
|
||||||
"integration/docker"
|
"integration/docker"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
|||||||
Reference in New Issue
Block a user