Open1
hono + pages, react-dom SSR お試し
概要
hono で、SSRを react-dom/server使うメモになります。
- フルスタック構成ですが、今回はSSRの内容です。
[投稿日: 2023/11/18]
環境
- hono: 3.9.0
- vite: 4.5.0
- cloudflare pages
- react-dom
作成したコード
- package.json
{
"type": "module",
"scripts": {
"dev": "vite",
"build": "vite build && vite build --mode client",
"preview": "wrangler pages dev dist",
"deploy": "$npm_execpath run build && wrangler pages deploy dist"
},
"dependencies": {
"hono": "^3.9.0",
"htm": "^3.1.1",
"marked": "^10.0.0",
"micromodal": "^0.4.10",
"preact": "^10.18.1",
"react": "^18.2.0",
"react-dom": "^18.2.0"
},
"devDependencies": {
"@cloudflare/workers-types": "^4.20230914.0",
"@hono/vite-cloudflare-pages": "^0.0.2",
"@hono/vite-dev-server": "^0.0.12",
"@preact/preset-vite": "^2.6.0",
"@types/react": "^18.2.37",
"@types/react-dom": "^18.2.15",
"autoprefixer": "^10.4.16",
"postcss": "^8.4.31",
"tailwindcss": "^3.3.5",
"vite": "^4.5.0",
"wrangler": "^3.14.0"
}
}
- tsconfig.json
{
"compilerOptions": {
"target": "ESNext",
"module": "ESNext",
"moduleResolution": "node",
"esModuleInterop": true,
"strict": true,
"lib": [
"ESNext"
],
"types": [
"@cloudflare/workers-types",
"vite/client"
],
"jsx": "react-jsx"
},
}
- pages/test/App.tsx
App.tsx
import React from 'react';
//
export default function Page(props: any) {
return (
<div>
<h1 className="text-4xl font-bold">Test/App.tsx</h1>
{/* JS */}
{import.meta.env.PROD ? (
<script type="module" src="/static/Page2.js"></script>
) : (
<script type="module" src="/src/client/Page2.ts"></script>
)}
</div>
)
}
- index.tsx
index.tsx
import Test1 from './pages/test/App';
app.get('/test1', async (c) => {
return c.html(renderToString(Test1([])));
});
- pages/test2/App.tsx: List
App.tsx
import React from 'react';
import { marked } from 'marked';
const messages = ['Good Morning', 'Good Evening', 'Good Night']
//
export default function Page(props: any) {
//console.log(props);
//
return (
<div>
<h1 className="text-4xl font-bold">Test2</h1>
<hr className="my-2" />
<ul>
{messages.map((message: any, index: number) => {
return (<li className="my-2" key={index}
>{message}!!</li>)
})}
</ul>
<hr className="my-2" />
</div>
)
}
MD変換の例
- pages/test3/App.tsx: dangerouslySetInnerHTML 使う例です
App.tsx
import React from 'react';
import { marked } from 'marked';
const testMD = `
### hoge
***
* 123
* 145
***
* CCC
`
//
export default function Page(props: any) {
const content = marked.parse(testMD);
console.log(content);
//
return (
<div>
<h1 className="text-4xl font-bold">Test3</h1>
<hr className="my-2" />
<pre dangerouslySetInnerHTML={{ __html: content }} />
<hr className="my-2" />
{/* JS */}
{import.meta.env.PROD ? (
<script type="module" src="/static/Page2.js"></script>
) : (
<script type="module" src="/src/client/Page2.ts"></script>
)}
</div>
)
}