Node.js
Hosting
Firebase
Functions

Node.js によるアプリを Firebase で Hosting する最短の道

はじめに

Firebase のホスティング、優れものです。静的コンテンツはもちろんのこと、なんと Node.js による動的コンテンツまでホスティングできちゃいます。それも開発時とか小さなサービスなら実質無料でいけちゃう感じです。

理解するために、静的コンテンツと動的コンテンツのホスティングについて、実現までの最短の道を見て見ます。

ちなみに静的コンテンツだけで OK なら、以下の公式ガイドを参照すれば大丈夫でしょう。
https://firebase.google.com/docs/hosting/quickstart?hl=ja

準備

  • Node.js と npm をインストールしてください。
    https://nodejs.org/en/
    この記事は、8.10.0 LTS で検証しています。

  • Firebase のプロジェクトを用意してください。

  • 手元のコンピュータに作業用のフォルダを作ってください。

  • Firebase CLI をインストールしてください。

$ npm install -g firebase-tools
  • Firebase のアカウントと紐付けてください。
$ firebase login

アプリを初期化する

$ cd <作業用のフォルダ>
$ firebase init

以下のような画面になります。Hosting と Functions を選択してください。

     🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥     🔥🔥🔥     🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥     🔥🔥 🔥🔥       🔥🔥     🔥🔥  🔥🔥   🔥🔥  🔥🔥       🔥🔥
     🔥🔥🔥🔥🔥🔥    🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥   🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥
     🔥🔥        🔥🔥  🔥🔥    🔥🔥  🔥🔥       🔥🔥     🔥🔥 🔥🔥     🔥🔥       🔥🔥 🔥🔥
     🔥🔥       🔥🔥🔥🔥 🔥🔥     🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥 🔥🔥🔥🔥🔥🔥🔥🔥  🔥🔥     🔥🔥  🔥🔥🔥🔥🔥🔥  🔥🔥🔥🔥🔥🔥🔥🔥

You're about to initialize a Firebase project in this directory:

  <作業用のフォルダ>

? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your choices. 
 ◯ Database: Deploy Firebase Realtime Database Rules
 ◯ Firestore: Deploy rules and create indexes for Firestore
 ◉ Functions: Configure and deploy Cloud Functions
❯◉ Hosting: Configure and deploy Firebase Hosting sites
 ◯ Storage: Deploy Cloud Storage security rules

いくつか選択肢が出て答えを求められます。下のように答えたとして話をすすめます。

? Select a default Firebase project for this directory: <Firebase のプロジェクト名>
? What language would you like to use to write Cloud Functions? JavaScript
? Do you want to use ESLint to catch probable bugs and enforce style? No
? Do you want to install dependencies with npm now? Yes

? What do you want to use as your public directory? public
? Configure as a single-page app (rewrite all urls to /index.html)? No

終了すると作業用フォルダは以下のような構成になっています。

.
├── firebase.json
├── functions
│   ├── index.js
│   ├── node_modules
│   ├── package-lock.json
│   └── package.json
└── public
    ├── 404.html
    └── index.html

public フォルダが静的コンテンツを入れるフォルダで、functions が動的コンテンツを入れるフォルダです。作業用のフォルダがからの状態から始めたとしたら、firebase-cli によって、ダミーのコンテンツが入っているはずです。
functions/index.js は何もしないコードになってるので、エディタであけてコメントを外して、下のようなコードにしてください。

const functions = require('firebase-functions');
exports.helloWorld = functions.https.onRequest((request, response) => {
 response.send("Hello from Firebase!");
})

ローカルで確認

firebase はローカルでシミュレートする機能を持っていますので、この時点で確認してみます。

静的コンテンツ

$ firebase serve

=== Serving from '<作業用のフォルダ>'...

i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000

http://localhost:5000 は以下のようになります。
ST1.png

5000番のポートで静的コンテンツがホストされるようになります。

動的コンテンツ

$ firebase serve --only functions

=== Serving from '<作業用のフォルダ>'...

i  functions: Preparing to emulate functions.
Warning: You're using Node.js v8.10.0 but Google Cloud Functions only supports v6.11.5.
✔  functions: helloWorld: http://localhost:5000/<Firebase のプロジェクト名>/us-central1/helloWorld

http://localhost:5000/<Firebase のプロジェクト名>/us-central1/helloWorld は以下のようになります。
ST3.png

  • 5000番のポートで動的コンテンツがホストされるようになります。

  • index.js の中で export している、exports.helloWorld という名前が URL に現れます。

  • Node.js のバージョンが高すぎ、みたいな警告出てます。気になるかたは、Nodeを v6.11.5 で。

混在

$ firebase serve --only hosting,functions

=== Serving from '<作業用のフォルダ>'...

i  functions: Preparing to emulate functions.
i  hosting: Serving hosting files from: public
✔  hosting: Local server: http://localhost:5000

Warning: You're using Node.js v8.10.0 but Google Cloud Functions only supports v6.11.5.
✔  functions: helloWorld: http://localhost:5001/<Firebase のプロジェクト名>/us-central1/helloWorld

5000番のポートで静的コンテンツが、5001番のポートで動的コンテンツがホストされるようになります。

デプロイ

ローカルで確認したときとちょっとオプションが違うので注意!

  • ローカル

    • 静的コンテンツ 無し
    • 動的コンテンツ --only functions
    • 混在      --only hosting,functions
  • デプロイ

    • 静的コンテンツ --only hosting
    • 動的コンテンツ --only functions
    • 混在      無し
$ firebase deploy 

=== Deploying to '<Firebase のプロジェクト名>'...

i  deploying functions, hosting
i  functions: ensuring necessary APIs are enabled...
✔  functions: all necessary APIs are enabled
i  functions: preparing functions directory for uploading...
i  functions: packaged functions (31.21 KB) for uploading
✔  functions: functions folder uploaded successfully
i  hosting: preparing public directory for upload...
✔  hosting: 2 files uploaded successfully
i  functions: updating function helloWorld...
✔  functions[helloWorld]: Successful update operation. 
Function URL (helloWorld): https://us-central1-<Firebase のプロジェクト名>.cloudfunctions.net/helloWorld

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/<Firebase のプロジェクト名>/overview
Hosting URL: https://<Firebase のプロジェクト名>.firebaseapp.com

以下のアドレスでホストされるようになります。

静的コンテンツは https://<Firebase のプロジェクト名>.firebaseapp.com
動的コンテンツは https://us-central1-<Firebase のプロジェクト名>.cloudfunctions.net/helloWorld

最後に

ここまでくれば、あとは自由に public と functions フォルダに必要なものを入れていけばいいでしょう。

Express などのミドルが必要になるなど、ちょっと踏み込みたくなったら、こちらの記事で本家のビデオを解説してるので、これも参照されるといいでしょう。

それではー