何番煎じだって感じの内容ですが、ちょっとVue周りの知見を得たかったのと、これらを使って試してみたい事があったのでやってみた。

今回はNuxtでgenerateしたhtml,css,jsファイル類を置く所までの記事とするのでFirebaseはHostingのみ利用します。
Cloud Functionsを利用してサーバーレスでSSR(サーバーサイドレンダリング)もやっている方が居ますが、そこら辺は必要になったら試していこうと思います。

Dockerは個人的に開発機に直接コマンド類をインストールしていくのが嫌なので利用します。

 

Docker で環境を作る

適当な場所に作業用ディレクトリを作成しましょう。

$ mkdir -p ~/Documents/docker/nuxt

そこにターミナルで移動してDockerfileを作成。

cd ~/Documents/docker/nuxt
$ vi Dockerfile

Dockerfileを以下のように編集して保存。

FROM node:8-alpine
WORKDIR /work
ENV HOST 0.0.0.0
ENV PORT 80
EXPOSE 80

Dockerイメージのビルド。

$ docker build -t nuxt-image .
$ docker images
REPOSITORY TAG IMAGE ID CREATED SIZE
nuxt-image latest 51d03c8913af 5 seconds ago 66.3MB
node 8-alpine 5c0c5c94503f 2 days ago 66.3MB

Dockerイメージからコンテナを作成して実行。
後でブラウザからアクセスする為Macの80番ポートとコンテナの80番ポートを繋げておきます。

$ docker run -itd --name nuxt -p 80:80 nuxt-image

コンテナ内に入る。

$ docker exec -it nuxt sh
/work #

ここに諸々インストールしていき開発環境を作って行きます。

Nuxt プロジェクトを作る
とりあえずサンプルとしてcreate-nuxt-appで適当にプロジェクトを作る。

/work # yarn create nuxt-app nuxt

途中で幾つかの項目に入力を求められるので今回は以下のように答えました。

? Project name nuxt
? Project description My kryptonian Nuxt.js project
? Use a custom server framework none
? Use a custom UI framework none
? Choose rendering mode Single Page App
? Use axios module no
? Use eslint no
? Use prettier no
? Author name hoge太郎
? Choose a package manager yarn

さっそくnuxtの組み込みサーバーを起動してみます。

/work # cd nuxt/
/work/nuxt # yarn run dev

成功すると下記のような出力が出るはずです。

yarn run v1.12.3
$ nuxt
ℹ Preparing project for development                                                                                 15:30:42
ℹ Initial build may take a while                                                                                    15:30:42
✔ Builder initialized                                                                                               15:30:42
✔ Nuxt files generated                                                                                              15:30:42

✔ Client
  Compiled successfully in 5.45s

ℹ Waiting for file changes                                                                                          15:30:48

   ╭────────────────────────────────────────╮
   │                                        │
   │   Nuxt.js v2.3.4                       │
   │   Running in development mode (spa)    │
   │   Memory usage: 123 MB (RSS: 211 MB)   │
   │                                        │
   │   Listening on: https://172.17.0.2:80   │
   │                                        │
   ╰────────────────────────────────────────╯

ブラウザでDocker内で起動したNuxtプロジェクトにアクセスしてみる。

ちゃんとHMRも効いているので編集内容が直ぐに反映されて捗ります。
後はこれをFirebaseにデプロイして動けばとりあえず完了です。
非常に簡単ですね!

 

Firebase で動かす

事前準備としてFirebaseに必要なGoogleアカウントを用意してください。
そして予めFirebase consoleにログインしておきましょう。


コンテナ内にFirebase toolをインストールします。

/work/nuxt # yarn global add firebase-tools

Firebaseにログインします。
コンテナ内でログインする為に–no-localhost オプションを付けます。

/work/nuxt # firebase login --no-localhost

Firebaseに匿名情報を送信してよいか聞かれるので丁重にお断りする。

? Allow Firebase to collect anonymous CLI usage and error reporting information? No

ターミナル上にURLが表示される。
最後にコードをここに入力してと言われているのでブラウザで認証を行います。

Visit this URL on any device to log in:
https://accounts.google.com/o/oauth2/auth?client_id=563584335869-fgrhgmd47bqnekij5i8b5pr03ho849e6.apps.googleusercontent.com&scope=email%20openid%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloudplatformprojects.readonly%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Ffirebase%20https%3A%2F%2Fwww.googleapis.com%2Fauth%2Fcloud-platform&response_type=code&state=690692950&redirect_uri=urn%3Aietf%3Awg%3Aoauth%3A2.0%3Aoob

