Closed19
Honoでyamada-uiを動かす
参考になりそう
手順
pnpm create hono
する
pnpm add @yamada-ui/react react react-dom
pnpm add -D @types/react @types/react-dom
した
追加
client.tsx
import { UIProvider } from "@yamada-ui/react";
import { createRoot } from "react-dom/client";
import { App } from "./app"
const domNode = document.getElementById("root")!;
const root = createRoot(domNode);
root.render(
<UIProvider>
<App />
</UIProvider>,
);
変更
index.ts
→index.tsx
index.tsx
import { Hono } from "hono"
import { renderToString } from "react-dom/server"
const app = new Hono()
app.get("*", (c) => {
return c.html(
renderToString(
<html lang="ja" data-mode="light">
<head>
<script type="module" src="/src/client.tsx"></script>
</head>
<body>
<div id="root"></div>
</body>
</html>,
),
)
})
export default app
pnpm add -D @hono/vite-dev-server vite
を実行する
package.json
{
+ "type": "module",
"scripts": {
"dev": "tsx watch src/index.ts"
},
"dependencies": {
"@hono/node-server": "^1.9.0",
"@yamada-ui/react": "^1.3.0",
"hono": "^4.1.5",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@hono/vite-dev-server": "^0.10.0",
"@types/node": "^20.11.17",
"@types/react": "^18.2.73",
"@types/react-dom": "^18.2.22",
"tsx": "^3.12.2",
"vite": "^5.2.6"
}
}
tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "Bundler",
"strict": true,
"types": [
"node"
],
"jsx": "react-jsx",
+ "jsxImportSource": "react"
- "jsxImportSource": "hono/jsx"
}
}
ファイル追加
vite.config.ts
import devServer, { defaultOptions } from "@hono/vite-dev-server";
import { defineConfig } from "vite";
export default defineConfig(({ mode }) => {
if (mode === "client") {
return {
build: {
rollupOptions: {
input: "./src/client.tsx",
output: {
entryFileNames: "static/client.js",
},
},
},
resolve: {
alias: {
"@": "/src",
},
},
};
} else {
return {
ssr: {
external: ["react", "react-dom"],
},
plugins: [
devServer({
exclude: ["/*", ...defaultOptions.exclude],
entry: "src/index.tsx",
}),
],
server: {
port: 4448,
},
resolve: {
alias: {
"@": "/src",
},
},
};
}
});
カラーモードとかが入る前に描画されてしまうので、cookieでとってそのままモードを格納するようにした。
(ColorModeManagerがやっていること)
index.tsx
import { ColorModeScript, ThemeSchemeScript } from "@yamada-ui/react"
import { Hono } from "hono"
import { getCookie } from "hono/cookie"
import { renderToString } from "react-dom/server"
import { config } from "./theme"
const app = new Hono()
app.get("*", (c) => {
+ const colorMode = getCookie(c, "ui-color-mode")
+ const themeScheme = getCookie(c, "ui-theme-scheme")
return c.html(
renderToString(
<html lang="ja">
<head>
<title>Hono App - Yamada UI</title>
<meta charSet="utf-8" />
<meta content="width=device-width, initial-scale=1" name="viewport" />
<link rel="icon" href="/favicon.svg" />
<script type="module" src="/src/client.tsx"></script>
</head>
<body>
<ColorModeScript
type="cookie"
nonce="testing"
- initialColorMode={colorMode ?? config.initialColorMode}
+ initialColorMode={colorMode ?? config.initialColorMode}
/>
<ThemeSchemeScript
type="cookie"
nonce="testing"
- initialThemeScheme={config.initialThemeScheme}
+ initialThemeScheme={themeScheme ?? config.initialThemeScheme}
/>
<div id="root"></div>
</body>
</html>,
),
)
})
export default app
note: index.tsxだけ先にサーバー側で生成され表示されるために、ダークモード時のフラッシュを防止するために使用しています。
このスクラップは2024/03/30にクローズされました