Open2

Deno Hono で Panda CSS を使う

5t1111115t111111

Hono で静的ファイルを配信するように設定

Hono の serveStatic ミドルウェアを使う。

+ import { serveStatic } from "hono/deno";
+ app.use("/static/*", serveStatic({ root: "./" }));

Panda CSSを依存に追加

deno add npm:@pandacss/dev

Panda CSS の設定

Panda CSS はローカルの node_modules/ を読みに行くため、 deno.jsonnodeModulesDir: true を設定しておく。

{
  ...
  "nodeModulesDir": true,
  ...
}

.gitignore にも node_modules ディレクトリを追加しておく。

以下を実行すると、設定ファイル panda.config.mjs が生成される。

deno run -A npm:@pandacss/dev init

デフォルトで生成された panda.config.mjs の内容は以下:

import { defineConfig } from "@pandacss/dev";

export default defineConfig({
  // Whether to use css reset
  preflight: true,

  // Where to look for your css declarations
  include: ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"],

  // Files to exclude
  exclude: [],

  // Useful for theme customization
  theme: {
    extend: {},
  },

  // The output directory for your css system
  outdir: "styled-system",
});

解析対象を変更する (ディレクトリ構成次第で合わせる):

- include: ["./src/**/*.{js,jsx,ts,tsx}", "./pages/**/*.{js,jsx,ts,tsx}"],
+ include: ["./components/**/*.{js,jsx,ts,tsx}", "./layouts/**/*.{js,jsx,ts,tsx}", "./routes/**/*.{js,jsx,ts,tsx}"],

Hono で静的ファイルを static/ 以下で配信するので合わせる。
https://hono.dev/docs/getting-started/deno#serve-static-files

- outdir: "styled-system",
+ outdir: "./static/styled-system",

Denoはimportの拡張子が必須なので拡張子を強制する

+ forceConsistentTypeExtension: true,

Panda CSS の読み込み

レイアウトなどのファイルに以下を追加:

import { html } from "hono/html";

interface SiteData {
  title: string;
  description: string;
  // deno-lint-ignore no-explicit-any
  children?: any;
}

export const Layout = (props: SiteData) => {
  return html`
    <html lang="ja">
      <head>
        <meta charset="UTF-8">
        <title>${props.title}</title>
        <meta name="description" content="${props.description}">
        <link rel="stylesheet" href="/static/styled-system/styles.css" /></head>
      <body>
        <div>
          ${props.children}
        </div>
      </body>
    </html>
  `;
};

以下を実行すると static/styled-system ディレクトリにファイルが生成される:

deno run -A npm:@pandacss/dev     
🐼 info [css] /workspaces/voting-2024/app/static/styled-system/styles.css
🐼 info [hrtime] Successfully extracted css from 5 file(s) ✨ (33.17ms)

実際の開発時は、とりあえず以下の2つのタスクを両方起動しておくことにする (TODO: もっとマシにしたい)

  "tasks": {
    "dev": "deno run -A --unstable-kv --env --watch main.ts",
    "panda": "deno run -A npm:@pandacss/dev --watch"
  },

スタイルの記述

import 時に生成された mjs を import した上で index.d.mts@deno-types に指定しないと正しく型が付く&動く状態にならない

// @deno-types="../static/styled-system/css/index.d.mts"
import { css } from "../static/styled-system/css/index.mjs";
// @deno-types="../static/styled-system/css/index.d.mts"
import { css } from "../static/styled-system/css/index.mjs";

export const Hero = () => {
  return (
    <div
      class={css({
        backgroundColor: "blue",
      })}
    >
      <div
        class={css({
          paddingTop: "2rem",
        })}
      >
        <h1
          class={css({
            fontSize: "3rem",
            fontWeight: "bold",
            color: "white",
            textAlign: "center",
          })}
        >
          Deno, Hono and panda
        </h1>
      </div>
    </div>
  );
};