Quantcast
Channel: プログラミング
Viewing all articles
Browse latest Browse all 8071

HonoX で `app/` ディレクトリ以外でももろもろを動作させたい - なつねこメモ

$
0
0

素直に app/でやれば良いのだが、やんごとなき理由で app/以外の、例えば src/my-worldest-strong-app/などで開発したいことがある (かもしれない)。 そういうときにやると良いハック。 PR は送るべきか悩んで放置している。

まずは HonoXにパッチを当てる必要があるので、パッチを当てます。お使いのパッケージマネージャーでできる方法で試しましょう。

$ pnpm patch honox

差分は以下のような形。単純に honopx/vite/clientに対して、 entryを渡せるようにしただけ:

diff --git a/dist/vite/client.d.ts b/dist/vite/client.d.tsindex 7d4b2c20a9fc97ad538d89c850d0517df41271a0..54f6a0f4383c78f4dd353ae7c4a28572148098e0 100644--- a/dist/vite/client.d.ts+++ b/dist/vite/client.d.ts@@ -1,6 +1,7 @@
 import { Plugin } from 'vite';
 
 type Options = {
+    entry?: string;
     jsxImportSource?: string;
     assetsDir?: string;
 };
diff --git a/dist/vite/client.js b/dist/vite/client.jsindex 2beda22387a7506caafe9e4b961facc1af661b05..13935f18b3b72124d5227ae1c86f15fe113380e1 100644--- a/dist/vite/client.js+++ b/dist/vite/client.js@@ -1,4 +1,5 @@
 const defaultOptions = {
+  entry: "/app/client.ts",
   jsxImportSource: "hono/jsx/dom",
   assetsDir: "static"
 };
@@ -9,7 +10,7 @@ function client(options) {
       return {
         build: {
           rollupOptions: {
-            input: ["/app/client.ts"]+            input: [options?.entry ?? defaultOptions.entry]
           },
           assetsDir: options?.assetsDir ?? defaultOptions.assetsDir,
           manifest: true

適用したら、次の手順。 まず、 vite.config.tsにて、クライアント/サーバーともにエントリーポイントを書き換える。 このとき、 server側 (honox/vite) も同様に appにあることを前提としたコードがあるのだが、そこについてはオプションで対応できるので、あわせて指定している (islandComponents)。

import pages from"@hono/vite-cloudflare-pages";import honox from"honox/vite";import client from"honox/vite/client";import{ defineConfig }from"vite";import path from"node:path";exportdefault defineConfig(({ mode })=>{if(mode ==="client"){return{
      plugins: [client({ entry: "/src/client.ts"})],};}return{
    plugins: [
      honox({
        entry: "/src/server.ts",
        islandComponents: {
          isIsland: (id)=>{return path
              .resolve(path.join(import.meta.dirname,"src", id))
              .includes("islands");},},}),
      pages(),],};});

次はサーバー側のエンドポイントにて、自動検索されるパスをすべて置き換える。 基本は次のようにすれば動くはず。 routesも変えたい!という場合は良い感じに書き換えよう。

// src/server.ts
mport { showRoutes }from"hono/dev";import{ createApp }from"honox/server";const app = createApp({
  root: "/src/routes",
  NOT_FOUND: import.meta.glob("/src/routes/**/_404.(ts|tsx)",{
    eager: true,}),
  ERROR: import.meta.glob("/src/routes/**/_error.(ts|tsx)",{
    eager: true,}),
  RENDERER: import.meta.glob("/src/routes/**/_renderer.tsx",{
    eager: true,}),
  MIDDLEWARE: import.meta.glob("/src/routes/**/_middleware.(ts|tsx)",{
    eager: true,}),
  ROUTES: import.meta.glob("/src/routes/**/!(_*|*.test|*.spec).(ts|tsx|mdx)",{
    eager: true,}),});

showRoutes(app);exportdefault app;

同様にしてクライアント側のエントリーポイントも設定する。

// src/client.tsimport{ createClient }from"honox/client";

createClient({
  island_root: "/src",
  ISLAND_FILES: {
    ...import.meta.glob("/src/islands/**/[a-zA-Z0-9[-]+.(tsx|ts)"),
    ...import.meta.glob("/src/routes/**/_[a-zA-Z0-9[-]+.island.(tsx|ts)"),},});

最後に、 Renderer においてクライアント側エントリーポイントのパスを指定している場所があるので、書き換える。

--- a/app/routes/_renderer.tsx+++ b/src/routes/_renderer.tsx@@ -9,10 +9,10 @@ export default jsxRenderer(({ children, title }) => {<meta charset="utf-8" />
         <meta name="viewport" content="width=device-width, initial-scale=1.0" />
         <title>{title}</title>
-        <Script src="/app/client.ts" async />+        <Script src="/src/client.ts" async /><Style />
       </head>
       <body>{children}</body>
     </html>

あとはいつも通り開発環境を起動すると、もろもろが動く。終わり。

サンプル:

github.com


Viewing all articles
Browse latest Browse all 8071