konchangakita

KPSを一番楽しんでいたブログ 会社の看板を背負いません 転載はご自由にどうぞ

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 Layout を作る

SSR で Fetch して表示するデータはそろってきました

ここでページ移動しても共通で表示させる「ナビゲーションバー」を Layout コンポーネントを作ってみます

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
ログインページをデザイン
フォーム制御
とりあえずFetch
FetchからRouterでページ遷移
SSR で Fetch する
・Layoutつくる ←イマココ


準備

今回の最終形態はコチラ(Github)で公開しています

Layoutファイルの設置場所

Next.js のプロジェクト直下に「components」フォルダを作って、「layout.tsx」ファイルを作ります


Layoutの作成

まず初めに、tailwindcss のコンフィグファイルに Layoutファイルの場所を追記します

...
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
    "./components/**/*.{js,ts,jsx,tsx}",
  ],
...


layout.tsx をまず {children} (ベースとなるページ)を表示するだけの空っぽ状態を作ってみます
<components/layout.tsx

import type { NextPage } from 'next'

import { ReactElement } from 'react'

type LayoutProps = Required<{
  readonly children: ReactElement
}>

const Layout: NextPage<LayoutProps> = ({children}) => {

  return (
    <>
        {children}
    </>
  )
}

export default Layout


あとはレイアウトを使う側のページで、ファイルの場所をインポートし タグで挟んでやるだけです
<pages/home.tsx

import Layout from '../components/layout'

    <Layout>
      ...
    </Layout>


ナビゲーションバーの実装

daisyUI の Navbar を参考に作ってみます
Navbar — Tailwind CSS Components

まだナビゲーションバーとしての役目は、まだ何もないですが、とりあえず見栄えだけ整えてみました
<components/layout.tsx

<pages/home.tsx


http://localhost:7778/home?cluster_name=クラスタ名>」
Elasticsearchからデータが取得できると一覧がドワーっと表示されます

うまくデータが取得できなかった時

さいごに

デザイン的には本当は CSS 使うのでしょうが、tailwindCSS と DaisyUI いれてるので、ほとんど使っていません
(きっともうちょっと大規模になれば必要かと)

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 SSR で Fetch する

Fetch で得た レスポンスデータ を使ってページ遷移までを行いました
次に、ページ遷移した後に表示するデータをバックエンド(Flask、Elasticsearch)から取得して サーバサイドレンダリングSSR)を行います


【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
ログインページをデザイン
フォーム制御
とりあえずFetch
FetchからRouterでページ遷移
SSR で Fetch する ←イマココ
・Layoutつくる 



SSR は、ユーザからのリクエストごとに動的にデータを取得してページが作成されます
今回でいうと、Elasticsearchからデータを取得しページに表示させることになります


Next.js で SSR するには 「getServerSideProps」 を 使います

準備

今回の最終形態はコチラ(Github)で公開しています

1.コンテナ起動

docker-compose.yml からコンテナたちを起動します

2.プログラム起動

コンテナ frontend、backend のコンテナ内で
・フロントエンドの起動
"/usr/src/next-app/uuid"

# npm run dev

・バックエンドの起動
"/usr/src/flaskr"

# python app.py
3.ブラウザアクセス

ブラウザから「http://localhost:7778/」にアクセス

4.Nutanixクラスタの IP/ユーザー/パスワード を入力してログイン


getServerSideProps の使い方

遷移先のページで 「getServerSidePropsType」作ってやることで、データ取得してからページレンダリングされます
(なのでページ表示まで時間がかかる)

以下の例では、URL の GETパラメータを Next.js コンソールに表示するようにしています

import type { GetServerSideProps, InferGetServerSidePropsType } from 'next'
type Props = InferGetServerSidePropsType<typeof getServerSideProps>

export const getServerSideProps: GetServerSideProps = async context => {
  console.log('query: ', context.query)

  /* ここに fetch などの処理 */

  return {
    props: {}
  }
}

TypeScript では 型を気にしないといけないので、いろいろつけてます

こんな URL なら

こんな 表示


SSR で Fetch

では、この GET パラメータを使って Fetch してみます
この記事のバックエンドで作ったAPI /api/latestdataset を少し改良したデータを取ってきます
※まだ return していません
フロントエンド<pages/home.tsx

