Next.js_1 (graphQL + ApoloClient + Heroku 基礎構築編)

■Next.js 公式事例

https://nextjs.org/examples

■0.Hasuraで必要なgraphQLAPIの作成

https://cloud.hasura.io/

にアクセスすると、GoogleGitHubのアカウントを聞かれる。(本プロジェクトはGithubのアカウントを使用)。

  1. 「New Project」をクリック。
  2. 「Create Project」に入るので、ここでは「Free Tier」が選択されたままで、そのほかはいじらずに、Create Free Projectを選択
  3. プロジェクトが自動生成され、基本情報の画面に遷移する。「Name」で、わかるように名前を変更。

    ここでは「ap-plat-project1」とした。

  4. 「Env vars」タブを確認。以下のようにADMIN_SECRETが自動生成されてしまっている場合は、「ADMIN_SECRET」をクリックして、ゴミ箱に捨てる。

  1. 画面右上の「Launch Console」をクリック。
  2. 以下のようなGUI画面に入る。

  1. Data」タブをクリック
  2. 「Connect Existing Database」ということで、今回はHerokuを使っていく。

    隣のタブの「Create Heroku Database( Freee )」をクリック。

  3. 「Heroku」のアイコンをクリック。

  1. すると、Herokuに自動的に連携してくれる(ただし

    、使用しているPCからHerokuにデプロイしていて、情報がある状態の場合)。

  2. 連携が成功したら、以下の画面に移る。

  1. テーブルの名前を決める。

    Columsに必要なフィールドを決めていく。以下、設定したフィールド。

  1. Primary Keyで「id」を選択し、「Add Table」でテーブルを生成する。
  2. 作成できたら、「Insert Row」に移動。こちらが、実際にデータを追加する箇所になる。

  1. 「Browse Rows」タブには、Insert Row で入力したデータが入っている。
  2. グラフQLのAPIを確認する。「API」のナビをクリック。

  1. そうすると、作成したテーブルに対する、コマンドが自動生成してくれる。以下のように。

  1. 「limit」は「何件取得するか?」という意味。
  2. 「offset」は「どこから開始するか? ?」という意味。
  3. 「order_by」は「並べ替え」。asc:昇順、desc:降順
  4. 続きは~セクション2:Hasura Cloud 4.Hasura Cloud:create table(9:36)~から

■1. Nextjs Project 新規作成

1-1. yarn install *インストールしていない場合

npm install --global yarn
yarn --version

1-2. create-next-app

npx create-next-app .

※npm同様、プロジェクトをコピーするときは「yarn install」でできるようだ。

1-3. Apollo Client + heroicons + cross-fetch のインストール

yarn add @apollo/client graphql @apollo/react-hooks cross-fetch @heroicons/react

1-4. React-Testing-Library + MSW + next-page-tester のインストール

yarn add -D msw@0.35.0 next-page-tester jest @testing-library/react @types/jest @testing-library/jest-dom @testing-library/dom babel-jest @babel/core @testing-library/user-event jest-css-modules

1-5. Project folder 直下に".babelrc"ファイルを作成して下記設定を追加

touch .babelrc (macのターミナル)
New-Item .babelrc (Windowsのシェルスクリプト)

Next.jsを使いますと、というプリセットを、.babelrcに追記

 {
     "presets": ["next/babel"]
 }

(現段階までのディレクトリの様子)

1-6. package.json に jest の設定を追記

(テストの対象外のものを追記。cssはモックするようにしておく)

    "jest": {
        "testPathIgnorePatterns": [
            "<rootDir>/.next/",
            "<rootDir>/node_modules/"
        ],
        "moduleNameMapper": {
            "\\.(css)$": "<rootDir>/node_modules/jest-css-modules"
        }
    }

1-7. package.jsonに test scriptを追記

 "scripts": {
        ...
        "test": "jest --env=jsdom --verbose"
    },

1-8. prettierの設定 : settingsでRequire Config + Format On Saveにチェック

touch .prettierrc(macのターミナル)
New-Item .prettierrc(Windowsのシェルスクリプト)

次に、prittierの設定ファイルに以下追記。

シングルクオートに出来るものは自動的に変換、不要なセミコロンを削除

    {
        "singleQuote": true,
        "semi": false
    }

(できるだけシングルクオートにした)

■2. TypeScript の導入

https://nextjs.org/learn/excel/typescript/create-tsconfig

2-1. 空のtsconfig.json作成

    touch tsconfig.json(macのターミナル)
    New-Item tsconfig.json(Windowsのシェルスクリプト)

2-2. 必要moduleのインストール

