Open7

HonoXでtailwindcssを使う

ryuryu

プロジェクトを新規作成(x-basic)

npm create hono@latest
ryuryu

tailwindcssをインストール

npm install -D tailwindcss postcss autoprefixer
npx tailwindcss init -p

設定する

postcss.config.js
export default {
  plugins: {
    tailwindcss: {},
    autoprefixer: {},
  },
}
tailwind.config.js
/** @type {import('tailwindcss').Config} */
export default {
  content: ['./app/**/*.tsx'],
  theme: {
    extend: {},
  },
  plugins: [],
}
ryuryu

cssを設定する

app/style.css
@tailwind base;
@tailwind components;
@tailwind utilities;

_renderer.tsx内のheadタグにlinkタグを追加

app/routes/_renderer.tsx
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{title}</title>
+        {import.meta.env.PROD ? (
+          <link href='static/assets/style.css' rel='stylesheet' />
+        ) : (
+          <link href='/app/style.css' rel='stylesheet' />
+        )}
        <Script src="/app/client.ts" />
        <Style />
      </head>
ryuryu

viteの設定でビルド後にcssファイルが含まれるようにする

vite.config.ts
export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
+      build: {
+        rollupOptions: {
+          input: ['/app/style.css'],
+          output: {
+            assetFileNames: 'static/assets/[name].[ext]'
+          }
+        }
+      },
      plugins: [client()]
    }
  } else {
ryuryu

2024/03/31追記
Typeエラーが出るので@ts-ignoreを追加
ignoreしたくなければ、上記の公式の手順通りでよさそう


GitHubのIssueでもっとシンプルな構成があったので、そっちを採用する
cssファイルのパスを参照することで、rollupの設定を不要にできる

app/routes/_renderer.tsx
  import { Style } from 'hono/css'
  import { jsxRenderer } from 'hono/jsx-renderer'
  import { Script } from 'honox/server'
+ // @ts-ignore
+ import styles from "../style.css?url"

export default jsxRenderer(({ children, title }) => {
  return (
    <html lang="en">
      <head>
        <meta charset="utf-8" />
        <meta name="viewport" content="width=device-width, initial-scale=1.0" />
        <title>{title}</title>
-       {import.meta.env.PROD ? (
-         <link href='static/assets/style.css' rel='stylesheet' />
-       ) : (
-         <link href='/app/style.css' rel='stylesheet' />
-       )}
+       <link href={styles} rel="stylesheet" />
        <Script src="/app/client.ts" />
        <Style />
      </head>
      <body>{children}</body>
    </html>
  )
})

vite.config.ts
import pages from '@hono/vite-cloudflare-pages'
import honox from 'honox/vite'
import client from 'honox/vite/client'
import { defineConfig } from 'vite'

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [client()],
    }
  }

  return {
    plugins: [honox(), pages()],
    build: {
      assetsDir: 'static',
      ssrEmitAssets: true,
    },
  }
})

https://github.com/honojs/honox/issues/90#issuecomment-1975370211

ryuryu

v0.1.19でLinkタグコンポーネントが追加された
これを使うことによって、dev環境とprod環境でタグを切り替えを行わずにlinkタグを使えるようになり、_renderer.tsxを簡素化することが出来るようになった

app/routes/_renderer.tsx
     <head>
       <meta charset="utf-8" />
       <meta name="viewport" content="width=device-width, initial-scale=1.0" />
       <title>{title}</title>
-        {import.meta.env.PROD ? (
-          <link href='static/assets/style.css' rel='stylesheet' />
-        ) : (
-          <link href='/app/style.css' rel='stylesheet' />
-        )}
+      <Link href="/app/style.css" rel="stylesheet" />
       <Script src="/app/client.ts" />
       <Style />
     </head>
vite.config.ts
import pages from '@hono/vite-cloudflare-pages'
import honox from 'honox/vite'
import client from 'honox/vite/client'
import { defineConfig } from 'vite'

export default defineConfig(({ mode }) => {
  if (mode === 'client') {
    return {
      plugins: [client()],
      build: {
        rollupOptions: {
          input: ["/app/style.css"]
        },
      },
    }
  }

  return {
    plugins: [honox(), pages()]
  }
})

GitHubのテンプレートもこの方式に戻す

参考
https://github.com/honojs/honox/pull/181