export const getServerSideProps: GetServerSideProps = async context => {
  //console.log('query: ', context.query)
  const keyword = context.query

  const requestOptions = {
    method: "POST",
    headers: {'Content-Type' : 'application/json'},
    body: JSON.stringify(keyword)
  }

  console.log(requestOptions)

  const fetchUrl = "http://backend:7777/api/latestdataset"
  const response = await fetch(fetchUrl, requestOptions)
  if (response.ok) {
    var res:dict = await response.json()
  } else {
    var res:dict = { 'list' : '' }
  }

  console.log(res)

  return {
    props: {}
  }
}

Next.js のコンソール


SSRでデータを表示

getServerSidePropsType を使って、取得したデータを使ってページレンダリングするには、return で変数を返してやります

  ...

  return {
    props: { res }
  }


次に受け取る側の関数で、return された同じ変数名で受け取ります

const Home: NextPage<Props> = ({res}) => {
  console.log(res)

  ....
}

export default Home


バックエンドから受け取ったデータをそのまま表示する流れがコチラ

フロントエンド:<pages/home.tsx

バックエンド:<flaskr/app.py>

getServerSidePropsType を使ってバックエンドから取得したデータをただ表示しているだけなのでだいぶブサイクです
次回、表示を整えます


SSRは終了

これでバックエンドとのやりとりの部分は完了です
ここからは Next.js の中でどんな風に表現したいのかを考えながら、データを取り扱っていきます

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 FetchからRouterでページ遷移

前回はとりあえず fetch してレスポンスを確認しただけだったので、フォーム入力されたデータを使って、ページ遷移します

下記エントリで Native React で Fetch を作り込んだ「/api/connect」、「/api/latestdataset」からデータひっぱってきたいと思います
konchangakita.hatenablog.com



【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
ログインページをデザイン
フォーム制御
とりあえずFetch
・FetchからRouterでページ遷移 ←イマココ
SSR で Fetch する
・Layoutつくる 


準備

今回の最終形態はコチラ(Github)で公開しています

この docker-compose.yml からコンテナたちを起動します

コンテナ frontend、backend のコンテナ内で
・フロントエンドの起動
"/usr/src/next-app/uuid"

# npm run dev

・バックエンドの起動
"/usr/src/flaskr"

# python app.py

ブラウザから「http://localhost:7778/」にアクセス

POST で fetch

前回とりあえず fetch の練習だけおこなっていましたが、
onConnect関数 にフォームにインプットされたデータを使って POST します

POSTで渡す値は、json形式にします

const requestOptions = {
  method: "POST",
  headers: {'Content-Type' : 'application/json'},
  body: JSON.stringify(data)
}


関数に組み込んでみると
フロントエンド:<pages/index.tsx

  const onConnect: SubmitHandler<FormValues> = async data => {
    console.log(data)
    const requestOptions = {
      method: "POST",
      headers: {'Content-Type' : 'application/json'},
      body: JSON.stringify(data)
    }

    const response = await fetch('/api/connect', requestOptions)
    if(response.status === 200) {
      const res_json = await response.json()
      console.log(res_json)
      if(res_json.info === 'success') {
        console.log(res_json)
      } else { alert('login failed') }
    }
  }


CORS問題対策に間に挟む別ファイルの関数にも、POSTで受け取ったデータを使って、バックエンドへ POST で fetch しています

フロントエンド:<pages/api/connects.ts>

import { NextApiRequest, NextApiResponse } from 'next'

export default async (req: NextApiRequest, res: NextApiResponse) => {
  const requestOptions = {
    method: "POST",
    headers: {'Content-Type' : 'application/json'},
    body: JSON.stringify(req.body)
  }

  const response = await fetch("http://backend:7777/api/connect", requestOptions)
  const data = await response.json()

  // response.status > success 200
  res.status(response.status).json(data);
}

fetch でデータをとってくる先は、バックエンドの flask で作った 「Nutanixクラスタに接続しクラスタ名を取得し、データを Elasticsearch へインプットする」関数です
関数の中身の説明はココ
【Nutanix UUIDエクスプローラーを作ってみよう】Flask表示までのまとめ - konchangakita


Nutanixクラスタのログイン情報をインプットし、無事接続できると Elasticsearch にデータ入力後にクラスタ名がレスポンスで返ってきます