yarn add -D typescript @types/react @types/node

2-3. 開発server起動

yarn dev

そうすると、tsconfig.json に初期設定が自動的に反映される。

2-4.  「pages」ディレクトリの、_app.jsと index.jsを -> tsx へ拡張子変更

2-5. _app.jsを、AppProps型に編集

import { AppProps } from 'next/app'

function MyApp({ Component, pageProps }: AppProps) {
    return <Component {...pageProps} />
}
export default MyApp

■3. Tailwind CSS の導入

https://tailwindcss.com/docs/guides/nextjs

3-1. 必要moduleのインストール

yarn add tailwindcss@latest postcss@latest autoprefixer@latest

3-2. tailwind.config.js, postcss.config.jsの生成

npx tailwindcss init -p

3-3. tailwind.config.jsのpurge設定編集

tailwind.cssの適用範囲を意味する。

module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [],
}

3-4. ルートディレクトリに、componentsフォルダを作成

mkdir components

3-5. globals.cssの編集

@tailwind base;
@tailwind components;
@tailwind utilities;

■4.Test動作確認

4-1. testsフォルダ作成

mkdir __test__

test ディレクトリに移動し、Home.test.tsxファイルの作成

cd __test__

touch Home.test.tsx(macのターミナル)
New-Item Home.test.tsx(Windowsのシェルスクリプト)

Home.test.tsxファイルへ動作確認用の以下のコードをペースト

import { render, screen } from '@testing-library/react'
import '@testing-library/jest-dom/extend-expect'
import Home from '../pages/index'
it('Should render title text', () => {
  render(<Home />)
  expect(screen.getByText('Next.js!')).toBeInTheDocument()
})

4-2. yarn test -> テストがPASSするか確認

yarn test

Ran all test suites.でテスト合格

■5. GraphQL codegen

QraphQLのデータ型を自動生成する「codegen」を利用する。

5-1. install modules + init

yarn add -D @graphql-codegen/cli
yarn graphql-codegen init

yarn graphql-codegen init を実行すると、いくつか質問される。

1問目が以下。

「Application built with React」のままenter。

次に

と、GraphQLサーバーのURLを質問されるので、Hasuraで作成したGraphql エンドポイントを持ってくる。

今回のテストプロジェクトの場合は

https://closing-chamois-44.hasura.app/v1/graphql

次に、「Where are your operations ~」で、codegenはプロジェクトの中に定義されているクエリの内容を読みにいって、自動的に解析していくが、そのクエリがプロジェクトのどの階層に定義されているかをここで指定する必要あり。

今回は、ルートディレクトリに「queries」というディレクトリを後程作成して、その中に.tsで、カスタムのクエリを定義していく。よって、サブフォルダを含めたこのディレクトリ直下に存在する全ての.tsファイルから探しにいくように定義する。

今回のテストプロジェクトの場合は