? Paste authorization code here:

このURLをFirebaseにログインしているブラウザで開きましょう。


最後に出てきたコードをコピーしてターミナルに貼り付け。

? Paste authorization code here: 4/wgBwkKtgnLJktghWTJB8qHP4H-g79vbz6rV1kcAWqWWKADICgCEmvo8

✔ Success! Logged in as taro.hoge.braver@gmail.com

ログイン完了です。

そしたらFirebase Hosting上にファイルをアップロードする準備を行います。
まず先程作ったNuxtプロジェクトをgenerate コマンドで静的ファイル化します。

/work/nuxt # yarn run generate
yarn run v1.12.3
$ nuxt generate
ℹ Production build                                                                                                  16:16:26
✔ Builder initialized                                                                                               16:16:26
✔ Nuxt files generated                                                                                              16:16:26

✔ Client
  Compiled successfully in 10.66s


Hash: bf4ab9f4bfa678652068
Version: webpack 4.28.3
Time: 10667ms
Built at: 2018-12-29 16:16:37
                  Asset       Size  Chunks             Chunk Names
3c2c61bd4581f826e2bf.js   31.9 KiB       0  [emitted]  app
3fc0b54c921cc8f62cc3.js    141 KiB       1  [emitted]  commons.app
4efc9cccfed713e52a56.js   3.59 KiB       2  [emitted]  pages/index
               LICENSES  426 bytes          [emitted]
f3c8b4c523e66b42454e.js   2.15 KiB       3  [emitted]  runtime
 + 2 hidden assets
Entrypoint app = f3c8b4c523e66b42454e.js 3fc0b54c921cc8f62cc3.js 3c2c61bd4581f826e2bf.js
ℹ Generating pages                                                                                                  16:16:37
✔ Generated /                                                                                                       16:16:38
Done in 13.85s.

生成されたファイルはdistというディレクトリ以下に作られています。

/work/nuxt # ls -al dist
total 28
drwxr-xr-x    3 root     root          4096 Dec 29 16:16 .
drwxr-xr-x   13 root     root          4096 Dec 29 16:16 ..
-rw-r--r--    1 root     root             0 Dec 29 16:16 .nojekyll
-rw-r--r--    1 root     root          2661 Dec 29 16:16 200.html
-rw-r--r--    1 root     root           362 Dec 29 16:16 README.md
drwxr-xr-x    2 root     root          4096 Dec 29 16:16 _nuxt
-rw-r--r--    1 root     root          1150 Dec 29 16:16 favicon.ico
-rw-r--r--    1 root     root          2441 Dec 29 16:16 index.html

このファイル一式をFirebase Hostingにアップロードする事で世の中へ公開する事が出来ます。
さっそくfirebase-toolsを使ってデプロイして行きましょう。
まずはセットアップから。

/work/nuxt # firebase init

すると幾つか質問されるので答えていきます。

/work/nuxt # firebase init

     ######## #### ########  ######## ########     ###     ######  ########
     ##        ##  ##     ## ##       ##     ##  ##   ##  ##       ##
     ######    ##  ########  ######   ########  #########  ######  ######
     ##        ##  ##    ##  ##       ##     ## ##     ##       ## ##
     ##       #### ##     ## ######## ########  ##     ##  ######  ########

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

  /work/nuxt

Before we get started, keep in mind:

  * You are currently outside your home 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

今回はHostingのみ。

? Which Firebase CLI features do you want to setup for this folder? Press Space to select features, then Enter to confirm your
choices. Hosting: Configure and deploy Firebase Hosting sites

=== Project Setup

First, let's associate this project directory with a Firebase project.
You can create multiple project aliases by running firebase use --add,
but for now we'll just set up a default project.

