Vue Routerを使ったプロジェクトをFirebaseで公開するには?

Vue Routerを使ったプロジェクトをFirebaseで公開するには?

2022年3月31日


Vue Router を使ったプロジェクトを Firebase で公開するには?

Vue Router は Vue を使った Web アプリで、ページ毎に表示を切り替える場合に利用されます。ところが、設定によっては、「ページが見つからない」(404エラー)になる場合があります。原因は、Web サイトのページの切り替え(ルーティング)にあります。この記事では、Firebase を利用して、Vue Router を利用した、Vue アプリを公開する方法を紹介しています。

ルーティングの仕組み

Web サイトで表示するページを切り替える仕組みを「ルーティング」と呼んでいます。 簡単にいうと、Web ブラウザで指定したリンク(URL)によって、表示を切り替える事ができますが、この切り替えの仕組みをルーティングと呼んでいます。 この「切り替え」を行なっているのは、通常の Web サイトでは、Web サイトの情報を持っているサーバー(Web サーバー)が行なっています。

Web ブラウザは、指定されたリンク(URL)を Web サーバーに送って、表示する情報を Web サーバーから受け取って表示をしています。

Vue の表示の仕組み

Vue は「フロントエンドのフレームワーク」の一つで、「Web ブラウザで表示を管理する仕組み」です。 一般的に Vue で作成した Web アプリをインターネットで公開する場合には、Viteを使って Vue のプロジェクトを作成した場合には以下のコマンドを実行して公開用の情報(イメージ)を作成します。 (*)この連載では、Viteを Vue のサンプルプロジェクト(テンプレート/ひな型)を作成する方法を前提に紹介しています。

$ npm run build

この公開用の情報(イメージは)、作成した Vue のプロジェクトフォルダの下に「dist」というホルダーを作成してその下に作成されます。 実際に作成してこのフォルダの中身を見ると分かると思いますが、基本的にプロジェクトフォルダにある「index.html」を基にして、公開用のページである「dist/index.html」のファイルを作成して、必要な Javascript や CSS などのファイルを読み込むようになっています。作成した、Vue のアプリで利用する部品などの記述を基に、必要な、Javascript や CSS も同時に作成して「dist」フォルダの下に保存されます。

Vue のアプリの表示は、Web サーバーにこの「dist」フォルダの情報を保存して、「dist/index.html」の情報を Web サーバーから Web ブラウザが受け取って行われます。 Vue のアプリの表示に必要な情報は全部この時に Web サーバーから受け取る情報に含まれています。

Vue Router でページ毎の表示を行なっている場合でも、Vue Router は Vue アプリの一部なので、最初に必要な情報を Web サーバーから受け取っておけば、後は表示を切り替えても Vue アプリの中の場合には、Web サーバーから追加情報をもらう必要はありません。

二つある Vue Router の表示の仕組み

Vue Router を利用して、Vue アプリでページ毎の表示をする場合には、二つのやり方があります。

  • createWebHistory()で行う場合 (ヒストリーモード)
  • createWebHashHistory()で行う場合(ハッシュモード)

で、これは、「src/router/index.js」 で、Vue Router の設定を行う際に呼び出しています。 Vite で Vue のプロジェクト作成時に、「Vue Router を使う」を選択した場合には、標準設定では、「ヒストリーモード」に設定されています。

以下に設定をしている部分のコードを抜き出してみました。

// (src/router/index.js)
.....
const router = createRouter({
  history: createWebHistory(import.meta.env.BASE_URL),
  routes: [
    {
      path: '/',
      name: 'home',
      component: HomeView
    },
   .......
  ]
})
.....

この「history: createWebHistory(import.meta.env.BASE_URL),」の部分を置き換えると設定を変える事ができます。

ヒストリーモードの場合、リンク(URL)の指定の方法は、通常の Web サイトの指定の方法と同じように指定できます。 Viteの標準設定で作成される Vue のサンプルプロジェクトの場合、「Home(/)」と「About(/about)」の二つのページが作成されていますが、「About (/about)」のページを表示する場合、ヒストリーモードでは、Firebase のドメイン名(リンク/URL)が「text-xxxx.web.app」の場合には、「test-xxxx.web.app/about」の様に指定して表示する事ができます。ハッシュモードの場合には、「test-xxxx.web.app/#/about」の様に「#(ハッシュ)」を入れる必要があります。

実際の開発では、開発用の Web サーバーを開発用の PC で動かして表示させながら動作を確認しながら行います。

$ npm run dev

