FirebaseとNuxt.jsで、CRUDのベストプラクティスを作ってみます。
できあがったもののプレビューはこちらから
■nuxt-basic-crud2
https://nuxt-basic-crud2.firebaseapp.com
作ったファイルは以下にアップしています。
■dog-ears/nuxt-basic-crud
https://github.com/dog-ears/nuxt-basic-crud
【環境】
・Windows10
・Visual Studio Code
・Node(Nodist)
ホスティングは、firebase hostingを使用する。
データベースは、Cloud Firestoreを使用する。
Nuxtは、サーバーサイドレンダリング(SSR)させる。
yarnは使わず、npmを使う。
(1)環境の準備
###1) Visual Studio Codeをインストール
###2) Nodeは、Nodistを使用。
■Nodist(公式)
https://github.com/nullivex/nodist/releases
2020年2月現在、Cloud FunctionsのNode.jsのバージョンは、10.15.3
■The Node.js 10 Runtime(英語)
https://cloud.google.com/functions/docs/concepts/nodejs-10-runtime?hl=en
nodistインストール後、下記実行
nodist + 10.15.3
nodist 10.15.3
nodeのバージョンは、10.15.3
npmのバージョンは、6.4.1
npxのバージョンは、10.2.0
#(2)Firebase の準備およびhostingテストまで。
###1) firebaseコンソールでやること
firebaseコンソールをブラウザで開く
https://console.firebase.google.com
googleアカウントでログインする。
プロジェクトの作成
googleアナリティクスは使用するとする。
Databaseを選択し、「データベースの作成」を選ぶ
「テストモードで開始」を選んで、「有効にする」を押す
Hostingを選択し、始めるを選ぶ。
###2)Firebase CLIのインストールおよびデプロイまで
ローカルにプロジェクトフォルダを作成する。
以後、[project_folder]とする。
Visual Studio Codeで、プロジェクトフォルダを開きコンソールから、以下実行
CLIのインストール
npm install -g firebase-tools
ログインと初期化
firebase login
firebase init
? Are you ready to proceed?
→ Y
? Which Firebase CLI features do you want to set up for this folder? Press Space to select features, then Enter to confirm your choices. (Press <space> to select)
→ Firestore、Functions、Hosting
? Select a default Firebase project for this directory:
→Use an existing project
→ 先ほど作ったプロジェクトを指定
— Firestore関連の質問 —
? What file should be used for Firestore Rules? (firestore.rules)
→ そのままenter
? What file should be used for Firestore indexes? (firestore.indexes.json)
→ そのままenter
— Functions関連の質問 —
? 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? (y/N)
→ n
? Do you want to install dependencies with npm now?
→ Y
— Hosting関連の質問 —
? What do you want to use as your public directory? (public)
→ そのままenter
? Configure as a single-page app (rewrite all urls to /index.html)?
→ N
これで、Firebaseの初期化が完了しました。
ディレクトリ構成は以下のようになっているかと思います。
[プロジェクトディレクトリ]
┣functions
┃┣node_modelus
┃┣.gitignore
┃┣index.js
┃┣package-lock.json
┃┗package.json
┣public
┃┣404.html
┃┗index.html
┣.firebaserc
┣.gitignore
┣firebase.json
┣firestore.indexes.json
┗firestore.rules
firebase serve
で、ローカルサーバーが立ち上がり、
http://localhost:5001
で、functionsのページが、
http://localhost:5000
で、Welcome Firebase Hosting Setup Completeのページが開きます。
ctrl + cでいったんサーバーを終了。
firebase deploy
で、
https://[プロジェクト名].firebaseapp.com/
にページがアップされます。
#(3)Functions の準備およびHostingからFunctionsを呼ぶまで。
###1) Node10ランタイムの設定
(参考)SSR モードの Nuxt.js を Firebase に Deploy する Tutorial
https://qiita.com/okamuuu/items/c9f2989241af4a1bf588
node10ランタイムを使えるようにします。
/functions/package.json
"engines": {"node": "8"}
↓
"engines": {"node": "10"}
###2) FunctionのhelloWorldテスト
/functions/index.js内に、helloWorldがコメントアウトされているので、
こちらを有効化します。
ついでに、function名をhelloWorldからnuxtServerに変えておきます。
/functions/index.js
// exports.helloWorld = functions.https.onRequest((request, response) => {
// response.send("Hello from Firebase!");
// });
↓
exports.nuxtServer = functions.https.onRequest((request, response) => {
response.send("Hello from Firebase!");
});
ローカルサーバーで確認してみる。
firebase serve --only functions:nuxtServer
無事、Hello from Firebase!が表示されました。
###3) HostingからFunctionsを呼び出す。
次に、hostingから、functionsを呼ぶようにします。
/firebase.json
"hosting": {
[中略]
"rewrites": [
{
"source": "**/*.*",
"destination": "/404.html"
},
{
"source": "**",
"function": "nuxtServer"
}
]
}
}
※rewritesの上の行の]の後に、「,」を足すのを忘れずに。
拡張子付きのアドレスにアクセスした場合、ファイルがあれば表示。
なければ、notFoundページを表示するようにしました。
それ以外のアドレスは、すべてnuxtServerファンクションを呼ぶようにしてます。
ローカルテスト
firebase serve --only functions:nuxtServer,hosting
http://localhost:5000/hoge
などを開くと、helloWorldが実行されます。
※ただし、ルートに関しては、/public/index.htmlがあるため、そちらの表示が優先されます。
確認後、/publicフォルダの中にあるindex.htmlファイルは、不要なので、削除します。
#(4)functions下にnuxtをインストールする
functions下にnuxtをcliでインストールしようと思います。
ただ、普通にfunctionsフォルダで、
npx create-nuxt-app
を実行すると、package.json等が上書きされてしまうので、
いったん下の階層(nuxt-src)にインストールします。
Visual Studio Codeのターミナルで、下記実行
cd functions
npx create-nuxt-app nuxt-src
? Project name
→ なんでもOK
? Project description
→ なんでもOK
? Author name
→ なんでもOK
? Choose a package manager
→ Npm
? Use a custom UI framework (Use arrow keys)
→ Buefy
? Use a custom server framework (Use arrow keys)
→ none
? Choose Nuxt.js modules (Press <space> to select, <a> to toggle all, <i> to invert selection)
→DotEnvのみ選択
? Choose linting tools (Press <space> to select, <a> to toggle all, <i> to invert selection)
→ ESLint、Prettierを選択
? Use a custom test framework (Use arrow keys)
→ none
? Choose rendering mode (Use arrow keys)
→ Universal
? Choose development tools
→ jsconfig.json
インストール完了後、
cd ./nuxt-src
npm run dev
を実行すると、.nuxtフォルダが生成され、
ローカルサーバーが立ち上がり
で、テストページを確認できました。
ローカルサーバーは、ctrl+cでいったん停止しておきます。
/functions/nuxt-src/.nuxtフォルダもいったん削除。
次にnuxtのルートフォルダを一つ上のfunctionsに移動します。
functions/nuxt-src/package.jsonから
functions/package.jsonに、下記のように表記を移動します。
■scripts
→ そのまま全部追加。
startのみ、ダブるのでもともとあったfunctionsのstartは削除します。
"start": "npm run shell", // → こちらを削除
"start": "nuxt start",
ついでに、npm run serveとnpm run deployで、hostingもサーブ・デプロイするように変更しておきます。
"serve": "firebase serve --only functions",
"deploy": "firebase deploy --only functions",
↓
"serve": "firebase serve --only functions,hosting",
"deploy": "firebase deploy --only functions,hosting",
■dependencies、devDependencies
→ まるごと移動でOK
移動が完了したら、
functions/nuxt-src/内の
・node_modules
・package.json
・package-lock.json
・.git ※あれば
は削除します。
nuxt-srcに残ったファイル(※フォルダはそのまま)を上の階層に移動
.editorconfig
.env
.eslintrc.js
.gitignore(※上書きでOK)
.prettierrc
jsconfig.json
nuxt.config.js
README.md
移動したnuxt.config.jsに、以下追加。
srcDir: 'nuxt-src'
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {}
},
↓
build: {
/*
** You can extend webpack config here
*/
extend(config, ctx) {},
publicPath: '/assets/'
},
上記すべて終わったら、functionsフォルダで
npm install
を実行しておく。
npm run devすると、
WARN No .env file found in …
が出るので、.env関連を修正する。
nuxt用の.envモジュール「@nuxtjs/dotenv」
公式を見ると、
modulesではなく、buildModulesに入れろと書いてあったので、
buildModdulesに移動しつつ、オプションでパスの指定をします。
buildModules: [
....(中略)
// Doc: https://github.com/nuxt-community/dotenv-module
['@nuxtjs/dotenv', { path: __dirname }]
],
#(5)ESlintがらみの設定変更
nuxtをインストールした時点で、
基本的なルールは設定されており、
npm run lint
で、lintチェックを実行できます。
実際に、lintチェックを実行したところ、
\functions\index.js
で、エラーが3つほど出ました。
修正をするにあたり、
まず、functions下に移動した.eslintrc.jsと.prettierrcを
VisualStudioCodeで使えるようにします。
※拡張機能のESLint、Prettierはインストールしておく。
■VisualStudioCodeでESLint拡張機能が動かない気がする時に確認したこと
https://note.kiriukun.com/entry/20190817-eslint-not-working-in-vscode
設定 – eslint.workingDirectories
をワークスペースで定義する。
settings.json
"eslint.workingDirectories": [
"./functions"
]
これでfunctions/index.htmlを開くと、
エラー箇所に赤波線が表示されます。
赤波線にカーソルを合わせて、「クイックフィックス」→fix this pretier/pretier problem
で、自動的に修正されます。
次に、基本ルールですが、
初期設定でconsole.logが使用禁止のため、
このルールを修正します。
functions/.eslintrc.js
rules: {
'no-console': 'off',
上記のルールで、console出力があってもエラー表示をしなくなります。
#(6)function「nuxtServer」で、nuxtをよびだしレンダリングする。
/functions/index.js
を、下記のように変更
コンフィグ内、@nuxtjs/eslint-moduleは残していると、デプロイ後に
Error: could not handle the request
が、発生する。
(ログを見ると、FATAL Cannot find module ‘@nuxtjs/eslint-module’と表示される)
なので、コンフィグを読み込んだ後に、@nuxtjs/eslint-moduleを除外する。
また、index.jsでrequireを使ってnuxt.config.jsを読み込むため、
nuxt.config.jsを以下のように修正します。
export default {
↓
module.exports = {
この時点で、npm run lint で、チェックすると、
1:1 error Unexpected module.exports, please use export default instead nuxt/no-cjs-in-config
が、出る。
CommonJSのrequireを使うなというエラー。
ルールから除外する。
/functions/.eslintrc.js
のrulesに、下記追加
'nuxt/no-cjs-in-config': 'off',
エラーが出なくなった。
nuxtをビルドする
npm run build
ローカルでfirebase サーバーを確認してみる
npm run serve
デプロイしてみる
npm run deploy
→見える(ただしエラーあり。)
/assetsにクライアントスクリプトを探しに行ってしまうので、
.nuxt/dist/clientの中身を/public/assetsにコピー。
これで、エラーが出なくなります。
npm buildしたときに自動的に.nuxt/dist/clientのなかみを
/public/assetsにコピーするようにする
npm install --save-dev cpx rimraf
下記ファイルを修正
/functions/package.json
"scripts": {
"postbuild": "npm run remove-assets && npm run copy-assets",
"remove-assets": "rimraf ../public/assets",
"copy-assets": "cpx ./.nuxt/dist/client/** ../public/assets",
これで npm run buildを実行すると、
/public/assets
内が、自動的に更新される。
/public/assetsは、git対象外にするので、.gitignoreに
public/assets
を追加します。
#(7)nuxtを修正する。
必要パッケージを入れる
npm install dayjs firebase htmlspecialchars vuexfire
.envの設定
デフォルトの設定では、サーバーサイドでしか読み取れない。
下記の対応をすることで、クライアントサイドでも読み取れるようになる。
/functions/nuxt.config.js
先頭に以下追加
require('dotenv').config()
Nuxtの修正内容は、以下のコミット履歴から確認できます。
だいぶ投稿が長くなってしまったので、Nuxtの詳細については割愛します。
リポジトリをクローンして、.env.sampleから.envファイルを作って、
npm run devすれば、コンソールで処理の流れが終えるようにしているので、
見ていただければと思います。