最初からmicrocms / gatsby / netlifyつかっときゃ良かった
自白
2年前にnuxt.jsでお客様が記事書くWebサイトを構築しました。
そしてSSRで記事編集して公開できるようにしました。
それから1年半してJAMstack(SSG)に手を出したらSSRより圧倒的に早いじゃないですか。。。
作ってから時間がたって、スマホだと遅いサイトだなとつくづく実感しました。
PCだとまだましだけどスマホだと完全に遅い。
お客様にも悪いので既存のSSRからSSGに乗り換える提案をするために調査と実験を繰り返しました。
対象読者
・nuxt.js使っててSSGに移行したい人
・でもサイトの編集機能があるからDBの編集機能にも対応したい人
・firebase functions遅いかなって感じてる人
解説しないこと
・nuxt.jsで編集画面作る方法
・firebaseにデプロイする方法
・gitの使い方
本題
既存のfirebaseの設定にGitHubの設定を追加
firebase init hosting:github
色々聞かれるけどこの記事参考にこたえていけばOKだと思います。
firebase-hosting-merge.yml
, firebase-hosting-pull-request.yml
が作成されるのでnodeのバージョンとnpmをyarnに変えました。
※本番に導入するならテストの設定もしましょう。(ここでは飛ばす)
# This file was auto-generated by the Firebase CLI
# https://github.com/firebase/firebase-tools
name: Deploy to Firebase Hosting on merge
'on':
push:
branches:
- main
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 12 # nodeのバージョンを12にしてます
uses: actions/setup-node@v1
with:
node-version: 12
- run: yarn install && yarn generate # npm → yarnに変えてます
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_PROJECT_X }}'
channelId: live
projectId: project-x
env:
FIREBASE_CLI_PREVIEWS: hostingchannels
このfirebase-hosting-pull-request.yml
をコピーしてfirebase-hosting-manual.yml
を作成します。
firebase-hosting-manual.yml
ではworkflow_dispatchという機能でWeb API経由でデプロイできるようにします。
name: Manually triggered workflow
on:
workflow_dispatch: # workflow_dispatchを設定(引数はいらない)
jobs:
build_and_deploy:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v2
- name: Use Node.js 12
uses: actions/setup-node@v1
with:
node-version: 12
- run: yarn install && yarn generate
- uses: FirebaseExtended/action-hosting-deploy@v0
with:
repoToken: '${{ secrets.GITHUB_TOKEN }}'
firebaseServiceAccount: '${{ secrets.FIREBASE_SERVICE_ACCOUNT_PROJECT_X }}'
channelId: live
projectId: project-x
env:
FIREBASE_CLI_PREVIEWS: hostingchannels
GitHubのmainレポジトリにcommit/pushしてmergeによるfirebaseへのdeployが走ることを確認してください。
うまくいかない場合はfirebase.json
を見直してください。
参考になるかもしれないので私のやつ置いておきます。
{
"rulesFile": "database.rules.json",
"functions": {
"source": "functions",
"predeploy": [
"npm --prefix ./ run build",
"rm -rf functions/nuxt",
"cp -r .nuxt/ functions/nuxt/",
"cp ./nuxt.config.js functions/"
]
},
"hosting": {
"public": "dist",
"rewrites": [
{
"source": "**/admin/**", # admin以下の部分は編集画面なのでSSGしない
"function": "ssrapp"
}
],
"ignore": [
"firebase.json",
"**/.*",
"**/node_modules/**"
]
},
"storage": {
"rules": "storage.rules"
}
}
ここまででCI/CDできましたがお客様がCRUD処理をしてもサイトが更新されなくなりました。
この記事参考にしてworkflow idを取得します。
curl \
-H "Accept: application/vnd.github.v3+json" \
https://api.github.com/repos/{github-user-name}/{repository-name}/actions/workflows
またこの記事参考にしてGithubのpersonal access tokenも準備してください。
で次のコマンドを実行するとgithubのワークフローが走りデプロイされることを確認してください。
curl -XPOST -H "Authorization: token $YOUR_GITHUB_TOKEN" https://api.github.com/repos/{github-user-name}/{repository-name}/actions/workflows/{workflow-id}/dispatches -d '{"ref": "main"}}'
ここまでくればあと一息。
Firebase Functionsに記事作成で起動されるトリガー関数を登録するだけです。
以下の関数をfirebase functionsにデプロイしてください。
const functions = require('firebase-functions')
const axios = require('axios').default
const GITHUB_TOKEN = functions.config().setting.github_token
const GITHUB_WORKFLOW_ID = functions.config().setting.workflow_id
exports.postGithubAction = functions.database.ref('articles/{articleId}')
.onWrite(async (change, context) => {
axios({
url: `https://api.github.com/repos/${github-user-name}/${repository-name}/actions/workflows/${GITHUB_WORKFLOW_ID}/dispatches`,
method: 'POST',
data: {
ref: 'main'
},
headers: {
Authorization: `token ${GITHUB_TOKEN}`
}
})
})
// 以下SSRの関数が続く
記事を更新してGithub Actionが実行されれば成功です!