で開発用の Web サーバーが起動されて、標準設定では、「localhost:3000」でアクセスできます。

  • ハッシュモードでは「localhost:3000/#/about」
  • ヒストリーモードでは「localhost:3000/about」

でアクセスできます。

開発用の Web サーバーでは、特に何もしなくても問題なく表示ができるので Vue Router を使った場合でも特に意識する必要はありません。

ところが、実際に Firebase でインターネットに公開するとハッシュモードの場合は問題が起きませんが、ヒストリーモードを使っている場合には Web ブラウザでリンク(URL)を指定すると「ページが見つからない」(404エラー)が発生します。

これは、Web ブラウザの動作がハッシュモードとヒストリーモードで違うために発生します。

Web ブラウザでリンクを指定する場合に、「#」(ハッシュ)は、表示しているページの特定の場所に「印」を付けておいて、その部分を表示する際に使われます。 これは、HTML の基本的な決まりで Web ブラウザは「今表示しているページ」というのがわかっているので、Web サーバーにリクエストを送りません。Vue の仕組みがページの切り替えをやってくれるので、正常にページの切り替えが動作します。

ところが、ヒストリーモードで指定すると、Web ブラウザ自体は Vue のアプリが動いているかどうかはわからないので、Web サーバーに「about」のページのリクエストを送ってしまいます。ところが、Web サーバー側には「about」のページは存在しないので、「ページがないよ!」と404エラーで応答します。そのため、Web ブラウザはエラーで表示してしまうという現象が起きます。実は、Vue Router で作ったページは、「dist/index.html」の一部で、実際には Web サーバー上では存在しないページだからです。

そのため、正常に動作させるためには、Web サーバーに「about」のページは、「dist/index.html」(Web サーバー上ではindex.html)であることを教えておく必要があります。

Firebase の設定方法は?

実際にインターネットに公開する場合には、利用している Web ホスティングによって設定が違います。 この記事では、Firebase を利用する場合の設定について紹介します。(その他の Web サーバーの場合は、インターネットを検索してください。)

既に、Firebase で Web ホスティングをする場合には、

  1. Google にアカウントを作成
  2. 「firebase login」で Firebase アカウントにログイン
  3. プロジェクトフォルダで「firebase init」で Firebase の設定を初期化
  4. 「firebase deploy」でインターネットに公開

の手順でインターネットに公開できます。

Vue Router を利用する場合には、三番目の Firebase の初期化が終わった後に設定の変更を行います。 この設定で、プロジェクトフォルダに「firebase.json」という Firebase の設定ファイルが作成されるので、このファイルに設定を追加します。

{
  "hosting": {
    "public": "dist",
    "rewrites": [
      {
        "source": "**",
        "destination": "/index.html"
      }
    ],
    "ignore": ["firebase.json", "**/.*", "**/node_modules/**"]
  }
}

ポイントは、「rewrite」を追加することです。 この、「rewrite」で「"source": "**"」は、全てのページのリクエストを「"distination": "/index.html"」にするという設定です。 つまり、全てのリクエストに「/index.html」で応答する様にするので「ページが見つからない」というエラーは発生しません。 実際のページの切り替えの処理は、Vue が Web ブラウザの中で行うという事になります。

まとめ

Web 開発では、開発中は、実際のインターネット上の Web サーバーではなく、開発用の PC 上で開発用の Web サーバーを動かして動作を確認しながら行う場合が多くなります。しかし、開発用の Web サーバーと実際の Web サーバーでは、細かい設定の違いがある場合も多く、どちらも同じ様に動作するとは限りません。 従って、開発用の Web サーバーで動作を確認した場合でも、実際に稼働しているインターネット上のサーバーでも動作を確認する事が重要です。

Vue Router でヒストリーモードを利用する場合は、その良い例です。開発用の Web サーバーは、この記事で説明したような設定が予めされているので動作は問題ないように見えますが、実際の Web サーバーでは設定が、Web サーバー毎に違う場合が多く、違った動作をします。こうした挙動は、多くの方が経験するエラーで実はインターネット上にはたくさんの情報があります。実際に試すのも勿論大切ですが、こうしたインターネットの情報を調べたりして、よくある共通の問題に対する知識を増やすこともスムーズに Web 開発を進める秘訣になります。


Copyright(c) 2017-2021 by Silicon Valley Super Ware, all rights reserved.

コメント

このブログの人気の投稿

ユーザーインターフェースの設計

足し算以外もできるようにする

改良版足し算プログラム