fetch 後にページ遷移

fetch してデータ取得に成功後にページ遷移をさせたい場合には、Next.js機能の Router を使います

import { useRouter } from 'next/router'

router.push({
  pathname: '/home',
  query: {
    cluster: res_json.cluster_name,
  }
})

こうすることで、ページ遷移の際に fetcth のレスポンスとして受け取ったクラスタ名を含んだ「http://~~/?cluster=クラスタ名」という GET のURLとなります


関数に組み込んでみます

  const onConnect: SubmitHandler<FormValues> = async data => {
    console.log(data)
    const requestOptions = {
      method: "POST",
      headers: {'Content-Type' : 'application/json'},
      body: JSON.stringify(data)
    }

    const response = await fetch('/api/connect', requestOptions)
    if(response.status === 200) {
      const res_json = await response.json()
      console.log(res_json)
      if(res_json.info === 'success') {
        console.log(res_json)
        router.push({
          pathname: '/home',
          query: {
            cluster: res_json.cluster_name,
          }
        })
      } else { alert('login failed') }
    }
  }


遷移先のページ作成

遷移先のページを「pages/home.tsx」で作ります
URL の GETパラメータをページ上に表示するだけのページを作ります

フロントエンド:<pages/home.tsx

import type { NextPage } from 'next'
import { useRouter } from 'next/router'

const Index: NextPage = () => {
  const router = useRouter()
  const {cluster} = router.query
  return (
    <div className="">
      <main data-theme="white" className="h-screen flex justify-center items-center">
        {cluster}
      </main>
    </div>
  )
}

export default Index

fetch に時間をかける

fetchしてページ遷移しましたが、次はページ遷移した先で fetch して SSR(サーバサイドレンダリング) を行います

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 とりあえずFetchする

フォームで受け取ったデータ(Prism IP、ユーザ名、パスワード)を使ってバックエンドにリクエスト行い、レスポンスを取得する Fetch を実装します
SSR(サーバサイドレンダリング)までは実装は次で

Next.jsの実装とともに、フロントエンドとバックエンドのコンテナを分けたことによって少々手間がかかります(CORS問題)


【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
ログインページをデザイン
フォーム制御
・とりあえずFetch ←イマココ
FetchからRouterでページ遷移
SSR で Fetch する
・Layoutつくる


準備

今回の最終形態はコチラ(Github)で公開しています

この docker-compose.yml からコンテナたちを起動します

コンテナ frontend、backend のコンテナ内で
・フロントエンドの起動
"/usr/src/next-app/uuid"

# npm run dev

・バックエンドの起動
"/usr/src/flaskr"

# python app.py

ブラウザから「http://localhost:7778/」にアクセス


curl でレスポンスチェック

プログラムに組み込む前に、curlコマンドを使ってチェックします

まずはバックエンド側にテスト用に簡単なレスポンスを仕込みます
バックエンドコンテナ:<flaskr/app.py>

from flask import Flask
from flask import render_template, request
from flask import make_response, jsonify

.........
@app.route('/api/fetchtest')
def fetchtest():
    return make_response(jsonify('Fetch Success'))
.........

これでフロントエンドコンテナのコンソールから「http//コンテナ名:ポート番号/api/fetchtest」向けに、curlコマンド実行してやると、仕込んでおいたレスポンスを得られます

# curl http://backend:7777/api/fetchtest
"Fetch Success"


フロントエンドに実装

前回までで、フォームをサブミットすると、入力内容をコンソールに表示するだけだったこの部分の関数を編集していきます

フロントエンド:<pages/index.tsx
コレを

  const onConnect: SubmitHandler<FormValues> = data => console.log(data)

こんな感じで

  const onConnect: SubmitHandler<FormValues> = async data => {
    console.log(data)
    const requestOptions = {
      method: "POST",
      headers: {'Content-Type' : 'application/json'},
      body: JSON.stringify(data)
    }
    const response = await fetch('http://backend:7777/api/fetchtest')
    if(response.status === 200) {
      const res_json = await response.json()
      console.log(res_json)
    }
  }


そうすると、、、なぜだかうまくいきません。。

