1.0.6 • Published 5 months ago

minttown_pf_community v1.0.6

Weekly downloads
-
License
UNLICENSED
Repository
-
Last release
5 months ago

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 のコードなど
  • ポート 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 に設定を足してください

  1. 止めたい箇所にブレークポイントを仕込む
  2. VSCode の左メニューから 実行とデバッグ を選び、Next.js Clientを選択して デバッグ実行ボタンを押す
  3. デバッグ用の Chrome が立ち上がるので、デバッグしたい画面を開き、ボタンなどを押す
  4. 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 {以下の規則に従った命名}

※マイグレーションのフォルダに時刻は自動的に入ってしまうため、不可避対応となります。

  1. 初回りリースまでのフォルダ名: YYYYMMDDHHMMSS_release_softlaunch
  2. リリース時のフォルダ名: YYYYMMDDHHMMSSrelease{フェーズ名}
  3. hotfix 時のフォルダ名: YYYYMMDDHHMMSShotfix{JIRA のチケット番号}
  4. 緊急で特定の要件対応時のフォルダ名: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

@apollo/client@aws-sdk/client-cloudfront@aws-sdk/client-cognito-identity-provider@aws-sdk/client-s3@aws-sdk/client-ses@aws-sdk/s3-request-presigner@chakra-ui/icons@chakra-ui/next-js@chakra-ui/react@cmdotcom/text-sdk@datadog/browser-rum@emotion/react@emotion/styled@fontsource/noto-sans@fontsource/noto-sans-jp@localazy/cli@next-auth/prisma-adapter@next/third-parties@prisma/client@radix-ui/react-accordion@radix-ui/react-avatar@radix-ui/react-checkbox@radix-ui/react-collapsible@radix-ui/react-dialog@radix-ui/react-icons@radix-ui/react-label@radix-ui/react-popover@radix-ui/react-progress@radix-ui/react-scroll-area@radix-ui/react-select@radix-ui/react-separator@radix-ui/react-slot@radix-ui/react-switch@radix-ui/react-tabs@radix-ui/react-toast@radix-ui/react-tooltip@react-spring/web@splidejs/react-splide@swc/core@swc/jest@tanstack/react-table@types/speakeasy@veriff/incontext-sdk@veriff/js-sdkajvajv-formatsasync-mutexaws-amplifyaws-sdkaxioschakra-react-selectchart.jsclass-variance-authorityclsxcookiecountry-list-jscryptocsv-parsercuiddayjsdd-tracedecimal.jsdeep-diffeslintfirebase-adminflag-iconsframer-motiongraphqlheic2anyhtml-react-parserhttpsi18nexti18next-browser-languagedetectorioredisjsonwebtokenjwks-rsajwt-decodelibphonenumber-jslodash.getlodash.mergelodash.picklodash.setlucide-reactmdurlnextnext-authnext-i18nextnext-intlnodemailerpatch-packagepostcssprismaprisma-extension-randompuppeteerpuppeteer-extrapuppeteer-extra-plugin-stealthreactreact-beautiful-dndreact-chartjs-2react-cropperreact-custom-roulettereact-domreact-i18nextreact-iconsreact-intersection-observerreact-markdownreact-rewardsreact-textarea-autosizerequest-ipseedrandomshadcn-uisharpspeakeasystreamswiperswrtailwind-mergetailwindcsstailwindcss-animatetsxtypescriptulidunist-builderweb-vitalszod
1.0.6

5 months ago

1.0.5

5 months ago

1.0.4

5 months ago

1.0.3

5 months ago

1.0.2

5 months ago

1.0.1

5 months ago

1.0.0

5 months ago