? Select a default Firebase project for this directory:
  [don't setup a default project]
❯ [create a new project]

Firebase上にプロジェクトをまだ作っていなかったのでここで作ってしまいます。

? Select a default Firebase project for this directory: [create a new project]

=== Hosting Setup

Your public directory is the folder (relative to your project directory) that
will contain Hosting assets to be uploaded with firebase deploy. If you
have a build process for your assets, use your build's output directory.

? What do you want to use as your public directory? (public) dist

公開するディレクトリをどうするか聞かれています。
Nuxtでgenerateされたファイル一式はdistディレクトリに展開されるのでそれを指定します。

? Configure as a single-page app (rewrite all urls to /index.html)? (y/N) y

SPAでいいのかって聞かれているのでYesと答える。

? File dist/index.html already exists. Overwrite? (y/N) n

既にindex.htmlがあるけど上書きしていいかって聞かれるのでNoと答える。

i  Skipping write of dist/index.html

i  Writing configuration info to firebase.json...
i  Writing project information to .firebaserc...

✔  Firebase initialization complete!

Project creation is only available from the Firebase Console
Please visit https://console.firebase.google.com to create a new project, then run firebase use --add

終わったようです。

いよいよデプロイします。

/work/nuxt # firebase deploy

Error: No project active. Run with --project <projectId> or define an alias by
running firebase use --add

おや、エラー。
どうやら勝手にFirebaseプロジェクトを作ってくれるわけじゃないらしいですね。

Please visit https://console.firebase.google.com to create a new project, then run firebase use --add

よくよく見るとinitコマンドの最後にFirebase Consoleから作ってねって出てますね…
仕方ないのでブラウザ上で作ります。

プロジェクト名は適当に、地域は日本、Cloud Firestoreは今回使用しないのでデフォルトのまま、Googleアナリティクスのデータ共有はとりあえずオフで。

この辺も特に必要ないのでチェックなしで作成します。

プロジェクトが作られました。
プロジェクトIDは「nuxt-7e934」だったのでfirebase use –add でこれを設定します。

/work/nuxt # firebase use --add
? Which project do you want to add? (Use arrow keys)
❯ nuxt-7e934

ちゃんと候補に出てきているのでこれを選択します。

? What alias do you want to use for this project? (e.g. staging)

なんて別名つけんの?stagingとか?って聞かれたのでとりあえずstagingで。

? What alias do you want to use for this project? (e.g. staging) staging

Created alias staging for nuxt-7e934.
Now using alias staging (nuxt-7e934)

設定されたらしい。
もう一度デプロイ。

/work/nuxt # firebase deploy

=== Deploying to 'nuxt-7e934'...

i  deploying hosting
i  hosting[nuxt-7e934]: beginning deploy...
i  hosting[nuxt-7e934]: found 9 files in dist
✔  hosting[nuxt-7e934]: file upload complete
i  hosting[nuxt-7e934]: finalizing version...
✔  hosting[nuxt-7e934]: version finalized
i  hosting[nuxt-7e934]: releasing new version...
✔  hosting[nuxt-7e934]: release complete

✔  Deploy complete!

Project Console: https://console.firebase.google.com/project/nuxt-7e934/overview
Hosting URL: https://nuxt-7e934.firebaseapp.com

上手く行ったようです。
https://nuxt-7e934.firebaseapp.com にアクセスしてみましょう。

タ━━━ヽ(∀゚ )人(゚∀゚)人( ゚∀)ノキ━━━!!

PWAは?


デフォルトではPWAに対応していないので対応をします。

/work/nuxt # yarn add '@nuxtjs/pwa'

nuxt.config.jsのmodules内に以下を追記。

  modules: [
    '@nuxtjs/pwa' <-- この1行を追加。
  ],

もう一度generate & deploy。

/work/nuxt # yarn run generate
/work/nuxt # firebase deploy


スマホでアクセスしてみる。
[one_fifth][/one_fifth]
[one_fifth][/one_fifth]
[one_fifth][/one_fifth]
[one_fifth][/one_fifth]
[one_fifth last][/one_fifth]
[clear]

ちゃんとホーム画面に保存して開くとブラウザのバーが消えてます。
オフラインでも表示されますし、ちゃんとPWAしてますね。
素晴らしい!

ここまでで一通りやりたかった事が全て出来ました。

 

まとめ

FirebaseのRealtimeDatabaseにデータを保存して利用すればこれだけでSPA×PWAのWEBアプリケーションを開発出来そうです。
Nuxtを利用すると最先端のWEBアプリ開発環境が非常に簡単に作れるのは便利ですね。

FirebaseもHostingだけじゃなくてWEBプッシュやFunctionsでちょっとしたバックエンドの処理を書いてみたり出来るので今後の為にも利用しておいて損は無いでしょう。
サーバーレスも流行りですし。

またNuxtの代わりにionicとか使ってiOSやAndroidアプリを作ってみるのも面白そうです。
私はこれらを使ってJSON Schemaで画面やデータ等の設計をするだけで、管理画面、API、HTML5のスマホサイトが出来上がるようなプロトタイプ制作ツールを作ってみようかと思います。

長々と書いてきましたが、簡単なWEBアプリを作るのにこの構成は結構いいのでは?と思ったので今回記事にしてみました。
よかったらお試しください。