minttown_pf_community v1.0.6
Fullstack Authentication Example with Next.js and NextAuth.js
This is the starter project for the fullstack tutorial with Next.js and Prisma. You can find the final version of this project in the final
branch of this repo.
Prisma command
- init
npx prisma generate
SQL 文章の生成と Typescript で使用できる ORM のキャッシュを生成する
minttown_pf_infra/local
で docker compose を落として、
(docker compose up
を再度実行すると npx prisma generate && npx prisma migrate dev
が行われる)
- migrate
npx prisma migrate dev
npx prisma generate
で作成したテーブルの変更リクエストを実行し、DB に変更を加える
(docker compose up
を再度実行すると npx prisma generate && npx prisma migrate dev
が行われる)
- init client
npx prisma generate client
- studio(Dashboard)
npx prisma studio
パッケージマネージャについて
このプロジェクトは yarn は使いません。npm を使ってください。
(yarn でも npm でも動くはずですが、lock ファイルは npm で作成しています)
Linter について
ローカル開発では .vscode/settings.json
で ESLint の除外ルールを記載する運用となってますが、Github Actions のフローでも ESLint
を組み込んでおります。もし除外したいルールがあれば、
.vscode/settings.json
eslintrc
の 2 ファイルの修正をそれぞれお願いします。
多言語化のサービスとして Localazy を利用する
基本的なサービス内容
- Localazy
- ja.json や en.json などを CLI 経由で Localazy にアップロードし、翻訳担当者が英語基準で機械翻訳&ネイティブチェックする
- コマンドは
npm run localazy:update
- 上記ダウンロードまで行うため、アップロード単体の場合は
npm run localazy:upload
- コマンドは
- デプロイ前に CLI 経由で de.json や fr.json などをダウンロードする
- コマンドは
npm run localazy:download
- コマンドは
- Localazy を使うための認証情報はプロジェクト直下に
localazy.keys.json
として配置する必要がある - バージョン 2 の Localazy を使うための認証情報はプロジェクト直下に
localazyV2.keys.json
として配置する必要がある- このファイルは git では管理しない。必要な人は管理者からもらって配置すること
実際の運用方法
- 開発中は Localazy を使うが、開発が落ち着いたら各 JSON ファイルを直接変更する運用に切り替える予定
- ja.json と en.json は仕様書に記載があるはずなので、エンジニア側で直接追加する
- この時、置き換え文字
${mg_amount}
なども埋め込んでおく - 作業が進んで言語ファイルのキーが増えたら、Localazy にアップロードすると、増えたキーだけ取り込まれる
- この時、置き換え文字
- アップロードする時は以下のコマンドをコンテナ内で叩く
- 変換先の言語は Localazy 側で設定するので、各言語ファイル名だけ
localazy.json
で指定する。以下のような部分- これを忘れると
zh-Hans-CN.json
のようなファイル名で出力される - 下記を設定すると
cn.json
と出力される
- これを忘れると
"langAliases": {
"zh-Hans-CN": "cn"
},
i18next での多言語化サイト対応について
必要なパッケージライブラリについて
- 本 PJ では
Localazy
で翻訳された json ファイルを元にサイトの多言語化対応を i18next
をベースに行っております。その際に使用するライブラリは以下となっております。- i18next
- i18next-browser-languagedetector
- next-i18next
- react-i18next -> next-i18next を使用するために必要。
言語設定を追加する場合
next.config.js を修正
i18n: { locales: ["en", "ja", "de"], # localesに追加 defaultLocale: "ja", },
next-i18next.config.cjs を修正
module.exports = { i18n: { locales: ["ja", "en", "cn", "es", "fr", "de"], defaultLocale: "ja", }, }
i18n/i18n.ts を修正
import xxCommon from "public/locales/xx/common.json";
を追加して、
const option: InitOptions = { resources: { en: { Common: enCommon, }, }
に言語ファイル設定を追記する。
テンプレートに言語設定を反映させる
- 本 PJ では SSR でレンダリングを行っているため、
getServerSideProps
で context から locale を取得して props でserverSideTranslations
を返す。 serverSideTranslations の locale には
next.config.js
で定義している locales の文言を任意に設定する事も可能。export const getServerSideProps: GetServerSideProps = async (context: GetServerSidePropsContext) => { const affiliateProp: Props = await getAffiliateProps(context.req, context.res, {}) return { props: {...await serverSideTranslations(context.locale), ...affiliateProp} } }
そうすることで、以下のように hooks 経由で locale に応じた翻訳をレンダリング出来る。
const { t } = useTranslation() {t('notify.inapp_notice.accept_mg_content')}
サイト全体の locale を変更したい
以下に公式での例を載せます。(あくまで数あるやり方の一つにすぎないです)
import Link from 'next/link' export default function IndexPage(props) { return ( <Link href="/another" locale="fr"> To /fr/another </Link> ) }
import { useRouter } from 'next/router' export default function IndexPage(props) { const router = useRouter() return ( <div onClick={() => { router.push('/another', '/another', { locale: 'fr' }) }} > to /fr/another </div> ) }
上記どちらのやり方でも、
context.locale
は設定した locale に切り替わってuseTranslation
での翻訳も 変更した locale に切り替わります。
参考 https://nextjs.org/docs/pages/building-your-application/routing/internationalization
V2 App Router での多言語化サイト対応について
- next-intlを導入しています
- URL に言語 Prefix が付与されるようになっているので、
Link
,redirect
,usePathname
,useRouter
,getPathname
を@/i18n/routing
からインポートしてください。 - RSC での翻訳例:
const t = await getTranslations("notify")
- ブラウザ側での翻訳例:
const t = useTranslations("notify")
ビルドできるか確認
docker-compose 環境が立ち上がっている状態で、以下のコマンドで確認できます
/app # npm run dev -- -p 30001
> hello-next@1.0.0 dev
> next -p 30001
- info Loaded env from /app/.env
- ready started server on [::]:30001, url: http://localhost:30001
- event compiled client and server successfully in 247 ms (18 modules)
- wait compiling...
- event compiled client and server successfully in 108 ms (18 modules)
- info Loaded env from /app/.env
- info Loaded env from /app/.env
なお、確認できたら ctrl + c
で終了してください。
ステップ実行(サーバ側)
ローカル環境では num run stepdev
でローカルサーバを立ち上げているので、起動時にステップ実行用の待受ポートが開きます
minttown-community | > minttown_pf_community@1.0.0 stepdev
minttown-community | > NODE_OPTIONS='--inspect' next dev
minttown-community |
minttown-community | Debugger listening on ws://127.0.0.1:9229/3d1f7bea-98eb-4e65-b688-6a7b1972bf0e
minttown-community | For help, see: https://nodejs.org/en/docs/inspector
minttown-community | - info Loaded env from /app/.env
minttown-community | Debugger listening on ws://127.0.0.1:9230/0122e55a-5dbe-4399-8784-ab5513d326bd
minttown-community | For help, see: https://nodejs.org/en/docs/inspector
minttown-community | - info the --inspect option was detected, the Next.js router server should be inspected at port 9230.
minttown-community | - ready started server on [::]:3000, url: http://localhost:3000
minttown-community | - event compiled client and server successfully in 300 ms (18 modules)
minttown-community | - wait compiling...
minttown-community | - info the --inspect option was detected, the Next.js server for app should be inspected at port 9232.
minttown-community | - info the --inspect option was detected, the Next.js server for pages should be inspected at port 9231.
minttown-community | Debugger listening on ws://127.0.0.1:9232/5c64a309-ce85-4630-a502-75fcdb38b9d5
minttown-community | For help, see: https://nodejs.org/en/docs/inspector
minttown-community | Debugger listening on ws://127.0.0.1:9231/5754925b-f669-4aa5-82ad-9f5b74174123
minttown-community | For help, see: https://nodejs.org/en/docs/inspector
minttown-community | - event compiled client and server successfully in 150 ms (18 modules)
minttown-community | - info Loaded env from /app/.env
minttown-community | - info Loaded env from /app/.env
minttown-community | - wait compiling /_error (client and server)...
minttown-community | - wait compiling /cms/ad (client and server)...
このポート番号は、環境によって使われていると別のポート番号に変わりますので、docker-compose up
した直後のログを確認してください
デバッグしたい箇所に合わせて、接続するポート番号を切り替える必要があります
- ポート 3000 は HTTP サーバ(ブラウザ応答用)
- ポート 9229 は不明
- ポート 9230 が
router server
- 用途不明
- ポート 9231 が
server for pages
- pages 下の tsx のコンポーネントや getServerSideProps の中のコードなど
- ブラウザ内で動いているんじゃないの?
- pages/api 下の REST API のコードなど
- pages 下の tsx のコンポーネントや getServerSideProps の中のコードなど
- ポート 9232 が
server for app
- App router を使ったときのコード?
実際に接続するには、VSCode の左メニューから 実行とデバッグ
を選び、 launch.jsonを開く
ボタンを押して接続先設定を開きます。以下のような感じです
{
"type": "node",
"request": "attach",
"name": "Next.js Server",
"skipFiles": [
"<node_internals>/**"
],
"port": 9231,
"resolveSourceMapLocations": [
"${workspaceFolder}/**",
"!**/node_modules/**"
]
}
ここの port
の番号を接続したいポート番号に書き換えて上書き保存してから、Next.js Server
を選択して デバッグ実行
ボタンを押すと、docker-compose を実行しているウインドウに Debugger attached.
と表示されます。
この状態で、止めたい箇所にブレークポイントを仕込んでから、ブラウザまたは REST クライアント(Postman など)からアクセスすると、最初に到達したブレークポイントで止まるはずです。
ステップ実行(クライアント側)
前提として、ここでは Chrome を使ったステップ実行を行います。他のブラウザでも動きそうですが、その場合は launch.json
に設定を足してください
- 止めたい箇所にブレークポイントを仕込む
- VSCode の左メニューから
実行とデバッグ
を選び、Next.js Client
を選択してデバッグ実行
ボタンを押す - デバッグ用の Chrome が立ち上がるので、デバッグしたい画面を開き、ボタンなどを押す
- VSCode 上で最初に到達したブレークポイントで止まるはず
ステップ実行(サーバ及びクライアント側)
サーバ側のデバッグとクライアントのデバッグは同時に実行できます(つまり両方同時にステップ実行できる)
その場合は、Next.js Server
を実行してからNext.js Client
を実行してください
ただし、コードがサーバとブラウザ上のどちらで実行されているのかを、明確に把握できていた方がデバッグしやすいと思うので、どちらか一方だけを使うのがおすすめではあります
マイグレーションについて
マイグレーション用の SQL 生成
ゲーム環境及び本番環境においては、prisma migrate dev
ではなく prisma migrate deploy
コマンドを流す必要があり、
その際には予めローカル環境で prisma migrate dev
を流しておいて prisma/migrations
フォルダ配下に SQL を保存しておく必要があります。
ローカルでの動作確認とリリース(もしくは hotfix 等)で対応する場合で命名規則を設けます。
注意としては、古いマイグレーションは 消さずに
マイグレーションを追加してリビジョンの更新をお願いします。
# ローカルで実行するコマンド
$ npx migrate dev --name {以下の規則に従った命名}
※マイグレーションのフォルダに時刻は自動的に入ってしまうため、不可避対応となります。
- 初回りリースまでのフォルダ名: YYYYMMDDHHMMSS_release_softlaunch
- リリース時のフォルダ名: YYYYMMDDHHMMSSrelease{フェーズ名}
- hotfix 時のフォルダ名: YYYYMMDDHHMMSShotfix{JIRA のチケット番号}
- 緊急で特定の要件対応時のフォルダ名:YYYMMDDHHMMSSfeature{JIRA のチケット番号}
マイグレーション失敗時について
ECS Exec にて bash シェルで Fargate コンテナにアタッチした後、
$ npx prisma migrate resolve --rolled-back Unique
を実行する事になります。その後はエラー原因を詳細調査して再度デプロイする流れとなります。
参考 https://www.prisma.io/docs/orm/prisma-migrate/workflows/patching-and-hotfixing