いろいろ調べてみると、フロントエンドとバックエンドのコンテナを分けたことによってCORS問題が発生している模様
さらにいろいろ調べてみましたが、正直なところ生半可な知識では解決方法は見つかりませんでした。。。

なので、直接このプログラムファイルから Fetch するのではなく、あいだにファイルを一個噛ませて2段階でやるとうまく取得できました

仕込みの手順

1.pagesフォルダ配下にapiフォルダを作成
2.connect.tsを作成
3.index.tsxでfetch(pages/api/connect.ts向け)
4.connect.tsでfetch(backend向け)

フロントエンド:<pages/index.tsx


フロントエンド:<pages/api/connect.ts>

ブラウザのコンソールログ

next.jsのログ


とりあえずの Fetch

CORS問題で一晩以上悩んだ結果、別ファイルを用意するという回りくどい方法をとりました
次でフォームのデータを使っての、リクエストを行います

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 フォームの実装

Nutanixクラスタに接続するための「Prism IP」、「ユーザ名」、「パスワード」フォーム入力の制御には、通常入力を必須にしたり、エラーメッセージの実装を作り込む必要があります
そうすると、フォームごとになかなかコードが増えてくし、なによりそれぞれ作るのはメンドウです。。。
というわけで、フォームの制御に Next.js に対応するReact Hook Formを使ってみます
ホーム | React Hook Form - Simple React forms validation


【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
ログインページをデザイン
・フォーム制御 ←イマココ
とりあえずFetch
FetchからRouterでページ遷移
SSR で Fetch する
・Layoutつくる

今回の成果物

今回の最終形態はコチラ(Github)で公開しています

React Hook Formのインストール

インストールは npm だけなので、簡単
next.jsのプロジェクトのディレクトリにて

# npm install react-hook-form


テスト実装

公式サイトの クイックスタート を参考にしながら進めていきます
サンプルコードの TS を押すと TypeScript 版での実装方法も書かれていて、親切で初心者にもウレシイ
これを参考に、現行のページに導入してみます


1つ目のポイントは、フォームの input に対応する Value を設定

type FormValues = {
  prism_ip: string
  prism_user: string
  prism_pass: string
}

あとは、React Hook Form のお作法に従う

  const {
    register,
    handleSubmit,
    formState: { errors },
  } = useForm<FormValues>()


フォームの input には 「{...register("prism_ip")}」という書き方で 設定した Value を呼び出します

<input {...register("prism_ip")} type="text" placeholder="Cluster IP" className="input input-info input-bordered m-1 w-64 text-lg" />
inputのオプション

React Hook Form の機能で入力必須にしたり、エラー表示も簡単に
入力必須:{...register("prism_ip", {required: true})}

<input {...register("prism_ip", {required: true})} type="text" placeholder="Cluster IP" className="input input-info input-bordered m-1 w-64 text-lg" />
エラー表示:{errors.prism_ip && 表示する内容}
{errors.prism_ip && <p className='text-red-600'>required.</p>}

インプットされた内容の処理

フォームで入力された内容は、Submitボタンを押されたときに onSubmit={handleSubmit(関数名)}で処理されます

<form onSubmit={handleSubmit(onConnect)}>


一旦、入力内容をコンソールに表示するだけならば

const onConnect: SubmitHandler<FormValues> = data => console.log(data)



実装

ここまでの実装をまとめると

いったんここまで

そもそもフォーム制御するライブラリというものがあるなんて考えてなかったので、はじめはとまどいながら実装してみましたが、一回慣れる手放せません
フォームで受け取ったデータを使っての fetch を次回

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓 ログインページをデザイン

Native React の環境では、一つのページ(URL)の中でNutanixクラスタ接続検索結果表示を行う、SPA(シングルページアプリケーション)でのカタチで作ってました

今回はなんとなく、それぞれ別にページを作っていきます


【Nutanix UUIDエクスプローラーを作ってみよう】Next.js特訓
・ログインページをデザイン ←イマココ
フォーム制御
とりあえずFetch
FetchからRouterでページ遷移
SSR で Fetch する
・Layoutつくる

今回の成果物

今回の最終形態はコチラ(Github)で公開しています

ページ設計

まともにWebサイトとか作ったことないので、どうやって設計するもんなんかはわかりませんが。。。
ページ設計としてはこんな感じで作ってみようかと


ログインページのベースデザイン

