2023/09/13

[Vite] マルチページを作成した際は rewrite を正しく設定しなければならない

Vite では、以下のように rollupOptions.input を指定することでマルチページアプリケーションを作ることが可能です。

vite.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
export default defineConfig({
  // 省略
  build: {
    rollupOptions: {
      input: {
        main: resolve(__dirname, 'src/main/index.html'),
        admin: resolve(__dirname, 'src/admin/index.html'),
        user: resolve(__dirname, 'src/user/index.html'),
      },
    },
  },
});

場合によっては便利なのですが、この設定をした上で Vue Router のようなルーティング機能を使うと問題がおこるので注意しなければなりません。

例えば main 以下に /main/users/1200 のようなサブページを作りたい場合、ルーターの設定をしただけでは動かないはずです。

この場合、サーバーは /main/users/1200 などというページが存在しないので、特定のページに rewrite します。 これが、 Vite の dev server の場合、デフォルトで /index.html なのです。つまり、そんなページは存在しないとエラーを吐かれてしまいます。

これを、 /main.html に rewrite するよう、設定を変更しなければなりません。

dev server

npm run dev 等で開発サーバーを立ち上げた場合、 Vite が内部に持っているサーバーが立ち上がります。 このサーバーの rewrite を設定するには、以下のように vite.config.ts に plugins を設定します。

vite.config.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
export default defineConfig({
  // 省略
  plugins: [
    {
      name: 'rewrite-route',
      configureServer({ middlewares }) {
        middlewares.use((req, _, next) => {
          if (req.url != null) {
            if (req.url.startsWith('/main/')) {
              req.url = '/main.html';
            } else if (req.url.startsWith('/admin/')) {
              req.url = '/admin.html';
            } else if (req.url.startsWith('/user/')) {
              req.url = '/user.html';
            }
          }
          next();
        });
      },
    },
  ],
});

Firebase Hosting

この挙動はサーバー側のものですから、サーバーの種類を変えた場合、設定方法も変わります。

本番環境にデプロイする場合は、こちらも考慮しなければなりません。

例えば Firebase Hosting の場合、以下のような設定ファイルを用意することで rewrite を制御することが可能です。

firebase.json
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
{
  "hosting": {
    "public": "dist",
    "ignore": [
      "firebase.json",
      "**/.*",
      "**/node_modules/**"
    ],
    "rewrites": [
      {
        "source": "/main/**",
        "destination": "/main.html"
      },
      {
        "source": "/admin/**",
        "destination": "/admin.html"
      },
      {
        "source": "/user/**",
        "destination": "/user.html"
      },
      {
        "source": "**",
        "destination": "/error.html"
      }
    ]
  }
}

大抵のホスティングサービスは、こういった制御が可能になっていますので、各サービスのマニュアルを参照してください。

0 件のコメント: