概要
firebase に nuxt のアプリケーションをデプロイしてサーバーサイドレンダリングの環境を構築する。この手順では、Hosting へのデプロイまでを実施します。firestore へのアクセス等は別の記事で紹介します。
プロジェクトIDは、blockquotor
としています。ここは個別なIDに変更してください。記事の中で blockquotor
となっている部分は適宜読み替えてください(あと、 Macのユーザー名はgosshys
となってますが、ここも個人のものに読み替えてください)
基本的には、1年前の以下の記事の焼き直しになります
nuxt の雛形からプロジェクトを作成する
% yarn create nuxt-app blockquotor
yarn create v1.22.17
[1/4] 🔍 Resolving packages...
[2/4] 🚚 Fetching packages...
[3/4] 🔗 Linking dependencies...
[4/4] 🔨 Building fresh packages...
success Installed "create-nuxt-app@4.0.0" with binaries:
- create-nuxt-app
[############################################################################################################################################################################] 342/342
create-nuxt-app v4.0.0
✨ Generating Nuxt.js project in blockquotor
? Project name: blockquotor
? Programming language: TypeScript
? Package manager: Yarn
? UI framework: Vuetify.js
? Nuxt.js modules: Axios - Promise based HTTP client
? Linting tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? Testing framework: None
? Rendering mode: Universal (SSR / SSG)
? Deployment target: Server (Node.js hosting)
? Development tools: (Press <space> to select, <a> to toggle all, <i> to invert selection)
? What is your GitHub username? gosshys
? Version control system: Git
🎉 Successfully created project blockquotor
To get started:
cd blockquotor
yarn dev
To build & start for production:
cd blockquotor
yarn build
yarn start
For TypeScript users.
See : https://typescript.nuxtjs.org/cookbook/components/
✨ Done in 264.92s.
できたディレクトリに移動してローカル環境で起動する
cd blockquotor
yarn dev
http://localhost:3000 にアクセスして下の画面が見れればOK
firebase の初期化
% firebase init
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
You're about to initialize a Firebase project in this directory:
/Users/gosshys/IdeaProjects/blockquotor
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. Firestore: Configure security rules and indexes
files for Firestore, Functions: Configure a Cloud Functions directory and its files, Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys, Stor
age: Configure a security rules file for Cloud Storage
=== 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.
? Please select an option: Create a new project
i If you want to create a project in a Google Cloud organization or folder, please use "firebase projects:create" instead, and return to this command when you've created the project.
? Please specify a unique project id (warning: cannot be modified afterward) [6-30 characters]:
blockquotor
? What would you like to call your project? (defaults to your project ID)
✔ Creating Google Cloud Platform project
✔ Adding Firebase resources to Google Cloud Platform project
🎉🎉🎉 Your Firebase project is ready! 🎉🎉🎉
Project information:
- Project ID: blockquotor
- Project Name: blockquotor
Firebase console is available at
https://console.firebase.google.com/project/blockquotor/overview
i Using project blockquotor (blockquotor)
=== Firestore Setup
Error: It looks like you haven't used Cloud Firestore in this project before. Go to https://console.firebase.google.com/project/blockquotor/firestore to create your Cloud Firestore database.
Error: It looks like you haven't used Cloud Firestore in this project before. Go to https://console.firebase.google.com/project/blockquotor/firestore to create your Cloud Firestore database.
「Firestoreがないからコンソールから作成してくれ」というエラーがでるので、エラーメッセージ中のリンクからfirebaseのコンソールを開く
https://console.firebase.google.com/project/blockquotor/firestore
この画面が表示されるはずなので、白い「データベースの作成」ボタンを押す
本番環境モードとテストモードのどちらかを選んで、「次へ」を押す。認証なしで firesotre にアクセス(主にレコードの追加と更新)したい人はテストモードを選ぶ(30日以内に本番環境モードに変えればいい)
Cloud Firestore のロケーションは、nuxt の SSR でバリバリデータ参照するなら、us-central で良いと思う。 SSR(HTTP 関数を使用して Firebase Hosting の動的コンテンツを提供する場合) が us-central1 しか利用できないので、firestore も近くのロケーションを選ばざるを得ないという考え。ロケーションを選択したら、青い「有効にする」ボタンを押す。
Cloud Functions のロケーション | Firebase Documentation
データベースができた画面が表示された準備完了
もう一度、 firebase init
コマンドを実行する
=== Hosting Setup の部分で、? Configure as a single-page app (rewrite all urls to /index.html)?
を No
としているにも係わらず、static/index.html が上書きされてしまいました(自分の理解が追いついていないだけかも)
✔ Wrote static/404.html
✔ Wrote static/index.html
なので、コマンド実行後に index.html を削除してください(404.htmlはあっても害はない)
rm -f static/index.html
参考
% firebase init
######## #### ######## ######## ######## ### ###### ########
## ## ## ## ## ## ## ## ## ## ##
###### ## ######## ###### ######## ######### ###### ######
## ## ## ## ## ## ## ## ## ## ##
## #### ## ## ######## ######## ## ## ###### ########
You're about to initialize a Firebase project in this directory:
/Users/gosshys/IdeaProjects/blockquotor
? Which Firebase features do you want to set up for this directory? Press Space to select features, then Enter to confirm your choices. Firestore: Configure security rules and indexes
files for Firestore, Functions: Configure a Cloud Functions directory and its files, Hosting: Configure files for Firebase Hosting and (optionally) set up GitHub Action deploys, Stor
age: Configure a security rules file for Cloud Storage
=== 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.
? Please select an option: Use an existing project
? Select a default Firebase project for this directory: blockquotor (blockquotor)
i Using project blockquotor (blockquotor)
=== Firestore Setup
Firestore Security Rules allow you to define how and when to allow
requests. You can keep these rules in your project directory
and publish them with firebase deploy.
? What file should be used for Firestore Rules? firestore.rules
Firestore indexes allow you to perform complex queries while
maintaining performance that scales with the size of the result
set. You can keep index definitions in your project directory
and publish them with firebase deploy.
? What file should be used for Firestore indexes? firestore.indexes.json
=== Functions Setup
A functions directory will be created in your project with sample code
pre-configured. Functions can be deployed with firebase deploy.
? What language would you like to use to write Cloud Functions? TypeScript
? Do you want to use ESLint to catch probable bugs and enforce style? No
✔ Wrote functions/package.json
✔ Wrote functions/tsconfig.json
✔ Wrote functions/src/index.ts
✔ Wrote functions/.gitignore
? Do you want to install dependencies with npm now? Yes
added 235 packages, and audited 236 packages in 16s
11 packages are looking for funding
run `npm fund` for details
2 low severity vulnerabilities
To address all issues (including breaking changes), run:
npm audit fix --force
Run `npm audit` for details.
=== 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? static
? Configure as a single-page app (rewrite all urls to /index.html)? No
? Set up automatic builds and deploys with GitHub? No
✔ Wrote static/404.html
✔ Wrote static/index.html
=== Storage Setup
Firebase Storage Security Rules allow you to define how and when to allow
uploads and downloads. You can keep these rules in your project directory
and publish them with firebase deploy.
? What file should be used for Storage Rules? storage.rules
✔ Wrote storage.rules
i Writing configuration info to firebase.json...
i Writing project information to .firebaserc...
✔ Firebase initialization complete!
めでたく初期化できたら、今度は firebase.json を編集する
% vi firebase.json
functions.source の箇所を追加(上の行にカンマが増えているところも注意)- hosting.rewrites の箇所を追加(上の行にカンマが増えているところも注意)
% cat firebase.json
{
"firestore": {
"rules": "firestore.rules",
"indexes": "firestore.indexes.json"
},
"functions": {
"predeploy": "npm --prefix \"$RESOURCE_DIR\" run build"
},
"hosting": {
"public": "static",
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
],
"rewrites": [
{
"source": "**",
"function": "ssr"
}
]
},
"storage": {
"rules": "storage.rules"
}
}
functions の設定
functions のディレクトリに移動する
cd functions
ルートの package.json の dependencies と揃えるために cat などで確認する
cat ../package.json
ルートの dependencies を functions の dependencies に設定する
vi package.json
こんな感じになるはず。dependenciesの @nuxtjs/axios
以下を追記しました(上の行にカンマが増えているところも注意)
% cat package.json
{
"name": "functions",
"scripts": {
"build": "tsc",
"serve": "npm run build && firebase emulators:start --only functions",
"shell": "npm run build && firebase functions:shell",
"start": "npm run shell",
"deploy": "firebase deploy --only functions",
"logs": "firebase functions:log"
},
"engines": {
"node": "16"
},
"main": "lib/index.js",
"dependencies": {
"firebase-admin": "^9.8.0",
"firebase-functions": "^3.14.1",
"@nuxtjs/axios": "^5.13.6",
"core-js": "^3.19.3",
"nuxt": "^2.15.8",
"vue": "^2.6.14",
"vue-server-renderer": "^2.6.14",
"vue-template-compiler": "^2.6.14",
"vuetify": "^2.6.1",
"webpack": "^4.46.0"
},
"devDependencies": {
"typescript": "^3.8.0",
"firebase-functions-test": "^0.2.0"
},
"private": true
}
yarn install
で package.json の内容を反映させる
% yarn install
yarn install v1.22.17
info No lockfile found.
warning package-lock.json found. Your project contains lock files generated by tools other than Yarn. It is advised not to mix package managers in order to avoid resolution inconsistencies caused by unsynchronized lock files. To clear this warning, remove package-lock.json.
[1/5] 🔍 Validating package.json...
[2/5] 🔍 Resolving packages...
warning nuxt > @nuxt/babel-preset-app > core-js@2.6.12: core-js@<3.4 is no longer maintained and not recommended for usage due to the number of issues. Because of the V8 engine whims, feature detection in old core-js versions could cause a slowdown up to 100x even if nothing is polyfilled. Please, upgrade your dependencies to the actual version of core-js.
warning nuxt > @nuxt/webpack > webpack-hot-middleware > querystring@0.2.1: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
warning nuxt > @nuxt/webpack > webpack > node-libs-browser > url > querystring@0.2.0: The querystring API is considered Legacy. new code should use the URLSearchParams API instead.
warning nuxt > @nuxt/webpack > webpack > watchpack > watchpack-chokidar2 > chokidar@2.1.8: Chokidar 2 does not receive security updates since 2019. Upgrade to chokidar 3 with 15x fewer dependencies
warning nuxt > @nuxt/webpack > webpack > watchpack > watchpack-chokidar2 > chokidar > fsevents@1.2.13: fsevents 1 will break on node v14+ and could be using insecure binaries. Upgrade to fsevents 2.
warning nuxt > @nuxt/webpack > webpack > micromatch > snapdragon > source-map-resolve@0.5.3: See https://github.com/lydell/source-map-resolve#deprecated
warning nuxt > @nuxt/webpack > cssnano > cssnano-preset-default > postcss-svgo > svgo@1.3.2: This SVGO version is no longer supported. Upgrade to v2.x.x.
warning nuxt > @nuxt/webpack > postcss-preset-env > postcss-color-gray > postcss-values-parser > flatten@1.0.3: flatten is deprecated in favor of utility frameworks such as lodash.
warning nuxt > @nuxt/webpack > webpack > micromatch > snapdragon > source-map-resolve > resolve-url@0.2.1: https://github.com/lydell/resolve-url#deprecated
warning nuxt > @nuxt/webpack > webpack > micromatch > snapdragon > source-map-resolve > source-map-url@0.4.1: See https://github.com/lydell/source-map-url#deprecated
warning nuxt > @nuxt/webpack > webpack > micromatch > snapdragon > source-map-resolve > urix@0.1.0: Please see https://github.com/lydell/urix#deprecated
[3/5] 🚚 Fetching packages...
[4/5] 🔗 Linking dependencies...
warning "firebase-admin > @firebase/database-compat@0.1.5" has unmet peer dependency "@firebase/app-compat@0.x".
warning "firebase-admin > @firebase/database-compat > @firebase/database > @firebase/auth-interop-types@0.1.6" has unmet peer dependency "@firebase/app-types@0.x".
warning "nuxt > @nuxt/components@2.2.1" has unmet peer dependency "consola@*".
[5/5] 🔨 Building fresh packages...
success Saved lockfile.
✨ Done in 67.55s.
ssr に理由する関数を作成する
vi src/index.ts
こんな感じの関数を作る(loggerはデバッグ用なので任意、コメントアウト部分も消してもよい)
% cat src/index.ts
import * as functions from "firebase-functions";
// // Start writing Firebase Functions
// // https://firebase.google.com/docs/functions/typescript
//
// export const helloWorld = functions.https.onRequest((request, response) => {
// functions.logger.info("Hello logs!", {structuredData: true});
// response.send("Hello from Firebase!");
// });
const { Nuxt } = require('nuxt')
const nuxt = new Nuxt({
buildDir: 'ssr',
dev: false
})
export const ssr = functions
.runWith({minInstances: 1})
.https.onRequest(async (req, res) => {
functions.logger.info("ssr-req:", req)
functions.logger.info("ssr-res:", res)
await nuxt.ready()
return nuxt.render(req, res)
})
ルートに戻る
cd ..
package.json の設定でビルド時に functions もビルドされるようにする
ルートディレクトリの package.json を編集することに注意
vi package.json
- scripts.build を
"nuxt build && npm run build:copy:ssr"
に変更 - scripts.build:copy:ssr を追加
{
"name": "blockquotor",
"version": "1.0.0",
"private": true,
"scripts": {
"dev": "nuxt",
"build": "nuxt build && npm run build:copy:ssr",
"build:copy:ssr": "rimraf functions/ssr && mkdirp functions/ssr && cp -R .nuxt/dist functions/ssr/dist",
"start": "nuxt start",
"generate": "nuxt generate"
},
"dependencies": {
"@nuxtjs/axios": "^5.13.6",
"core-js": "^3.19.3",
"nuxt": "^2.15.8",
"vue": "^2.6.14",
"vue-server-renderer": "^2.6.14",
"vue-template-compiler": "^2.6.14",
"vuetify": "^2.6.1",
"webpack": "^4.46.0"
},
"devDependencies": {
"@nuxt/types": "^2.15.8",
"@nuxt/typescript-build": "^2.1.0",
"@nuxtjs/vuetify": "^1.12.3"
}
}
firebase にデプロイする
yarn build && firebase deploy
初回のデプロイは、プランを Blaze にする必要があるので、警告が出て失敗する
Error: Your project blockquotor must be on the Blaze (pay-as-you-go) plan to complete this command. Required API cloudbuild.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
https://console.firebase.google.com/project/blockquotor/usage/details
↑ blockquotor の部分は、あなたのプロジェクトIDになるので注意してください
gosshys@gosshysnoMacBook-Air blockquotor % yarn build && firebase deploy
yarn run v1.22.17
$ nuxt build && npm run build:copy:ssr
ℹ Production build 08:12:33
ℹ Bundling for server and client side 08:12:33
ℹ Target: server 08:12:33
ℹ Using components loader to optimize imports 08:12:33
ℹ Discovered Components: .nuxt/components/readme.md 08:12:33
✔ Builder initialized 08:12:33
✔ Nuxt files generated 08:12:33
✔ Client
Compiled successfully in 7.70s
✔ Server
Compiled successfully in 2.48s
Hash: de358a0f165a6bd9581e
Version: webpack 4.46.0
Time: 7701ms
Built at: 2022/02/26 8:12:41
Asset Size Chunks Chunk Names
../server/client.manifest.json 17.6 KiB [emitted]
0d5c6f2.js 6.63 KiB 4 [emitted] [immutable] components/tutorial
1472b70.js 221 KiB 2 [emitted] [immutable] commons/app
24f46d8.js 948 bytes 5 [emitted] [immutable] components/vuetify-logo
56bed71.js 22.3 KiB 6, 3, 5 [emitted] [immutable] pages/index
6bc5b11.js 1.85 KiB 3 [emitted] [immutable] components/nuxt-logo
76a844e.js 484 KiB 9 [emitted] [immutable] [big] vendors/app
922f6d5.js 51.3 KiB 1 [emitted] [immutable] app
LICENSES 407 bytes [emitted]
c1007c5.js 666 bytes 7 [emitted] [immutable] pages/inspire
c2754aa.js 12.5 KiB 0 [emitted] [immutable] vendors/pages/index/pages/inspire
c4ff53b.js 2.35 KiB 8 [emitted] [immutable] runtime
+ 2 hidden assets
Entrypoint app = c4ff53b.js 1472b70.js 76a844e.js 922f6d5.js
WARNING in asset size limit: The following asset(s) exceed the recommended size limit (244 KiB).
This can impact web performance.
Assets:
76a844e.js (484 KiB)
Hash: 67dc7148f3fd15866680
Version: webpack 4.46.0
Time: 2481ms
Built at: 2022/02/26 8:12:44
Asset Size Chunks Chunk Names
components/nuxt-logo.js 5.9 KiB 1 [emitted] components/nuxt-logo
components/tutorial.js 7.82 KiB 2 [emitted] components/tutorial
components/vuetify-logo.js 4.99 KiB 3 [emitted] components/vuetify-logo
pages/index.js 55 KiB 4, 1, 3 [emitted] pages/index
pages/inspire.js 19.3 KiB 5 [emitted] pages/inspire
server.js 669 KiB 0 [emitted] app
server.manifest.json 667 bytes [emitted]
+ 6 hidden assets
Entrypoint app = server.js server.js.map
ℹ Ready to run nuxt start 08:12:44
> blockquotor@1.0.0 build:copy:ssr
> rimraf functions/ssr && mkdirp functions/ssr && cp -R .nuxt/dist functions/ssr/dist
✨ Done in 13.46s.
=== Deploying to 'blockquotor'...
i deploying storage, firestore, functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run build
> build
> tsc
✔ functions: Finished running predeploy script.
i firebase.storage: checking storage.rules for compilation errors...
✔ firebase.storage: rules file storage.rules compiled successfully
i firestore: reading indexes from firestore.indexes.json...
i cloud.firestore: checking firestore.rules for compilation errors...
✔ cloud.firestore: rules file firestore.rules compiled successfully
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
⚠ functions: missing required API cloudbuild.googleapis.com. Enabling now...
✔ functions: required API cloudfunctions.googleapis.com is enabled
Error: Your project blockquotor must be on the Blaze (pay-as-you-go) plan to complete this command. Required API cloudbuild.googleapis.com can't be enabled until the upgrade is complete. To upgrade, visit the following URL:
https://console.firebase.google.com/project/blockquotor/usage/details
functions 利用には、firebase のプランを変更する必要があるため、
以下のURL(blockquotor の部分はあなたのプロジェクトIDなので変更する)にアクセスして、プランを Blaze に変更する
https://console.firebase.google.com/project/blockquotor/usage/details
Spark と表示されているので、「プランを変更」ボタンを押す
Blaze の下の青い「プランを選択」ボタンを押す
請求先アカウントをプルダウンから選択。アカウントを登録していない場合は、登録して青い「続行」ボタンを押す
課金予算を設定する。100円でも良さそうだが1000円にした。青い「続行」ボタンを押す
プランの内容を確認して、青い「購入」ボタンを押す
アップグレード完了が表示されればOK
firebase にデプロイする(2回目)
再度、firebase のデプロイを実行する。今度は、yarn build
はなくてもOK
firebase deploy
途中で以下の警告がでるけど、迷わずY
(Yes)を選択する。functions が最小インスタンスを維持するため、月$0.62(約70円)かかる計算になります。通常であれば無料枠にはいるのかしら...詳しくは調べていません。
⚠ functions: The following functions have reserved minimum instances. This will reduce the frequency of cold starts but increases the minimum cost. You will be charged for the memory allocation and a fraction of the CPU allocation of instances while they are idle.
ssr(us-central1): 1 instances, 256MB of memory each
With these options, your minimum bill will be $0.62 in a 30-day month
? Would you like to proceed with deployment? Yes
% firebase deploy
=== Deploying to 'blockquotor'...
i deploying storage, firestore, functions, hosting
Running command: npm --prefix "$RESOURCE_DIR" run build
> build
> tsc
✔ functions: Finished running predeploy script.
i firebase.storage: checking storage.rules for compilation errors...
✔ firebase.storage: rules file storage.rules compiled successfully
i firestore: reading indexes from firestore.indexes.json...
i cloud.firestore: checking firestore.rules for compilation errors...
✔ cloud.firestore: rules file firestore.rules compiled successfully
i functions: ensuring required API cloudfunctions.googleapis.com is enabled...
i functions: ensuring required API cloudbuild.googleapis.com is enabled...
⚠ functions: missing required API cloudbuild.googleapis.com. Enabling now...
✔ functions: required API cloudfunctions.googleapis.com is enabled
✔ functions: required API cloudbuild.googleapis.com is enabled
i functions: preparing functions directory for uploading...
i functions: packaged functions (797.59 KB) for uploading
⚠ functions: The following functions have reserved minimum instances. This will reduce the frequency of cold starts but increases the minimum cost. You will be charged for the memory allocation and a fraction of the CPU allocation of instances while they are idle.
ssr(us-central1): 1 instances, 256MB of memory each
With these options, your minimum bill will be $0.62 in a 30-day month
? Would you like to proceed with deployment? Yes
i storage: uploading rules storage.rules...
i firestore: latest version of firestore.rules already up to date, skipping upload...
✔ firestore: deployed indexes in firestore.indexes.json successfully
✔ functions: functions folder uploaded successfully
i hosting[blockquotor]: beginning deploy...
i hosting[blockquotor]: found 5 files in static
✔ hosting[blockquotor]: file upload complete
✔ storage: released rules storage.rules to firebase.storage
✔ firestore: released rules firestore.rules to cloud.firestore
i functions: creating Node.js 16 function ssr(us-central1)...
✔ functions[ssr(us-central1)] Successful create operation.
Function URL (ssr(us-central1)): https://us-central1-blockquotor.cloudfunctions.net/ssr
i functions: cleaning up build files...
i hosting[blockquotor]: finalizing version...
✔ hosting[blockquotor]: version finalized
i hosting[blockquotor]: releasing new version...
✔ hosting[blockquotor]: release complete
✔ Deploy complete!
Project Console: https://console.firebase.google.com/project/blockquotor/overview
Hosting URL: https://blockquotor.web.app
デプロイされたアプリケーション(blockquotor の部分はあなたのプロジェクトIDなので変更する)にアクセスして起動を確認する
以下のページが表示されればOK
上手く行っていれば、functions のコンソールログで以下のようなログが確認できるはずです。
以下のエラーが表示されるようであれば、権限の設定の問題かもしれません。以下のページを参考に権限を設定する
Your client does not have permission to get URL /ssr/ from this server.
https://qiita.com/toshiaki_takase/items/ce65cd5582a80917b52f