queries/*/.ts

次に「Pick Plugins」というのがあるが、こちらはデフォルトの3つが選択されている状態でenter

次に「Where to write the output」で、自動生成したタイプ(型)の定義のファイルを、プロジェクトのどこの階層に定義しますか? という質問をされている。

今回のテストプロジェクトの場合は

types/generated/graphql.tsx

次に「インストロスペクション ファイル」を作りますか? と質問されているが、これはNo。

次に「コンフィグ ファイルの名前は?」と質問されているので、このデフォルトの名前でenter。

次に、「スクリプトを実行するときの、スクリプトの名前はどうするか?」と質問されているが、

今回のテストプロジェクトの場合は

gen-types

としておく。

これが終わると

と、「プラグインをインストールするためには、npm install を実行してください」と言われているので、今回はyarnを使っているので、

yarn

を実行。

最後に、以下のモジュールも追加。

yarn add -D @graphql-codegen/typescript

■6. クエリの設定

現状(2021/11/3)、セクション4で使用するnext-page-testerがNextjs ver12に対応していない為、下記コマンドを実行して、Nextのversionを11系に変更

yarn add next@11.1.2

6-1. queries という空のフォルダを作成

mkdir queries

「queries」ディレクトリに、queries.ts を新規作成

touch queries.ts(macのターミナル)
New-Item queries.ts(Windowsのシェルスクリプト)

6-2. queries.ts の編集。

今までHasuraのAPIで、ブラウザでクエリやミューテーションを操作していたものを、フロントエンド側で操作できるように、必要なコマンドを作っていく。

最初は、アポロクライアントから必要なオブジェクトをインポート。

import { gql } from '@apollo/client'

基本形。GetUsersの中身はHasuraのGraphQLからコピペする。

import { gql } from '@apollo/client'

export const GET_USERS = gql`
query GetUsers{
  users(order_by: {created_at: desc}) {
    id
    name
    created_at
  }
}
`

queryは一緒だが、「@client」とつけることで、クライアントサイドにあるキャッシュの方を見に行く。こうすることで、Reduxのように、色々なコンポーネントから自由に、保存されているGetUsersの一覧のデータを好きにアクセスすることができるようになる。

export const GET_USERS_LOCAL = gql`
query GetUsers{
  users(order_by: {created_at: desc}) @client {
    id
    name
    created_at
  }
}
`

完成形は以下。

import { gql } from '@apollo/client'

export const GET_USERS = gql`
  query GetUsers {
    users(order_by: { created_at: desc }) {
      id
      name
      created_at
    }
  }
`
export const GET_USERS_LOCAL = gql`
  query GetUsers {
    users(order_by: { created_at: desc }) @client {
      id
      name
      created_at
    }
  }
`
export const GET_USERIDS = gql`
  query GetUserIds {
    users(order_by: { created_at: desc }) {
      id
    }
  }
`
export const GET_USERBY_ID = gql`
  query GetUserById($id: uuid!) {
    users_by_pk(id: $id) {
      id
      name
      created_at
    }
  }
`
export const CREATE_USER = gql`
  mutation CreateUser($name: String!) {
    insert_users_one(object: { name: $name }) {
      id
      name
      created_at
    }
  }
`
export const DELETE_USER = gql`
  mutation DeleteUser($id: uuid!) {
    delete_users_by_pk(id: $id) {
      id
      name
      created_at
    }
  }
`
export const UPDATE_USER = gql`
  mutation UpdateUser($id: uuid!, $name: String!) {
    update_users_by_pk(pk_columns: { id: $id }, _set: { name: $name }) {
      id
      name
      created_at
    }
  }
`

6-3. typescriptに必要なデータ型の自動生成を行う。

generate types automatically を実行する。

1点注意点は、generate types automatically を実行する際は、以下の

export const GET_USERS_LOCAL = gql`
  query GetUsers {
    users(order_by: { created_at: desc }) @client {
      id
      name
      created_at
    }
  }
`

コメントアウトする。サーバー用とクライアント用で、同じクエリ「GetUsers 」が実行されることになるため、それはエラーとみなされるから。

yarn gen-types

自動生成の成功。

ここに自動生成される。

よって、プロジェクトの中では、この「graphql.tsx」から必要な型をインポートして、必要なところで使っていくことができる。

以下のコメントアウトを外して、戻しておく。

export const GET_USERS_LOCAL = gql`
  query GetUsers {
    users(order_by: { created_at: desc }) @client {
      id
      name
      created_at
    }
  }
`

yarn add --dev eslint

7. その他ライブラリ

SASSを読み込めるようにする

npm install sass

cssをscssにリネーム。pages内のファイルネームも忘れずに。

React-Bootstrapをインストール

https://react-bootstrap.github.io/getting-started/introduction

npm install react-bootstrap bootstrap@5.1.3

こちらの方がよりbootstrapライクである。

MUIをインストール

https://mui.com/getting-started/installation/

npm install @mui/material @emotion/react @emotion/styled
npm install @mui/material @mui/styled-engine-sc styled-components
npm install @mui/icons-material

こちらの方がReactだと一番ポピュラーらしい。typescriptのLinkとかで使う。

MATERIAL-UIをインストール

https://v4.mui.com/

npm install @material-ui/core

必要なのはこちら?typescriptのLinkとかで使う。

Reactのアイコンライブラリ

(公式)

https://react-icons.github.io/react-icons/

npm install react-icons

fontawesomeのReact版アイコンライブラリ

(公式)

https://fontawesome.com/v5/docs/web/use-with/react

npm i --save @fortawesome/fontawesome-svg-core
npm install --save @fortawesome/free-solid-svg-icons
npm install --save @fortawesome/react-fontawesome
npm install --save @fortawesome/free-brands-svg-icons

React Playerをインストール

(公式 ドキュメントはこれしか無い。。)

https://www.npmjs.com/package/react-player

npm i -D react-player

8. 番外編

npmのキャッシュクリア

npm cache verify --force

公式ドキュメント

https://nextjs-ja-translation-docs.vercel.app/docs/getting-started

Next.js 公式example集

https://github.com/vercel/next.js/tree/canary/examples

公式exampleを分類してくれている

https://qiita.com/masakinihirota/items/60c687427b1092cf072d