それっぽいログインページ風なものを作ってみます
(一旦色は無視)

画像の表示

表示する画像は、"public"配下に置いて

import Image from 'next/image'

<Image src="/uuid-xplorer_logo.png" alt="uuid xplorer logo" width={494} height={80} />

width, heightを両方指定しなければいけないのが、ちょっとメンドイ

フォーム

フォームには、daisyUI の Text Input をベースに使います
Text Input — Tailwind CSS Components

<input type="text" placeholder="Type here" className="input input-info" />

これだけでカタチになってくれるのは楽チン

ここから先は、tailwindcssも駆使しながらイメージしたデザインを作っていきます

<pages/index.tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'

//fontawesome
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowCircleRight } from '@fortawesome/free-solid-svg-icons'

const Index: NextPage = () => {
  return (
    <div className="">
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main data-theme="white" className="flex text-center items-center h-screen">
        <div className='w-1/2'>
          <div className='m-10'><Image src="/uuid-xplorer_logo.png" alt="uuid xplorer logo" width={494} height={80} /></div>
        </div>

        <div className="w-1/2 bg-primary h-screen flex justify-center items-center flex flex-col">
          <div className="form-control mt-20">
            <form >
              <div className='flex flex-col'>
                <input type="text" placeholder="Cluster IP" className="input input-info input-bordered m-1 w-64 text-lg" />
                <input type="text" placeholder="username" className="input input-info input-bordered m-1 w-64 text-lg" />
                <div className='m-1 relative'>
                  <input type="password" placeholder="Password" className="input input-info input-bordered w-64 text-lg" />
                  <button type="submit" className="absolute inset-y-2 right-2 opacity-20 hover:opacity-100"><FontAwesomeIcon icon={faArrowCircleRight} size="2x" /></button>
                </div>
              </div>
            </form>
          </div>
        </div>

      </main>
      <footer className="text-center text-sm">Copyright (C) konchangakita. All Rights Reserved.</footer>
    </div>
  )
}

export default Index



daisy UIを使ったテーマカラーの設定

daisyUI のテーマカラーを変更して、
 ・Primary を Nutanixのブルーに近いに色
 ・info をフォームの枠の色もぽいブルーに
 ・base をボタンのマウスオーバー用に
に設定してみます
daisyUI Theme Generator — Tailwind CSS Components

<tailwind.config.js>

module.exports = {
  content: [
    "./pages/**/*.{js,ts,jsx,tsx}",
  ],
  theme: {
    extend: {},
  },
  plugins: [
    require('daisyui'),
  ],
  daisyui: {
    themes: [
      {
        'mytheme': {
        'primary': '#21509e',

        'base-100': '#ffffff',
        'base-200': '#f9fafb',
        'base-300': '#d1d5db',
        'base-content': '#1f2937',
        'info': '#2094f3',

        },
      },
    ],
  }
}

ぽい色になった気がします


ここまで

今回は一旦簡単なデザインまで
フォーム制御、Fetch(SSR)につづく

【Nutanix UUIDエクスプローラーを作ってみよう】Next.js環境に tailwindcss/ DaisyUI/ Font Awesomeを導入

f:id:konchangakita:20220410110202p:plain
tailwindcss.com
daisyui.com
fontawesome.com



今回はNext.js環境に、デザインを意識したコンポーネント群を導入、初心者なのでとりあえずフレームワークを満載にして、フロントエンド開発環境をパワーアップさせてみます

今回の成果物

今回の最終形態はコチラ(Github)で公開しています
<フォルダ構造>
f:id:konchangakita:20220409145804p:plain

今回導入するモノ

tailwindcsscssが簡単になるcssフレームワーク的なな
daisyUI:デザインが完成されたtailwindcssの追加ライブラリ的な
Font Awesome:アイコンライブラリ的な

tailwindCSSの導入

ここを参照しつつ、環境にあわせてアレンジして設定していきます
Install Tailwind CSS with Create React App - Tailwind CSS

