サーバーサイドレンダリング
EffCSS を使用すると、サーバー側でスタイルシートを作成できます。スタイルとメタデータをシリアライズして、サーバーサイドレンダリング (SSR) または静的サイト生成 (SSG) に利用できます。
シリアライズ
EffCSS は、スタイルシートをシリアライズするための2つのユーティリティを提供します。
serializeは、CSSスタイルを含む<style>タグを格納した HTML 文字列を返します。serializeMetaは、メタデータを含む<script type="application/json">タグを格納した HTML 文字列を返します。
通常、serialize ユーティリティのみを使用すれば十分です。これらのスタイルはクライアント側で再利用されます。ただし、コントラクトユーティリティ(classNames と attributes)は、コントラクトセレクタを計算するためにコードを実行します。これらの計算がリソースを大量に消費する場合は、serializeMeta を使用してください。そうすれば、classNames と attributes ユーティリティは、追加の計算なしにメタデータからセレクタを使用します。
したがって、SSG とシンプルな SSR の場合は serialize で十分ですが、高度な SSR の場合は serializeMeta が必要です。
例
以下は、簡略化されたReact SSRの例です。
ts
import { StrictMode } from 'react';
import { renderToString } from 'react-dom/server';
import App from './App';
import { serialize, serializeMeta } from 'effcss';
export function render(_url) {
const html = renderToString(
<StrictMode>
<App />
</StrictMode>
);
const styles = serialize();
const metadata = serializeMeta();
const head = styles + metadata;
return { html, head };
}ts
import { StrictMode } from "react";
import { hydrateRoot } from "react-dom/client";
import App from "./App";
hydrateRoot(
document.getElementById("root"),
<StrictMode>
<App />
</StrictMode>
);js
import fs from "node:fs/promises";
import express from "express";
const app = express();
// There should be constants and server settings here,
// but rendering is more important for this example
// Serve HTML
app.use("*all", async (req, res) => {
try {
const url = req.originalUrl.replace(base, "");
let template;
let render;
if (!isProduction) {
template = await fs.readFile("./index.html", "utf-8");
template = await vite.transformIndexHtml(url, template);
render = (await vite.ssrLoadModule("/src/entry-server.tsx")).render;
} else {
template = templateHtml;
render = (await import("./dist/server/entry-server.js")).render;
}
const rendered = await render(url);
const source = template.replace(`<!--app-html-->`, rendered.html ?? "");
const html = source.replace(`<!--app-head-->`, rendered.head ?? "");
res.status(200).set({ "Content-Type": "text/html" }).send(html);
} catch (e) {
vite?.ssrFixStacktrace(e);
res.status(500).end(e.stack);
}
});
// Start http server
app.listen(port, () => {
console.log(`Server started at http://localhost:${port}`);
});