Vercelでrewriteの設定をvercel.jsonもしくはServerless Functions with Honoで行う

マイクロフロントエンドの実装方法として、Vercelを使用した2つの方法が紹介されています。1つ目はvercel.jsonでリライトルールを設定し、別のサイトのURLを指定する方法です。下層ページがある場合には正規表現を使用します。2つ目はHonoとServerless Functionsを使用し、コードで実装する方法です。vercel.jsonにHonoのソースコードを配置し、api/index.tsでリライトの実装を追加します。実現したい要件によってはvercel.jsonのリライトでは満たせない場合もありますが、JSONファイルだけで実現できる場合はコードを書く必要はありません。ただし、設定項目やレスポンスのカスタマイズが必要な場合もあるため、やり方を知っておくことは役に立つかもしれません。

広告ここから
広告ここまで

目次

    マイクロフロントエンド・・・というには大袈裟ですが、複数のサイト(CMS + Next.jsなどと、コードから生成するDocsサイトなど)を同一ドメインでホストしようとすると、rewriteルールの設定が必要になります。

    今回はVercelで、Next.jsの機能を使わずに実装する方法を2つ試しました。

    vercel.jsonでリライトルールを設定する

    確実なのはこちらです。destinationにもう一つのサイトのURLを指定しましょう。

    {
      "rewrites": [
        {
          "source": "/SUBDIRECTORY_NAME",
          "destination": "https://DESTINATION_DOMAIN/SUBDIRECTORY_NAME"
        },
      ]
    }

    下層ページがある場合は、正規表現をパスにつけます。

    {
      "rewrites": [
        {
          "source": "/proxy/:match*",
          "destination": "https://example.com/:match*"
        }
      ]
    }

    HonoとServerless Functionsで実装する

    もう一つの方法は、コードで実装するものです、vercel.jsonでHonoのソースコードを配置しているディレクトリにリライトさせましょう。

    {
      "rewrites": [
        {
          "source": "/(.*)",
          "destination": "/api"
        },
      ]
    }

    その後api/index.tsでリライトの実装を追加します。

    import { Hono } from 'hono'
    import { handle } from 'hono/vercel'
    
    export const config = {
      runtime: 'edge',
    }
    
    const app = new Hono()
    const elementsApp = new Hono()
    
    elementsApp.get('/*', c => {
      const path = c.req.path.replace(/^\/SUBDIRECTORY_NAME/, '')
      return fetch(`https://DESTINATION_DOMAIN/SUBDIRECTORY_NAME${path}`)
    })
    
    app.route('/SUBDIRECTORY_NAME', elementsApp)
    
    export default handle(app)
    

    vercel.jsonのリライトで要件を満たせない場合があるなら、Honoを使う?

    JSONファイルを配置するだけで実現できる要件を、わざわざコードを書いて対応する必要はないと思います。とはいえ、この手の作業はどこかで「設定項目が足りない」か「レスポンスなどをカスタマイズしないといけない」ケースが起きます。そんな時のためにやり方を知っておいても損はしないかなと思いました。

    広告ここから
    広告ここまで
    Home
    Search
    Bookmark