2つのコマンド実行
Next.jsのプロジェクト配下で(場所重要

# npm install -D tailwindcss postcss autoprefixer
added 54 packages, changed 2 packages, and audited 284 packages in 14s

74 packages are looking for funding
  run `npm fund` for details

found 0 vulnerabilities
# npx tailwindcss init -p
Created Tailwind CSS config file: tailwind.config.js
Created PostCSS config file: postcss.config.js

tailwind.config.js, postcss.config.js が作成されます


Reactデフォルトの pagesを使うので、tailwind.config.jsに下記を追記
tailwind.config.js

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


標準のCSSファイルに追記
styles/global.css

@import "tailwindcss/base";
@import "tailwindcss/components";
@import "tailwindcss/utilities";


これで、こんな感じで書くとスタイル(テキストを赤く)が適用されます
pages/index.html

<div className='text-red-500'>Welcome to UUID Xplorer</div>

f:id:konchangakita:20220410145217p:plain

ポイントNext.js環境では className とするのを気をつけましょう

daisyUIの導入

公式を参照してインストールします
Install daisyUI as a Tailwind CSS plugin — Tailwind CSS Components

Next.jsのプロジェクト配下で(場所重要

# npm i daisyui


tailwindcss をインストールしてできたコンフィグファイルに追記
tailwind.config.js

  plugins: [
    require('daisyui'),
  ],

pages/index.htmlに追記して、ボタンが表示されれば成功です
pages/index.html

<button className="btn">Button</button>

f:id:konchangakita:20220408232953p:plain

Font Awesomeの導入

React版のインストール方法を参照してインストールします
React | Font Awesome Docs

Next.jsのプロジェクト配下で実行(場所重要

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

Next.js用の適用方法を確認しつつ、
Use React with... | Font Awesome Docs

Next.jsですべてのページ共通で読み込まれる _app.tsx に追記
pages/_app.tsx

import '../styles/globals.css'
import type { AppProps } from 'next/app'

// fontawesome
import { config } from '@fortawesome/fontawesome-svg-core'
import '@fortawesome/fontawesome-svg-core/styles.css'
config.autoAddCss = false

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

export default MyApp


アイコンを使いたいページにアイコンごとに読み込みを行う
pages/index.tsx

import type { NextPage } from 'next'
import Head from 'next/head'
import Image from 'next/image'
import styles from '../styles/Home.module.css'

//fontawesome
import { FontAwesomeIcon } from '@fortawesome/react-fontawesome'
import { faArrowCircleRight } from '@fortawesome/free-solid-svg-icons'

const Home: NextPage = () => {
  return (
    <div className={styles.container}>
      <Head>
        <title>Create Next App</title>
        <meta name="description" content="Generated by create next app" />
        <link rel="icon" href="/favicon.ico" />
      </Head>

      <main className={styles.main}>
        <div className='text-red-500'>Welcome to UUID Xplorer</div>
        <FontAwesomeIcon icon={faArrowCircleRight} size="2x" />
      </main>
    </div>
  )
}

export default Home

f:id:konchangakita:20220410153819p:plain

docker-composeの整備

色々とインストールをしているうちに、package.json が成長していますね

{
  "name": "uuid-xplorer",
  "version": "0.1.0",
  "private": true,
  "scripts": {
    "dev": "next dev",
    "build": "next build",
    "start": "next start",
    "lint": "next lint"
  },
  "dependencies": {
    "@fortawesome/fontawesome-svg-core": "^6.1.1",
    "@fortawesome/free-solid-svg-icons": "^6.1.1",
    "@fortawesome/react-fontawesome": "^0.1.18",
    "daisyui": "^2.13.6",
    "next": "12.1.4",
    "react": "18.0.0",
    "react-dom": "18.0.0"
  },
  "devDependencies": {
    "@types/node": "17.0.23",
    "@types/react": "17.0.43",
    "@types/react-dom": "17.0.14",
    "autoprefixer": "^10.4.4",
    "eslint": "8.12.0",
    "eslint-config-next": "12.1.4",
    "postcss": "^8.4.12",
    "tailwindcss": "^3.0.23",
    "typescript": "4.6.3"
  }
}


ここまで準備ができたら、フロントエンドコンテナとして、docker-composeを整備します
バックエンドコンテナも併せて整備
<docker-compose>

これでGithubの状況と同じものがつくれます
https://github.com/konchangakita/blog-uuid-Xplorer/tree/main/blog/0418

準備完了

ここまで開発環境の準備は完了です
次からは、Next.jsを使って実際に Webインターフェースを構築していきます