ここ1ヶ月程Nuxt.js + FirebaseでSPAのシステムを作っていました。
短期構築がご要望でリアルタイム性が求められる内容。Firebaseに向いていると判断、提案したところ技術構成は自由にやらせていただけることになりました。
別件で一昨年末あたりからずっとバックエンドはLaravel、フロントエンドは素のVue.js + Vuex + Vue Routerで開発やってるんですが、PWA化したほうがよさそうだったこともあってNuxt.js(以降Nuxt)使ってみようかなってことで採用。
Nuxt、便利ですね。特にプラグインとミドルウェアが素敵!
Firebase(今回使用したのはAuthentication、Firestore、Hosting、Functions)との相性もバッチリでした。
ですが初めてということもありいろいろと悩んだりもするわけで…
それらをどう解決したか?の小ネタ集です(というか今回の落とし所、かな)
設定ファイルの扱いをどうするか?という悩みです。
バックエンドにFirebaseを使用していることもあり、クライアント側にapiKey等の設定をもたせる必要がありました。当然ながら開発用の設定と本番用の設定は異なります。
開発者の勘を働かせて(大げさ)envというキーワードでモジュールを調査。結果、cross-envを採用しました。
Qiitaにきっちりまとめてくださっている方がいらっしゃったので助かりました
Nuxtでcross-envを使い環境ごとに環境変数を分ける
今回のpackege.jsonのscriptsは以下のように開発・動作確認用Firebaseプロジェクトへのデプロイ用のbuild:staging、顧客練習用のbuild:trainingを追加しています。
"scripts": {
"dev": "nuxt",
"build": "nuxt build",
"build:staging": "cross-env NODE_ENV=\"staging\" nuxt build",
"build:training": "cross-env NODE_ENV=\"training\" nuxt build",
"start": "nuxt start",
"generate": "nuxt generate",
"lint": "eslint --ext .js,.vue --ignore-path .gitignore .",
"precommit": "npm run lint"
},
Nuxtでは通常のnuxt buildを行うとNODE_ENVはproductionになりますのでbuildをそのまま本番用としています。
ライブラリインスタンスの初期化をどこで行うか?という悩みです。
例えばFirebaseを利用するにはFirebaseプロジェクト用設定での初期化が必要ですが、プラグインの仕組みを利用して初期化するのが常道のようです。
確かに実行タイミング的に適していますね。
plugins/firebase.js
import firebase from 'firebase/app'
import 'firebase/auth'
import 'firebase/firestore'
if (!firebase.apps.length) {
firebase.initializeApp(process.env.firebase)
}
export default firebase
利用側では初期化したインスタンスをimportして利用します。
store/index.js
import firebase from '~/plugins/firebase'
export const strict = false
const db = firebase.firestore()
// 以下略
せっかく用意されている厳格モード、ご指導いただくべき?という悩みです。
Vuexの厳格モードは人類には厳しすぎる!というのが私の感想です。
前掲の利用側コードにありますがVuexの厳格モードは export const strict = false でオフにしました(開発中も)
ドキュメントに「本番環境で厳格モードを有効にしてデプロイしてはいけません! 」とあることですし、気にしない。
問題なく開発できる方は厳格モードを活用してください。
同じ処理をバラバラ書くのは避けたいもの。どこにまとめるべき?という悩みです。
プラグインに落ち着きました。さまざまなインジェクションも可能ですし、いろいろな場所で使う処理をあつかうのに便利です。他で再利用することは無いようなプロジェクト独自の処理もプラグインに書いています。
plugins/forApp.js
import Vue from 'vue'
import { cloneDeep } from 'lodash'
import firebase from '~/plugins/firebase'
const forApp = {
testA: function(a) {
return a
},
testB: function() {
return this.testA('b')
}
}
Vue.prototype.$forApp = forApp
export default forApp
のような感じでインジェクションとエクスポートを行えばvueファイル内ではthis.$forApp.testA(‘ええじゃないか’)みたいに使えますし、前掲のfirebase.jsのようにimportして使用することもできます。
こんなもんかな。
もっと良い方法があったら教えてくださいね。