Markdwonメモアプリ作成(TypeScript)(第一回)

データ管理

前回まで作成したMarkdwonメモアプリですが、TypeScriptを使うように変更します。

TypeScriptの使用経験はありませんが、勉強のために挑戦します。

前回の反省も踏まえて最初から作成したいと思います。

今回の手順は以下のとおりです。

構成紹介

今回作成する環境の構成は以下のとおりです。

  • React
  • Flask
  • MariaDB

Dockerを使って各環境を構築していきます。

ホストのマシンはWindows 10です。DockerとDocker Composeのインストールの手順については省略します。

React環境構築

最初にReactの環境を構築します。

環境構築の手順は以下のとおりです。

  • 1.ディレクトリ作成
  • 2.Dockerfile作成
  • 3.docker-compse.yml作成
  • 4.Reactアプリ作成
  • 5.Reactパッケージインストール
  • 6.docker-compse.yml作成
  • 7.React起動

なお最初の段階で以下のパッケージインストールしておきます。

  • axios
  • react-router-dom
  • react-markdown
  • remark-gfm
  • @mui/material
  • @mui/icons-material
  • @emotion/react
  • @emotion/styled

ディレクトリ作成

ディレクトリを作成します。React環境構築のディレクトリ構成は以下のとおりです。

「project」は環境構築における最初のディレクトリです。

Windowsの場合は「C:\project」や「D:\work\project」がディレクトリの場所になります。

「project」の配下に「front」のディレクトリを作成します。

「front」の配下に「src」のディレクトリを作成します。

以下のファイル構成になっていれば大丈夫です。

    
project/
 ┗ front/
     ┗ src/
    
  

Dockerfile作成

Dockerfileを作成します。

このDockerfileにnode.jsのイメージファイルの取得内容を記載します。

「front」の配下に「Dockerfile」のファイルを作成します。

    
project/
 ┗ front/
    ┣ Dockerfile
    ┗ src/
    
  

Dockerfileの内容は以下のとおりです。

    
FROM node:18-alpine
WORKDIR /usr/src
    
  

alpineサーバ、node.jsのバージョンが18のイメージを使います。

Docker内の作業用ディレクトリのパスは「/usr/src」です。

docker-compse.yml作成

docker-compse.ymlを作成します。

「project」の配下に「docker-compse.yml」のファイルを作成します。

    
project/
 ┣ front/
 ┃  ┣ Dockerfile
 ┃  ┗ src/
 ┗ docker-compose.yml
    
  

docker-composeの内容は以下のとおりです。

    
version: '3'

services:
  front:
    container_name: front
    build: ./front
    volumes:
      - ./front/src:/usr/src
    command: sh -c "cd markdown-app && yarn start"
    ports:
      - "3000:3000"
    
  

docker-compse.ymlにはnode.jsのDockerのビルド方法や、volumes、portの設定などを記載します。

Reactアプリ作成

Reactのアプリを作成します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

今回はnpxコマンドを使ってアプリを作成します。

    
docker-compose run --rm front sh -c "npx create-react-app markdown-app --template typescript"
    
  

docker-composeが実行されてDocker内にReactのアプリが作成されます。

アプリが作成されるとvolumesを設定しているので、ホスト側にもReactのアプリが作成されます。

このコマンドはReactアプリを作成後rmオプションでDockerコンテナを削除をしています。

成功すると「src/」配下に「markdown-app/」のディレクトリが作成されます。

    
project/
 ┣ front/
 ┃ ┣ Dockerfile
 ┃ ┗ src/
 ┃   ┗ markdown-app/
 ┗ docker-compose.yml
    
  

パッケージインストール

パッケージをインストールします。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

今回はnpxコマンドを使ってアプリを作成します。

    
docker-compose run --rm front sh -c "cd markdown-app && npm install axios react-router-dom react-markdown remark-gfm @mui/material @mui/icons-material @emotion/react @emotion/styled"
    
  

追加したパッケージがpackage.jsonに記載されていれば成功です。

    
project/
 ┗ front/
   ┣ Dockerfile
   ┗ src/
     ┗ markdown-app/
       ┗ package.json
    
  

以下のように記載されます。

    
・・・略・・・
  "dependencies": {
    "@emotion/react": "^11.9.0",
    "@emotion/styled": "^11.8.1",
    "@mui/icons-material": "^5.8.0",
    "@mui/material": "^5.8.0",
    "@testing-library/jest-dom": "^5.16.4",
    "@testing-library/react": "^13.2.0",
    "@testing-library/user-event": "^13.5.0",
    "@types/jest": "^27.5.1",
    "@types/node": "^16.11.36",
    "@types/react": "^18.0.9",
    "@types/react-dom": "^18.0.4",
    "axios": "^0.27.2",
    "react": "^18.1.0",
    "react-dom": "^18.1.0",
    "react-markdown": "^8.0.3",
    "react-router-dom": "^6.3.0",
    "react-scripts": "5.0.1",
    "remark-gfm": "^3.0.1",
    "typescript": "^4.6.4",
    "web-vitals": "^2.1.4"
  },
・・・略・・・
    
  

React起動

docker-compose upを使ってReactを起動します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

    
docker-compose up
    
  

起動したら以下のURLをブラウザに入力します。

http://localhost:3000

Reactの画面が表示されたら成功です。

Flask環境構築

つぎにFlaskの環境を構築します。

環境構築の手順は以下のとおりです。

  • 1.ディレクトリ作成
  • 2.app.py作成
  • 3.requirements.txt作成
  • 4.Dockerfile作成
  • 5.docker-compse.yml更新
  • 6.Flask起動

ディレクトリ作成

ディレクトリを作成します。

    
project/
 ・・・略・・・
 ┣ back/
 ┃ ┣ Dockerfile
 ┃ ┗ src/
 ┃   ┗ app.py
 ┗ docker-compose.yml
    
  

「project」の配下に「back」のディレクトリを作成します。

「back」の配下に「src」のディレクトリを作成します。

以下のファイル構成になっていれば大丈夫です。

    
project/
 ・・・略・・・
 ┣ back/
 ┃ ┗ src/
 ┗ docker-compose.yml
    
  

app.py作成

「Hello World」を返却するFlaskのアプリを作成します。

「back/src」の配下に「app.py」のファイルを作成します。

    
project/
 ・・・略・・・
 ┣ back/
 ┃ ┗ src/
 ┃   ┗ app.py 
 ┗ docker-compose.yml
    
  

app.pyの内容は以下のとおりです。

    
from flask import Flask, request
from flask_cors import CORS

app = Flask(__name__)
CORS(app) 

@app.route("/", methods=["GET"])
def test():
    return "Hello World"
    
  

requirements.txt作成

パッケージをインストールするためのrequirements.txtを作成します。

requirements.txtには、環境でつかうパッケージとバージョンを記述します。

「back」の配下に「requirements.txt」のファイルを作成します。

    
project/
 ・・・略・・・
 ┣ back/
 ┃ ┣ requirements.txt
 ┃ ┗ src/
 ┃   ┗ app.py 
 ┗ docker-compose.yml
    
  

requirements.txtの内容は以下のとおりです。

    
flask == 2.1.2
flask-cors ==  3.0.10
PyMySQL == 1.0.2
    
  

Dockerfile作成

Dockerfileを作成します。

「back」の配下に「Dockerfile」のファイルを作成します。

    
project/
 ・・・略・・・
 ┣ back/
 ┃ ┣ Dockerfile
 ┃ ┣ requirements.txt
 ┃ ┗ src/
 ┃   ┗ app.py 
 ┗ docker-compose.yml
    
  

Dockerfileの内容は以下のとおりです。

    
FROM python:3.10-alpine

WORKDIR /usr/lib
COPDY requirements.txt /usr/lib
RUN pip install -r requirements.txt

WORKDIR /usr/src
    
  

alpineサーバ、pythonのバージョンが3.10のイメージを使います。

requirements.txtをコピーした後、pipでパッケージをインストールします。

Docker内の作業用ディレクトリのパスは「/usr/src」です。

docker-compse.yml更新

docker-compse.ymlを更新します。

    
version: '3'

services:
  front:
    container_name: front
    build: ./front
    volumes:
      - ./front/src:/usr/src
    command: sh -c "cd markdown-app && yarn start"
    ports:
      - "3000:3000"

  back:
    container_name: back
    build: ./back
    volumes:
      - ./back/src:/usr/src
    command: flask run --host 0.0.0.0 --port 5000
    ports:
      - "5000:5000"
    
  

Flask起動

docker-compose upを使ってFlaskを起動します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

    
docker-compose up
    
  

起動したら以下のURLをブラウザに入力します。

http://localhost:5000

"Hello World"が表示されたら成功です。

MariaDB環境構築

最後にMariaDBの環境を構築します。

環境構築の手順は以下のとおりです。

  • 1.ディレクトリ作成
  • 2.docker-compse.yml更新
  • 3.MariaDB起動

ディレクトリ作成

ディレクトリを作成します。

    
project/
 ・・・略・・・
 ┣ database/
 ┃ ┣ init/
 ┃ ┗ data/ 
 ┗ docker-compose.yml
    
  

「project」の配下に「database」のディレクトリを作成します。

データベース関連のデータを格納するディレクトリです。

「database」の配下に「init」のディレクトリを作成します。

環境構築時にデータベースや、テーブルを作成するSQLを配置します。

「database」の配下に「data」のディレクトリを作成します。

Dockerを利用するとコンテナの内容は消えてしまいます。ホスト側でDockerのdatabaseの内容を保持することでデータの永続化(コンテナが消えてもデータがのこる)を行います。

init.sqlの作成

init.sqlを作成します。

「database/init/」の配下に「init.sql」のファイルを作成します。

    
project/
 ・・・略・・・
 ┣ database/
 ┃ ┣ init/
 ┃ ┃ ┗ init.sql
 ┃ ┗ data/ 
 ┗ docker-compose.yml
    
  
    
CREATE DATABASE IF NOT EXISTS mdb;

CREATE TABLE IF NOT EXISTS mdb.markdown (url varchar(500), title varchar(250), body text);

REPLACE INTO mdb.markdown (url, title, body) VALUES ('test/test', 'test', '# TEST');
REPLACE INTO mdb.markdown (url, title, body) VALUES ('test/test2', 'test2', '# TEST2');

COMMIT;
    
  

データが登録されない場合があります。その場合は手動で登録してください。

Dockerfile作成

Dockerfileの中でMariaDBが起動時に初期データを登録できるようにinitファイルをコピーしておきます。

「database」の配下に「Dockerfile」のファイルを作成します。

    
project/
 ・・・略・・・
 ┣ database/
 ┃ ┣ Dockerfile
 ┃ ┣ init/
 ┃ ┃ ┗ init.sql
 ┃ ┗ data/ 
 ┗ docker-compose.yml
    
  

Dockerfileの内容は以下のとおりです。

    
FROM mariadb
COPY ./init/init.sql /docker-entrypoint-initdb.d/
    
  

init.sqlに初期データベースの作成、テーブルの作成、データの作成を行うSQLを記載します。

COPYコマンドで /docker-entrypoint-initdb.d/にinit.sqlファイルに配置します。

コンテナ起動時にinit.sqlのファイルがよみこまれてSQLが実行されます。

これにより、Databaseやテーブルが起動時に作成されます。

docker-compse.yml更新

docker-compse.ymlを更新します。

    
version: '3'

services:
  front:
    container_name: front
    build: ./front
    volumes:
      - ./front/src:/usr/src
    command: sh -c "cd markdown-app && yarn start"
    ports:
      - "3000:3000"

  back:
    container_name: back
    build: ./back
    volumes:
      - ./back/src:/usr/src
    command: flask run --host 0.0.0.0 --port 5000
    ports:
      - "5000:5000"

  database:
    container_name: database
    build: ./database
    volumes:
      - ./data:/var/lib/mysql
    ports:
      - 3306:3306
    environment:
      - MYSQL_ROOT_PASSWORD=adminpass
      - MYSQL_DATABASE=mdb
      - MYSQL_USER=mdbuser
      - MYSQL_PASSWORD=mdbpass
    
  

MariaDB起動

docker-compose upを使ってMariaDBを起動します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

    
docker-compose up
    
  

起動したらMariaDBのコンテナに入ってデータベースにアクセスします。

    
docker exec -it database sh
    
  

コンテナに接続できたらmysqlにログインします。

    
mysql --user=mdbuser --password=mdbpass
    
  

以下のような表示であればログインは成功です。

    
Welcome to the MariaDB monitor.  Commands end with ; or \g.
Your MariaDB connection id is 5
Server version: 10.7.3-MariaDB-1:10.7.3+maria~focal mariadb.org binary distribution
Copyright (c) 2000, 2018, Oracle, MariaDB Corporation Ab and others.
Type 'help;' or '\h' for help. Type '\c' to clear the current input statement.
MariaDB [(none)]> 
    
  

ログアウトは「quit」を入力します。そのあと、「exit」でコンテナからログアウトします。

Flask-MariaDB接続

Flask-MariaDB接続設定を行います。

Flaskのapp.py更新

Flaskのapp.pyファイルを更新します

    
import os

from flask import Flask, request
from flask_cors import CORS

import pymysql.cursors
import json


app = Flask(__name__)
CORS(app)


def db_connection():
    conn = pymysql.connect(
        host='database',
        port=3306,
        user=os.environ.get('MYSQL_USER'),
        password=os.environ.get('MYSQL_PASSWORD'),
        db=os.environ.get('MYSQL_DATABASE'),
        cursorclass=pymysql.cursors.DictCursor
    )

    return conn

@app.route('/markdown', methods=["GET"])
def get_markdown():
    conn = db_connection()
    with conn.cursor() as cur:
        cur.execute(f"SELECT * FROM markdown")
        results = cur.fetchall()

    return json.dumps(results, indent=2)

    
  

「/markdown」のURLを指定した時にSELECT文を発行し内容を返却します。

Flaskのdocker-compse.yml更新

Flaskのdocker-compse.ymlの内容を更新します。

    
version: '3'

services:
  web:
    build: ./web
    volumes:
      - ./web/src:/usr/src
    command: sh -c "cd react-project && yarn start"
    ports:
      - "3000:3000"

  flask:
    container_name: api
    build: api/
    volumes:
      - ./api/src:/usr/src
    command: flask run --host 0.0.0.0 --port 5000
    ports:
      - "5000:5000"
    environment:
      - MYSQL_ROOT_PASSWORD=test
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    depends_on:
      - db

  db:
    container_name: db
    build: ./db
    volumes:
      - ./db/database:/var/lib/mysql
    environment:
      - MYSQL_ROOT_PASSWORD=test
      - MYSQL_DATABASE=test
      - MYSQL_USER=test
      - MYSQL_PASSWORD=test
    ports:
      - "3306:3306"

    
  

docker-compse起動

docker-compose upを使って各コンテナを起動します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

    
docker-compose up
    
  

起動したら以下のURLをブラウザに入力します。

http://localhost:5000

"Hello World"が表示されます。

次に、FlaskとMariaDBの接続を確認します。

http://localhost:5000/markdown

「[ { "url": "test/test", "title": "test", "body": "# TEST" }, { "url": "test/test2", "title": "test2", "body": "# TEST2" } ]」が表示されたら成功です。

React-Flask接続

React-Flask接続の設定を行います。

Reactのapp.tsx更新

Reactのapp.jsの内容を更新します。

更新するファイルは以下のファイルです。

    
project/
 ┣ front/
 ┃ ┣ Dockerfile
 ┃ ┗ src/
 ┃   ┗ markdown-app/
 ┃     ┗ src/
 ┃       ┗ app.tsx
・・・略・・・
    
  

下記のように書き換えます。

    
import axios from "axios";
import { FC, useEffect, useState } from "react";

export const App: FC = () => {

  type Markdown = {
    url: string
    title: string
    body: string;
  }

  const [markdown, setMarkdown] = useState([]);

  useEffect(() => {
    axios.get("http://localhost:5000/markdown")
      .then(res => { setMarkdown(res.data); })
  }, [])
  return (
    <div>
      {markdown.map((markdown_data: Markdown, index: number) => {
        return (<p key={index} >{markdown_data.title}</p>);
      })}
    </div>
  );
}
    
  

Reactのindex.tsx更新

Reactのapp.jsの内容を更新します。

更新するファイルは以下のファイルです。

    
project/
 ┣ front/
 ┃ ┣ Dockerfile
 ┃ ┗ src/
 ┃   ┗ markdown-app/
 ┃     ┗ src/
 ┃       ┣ index.tsx
 ┃       ┗ app.tsx
・・・略・・・
    
  

下記のように書き換えます。

    
import React from 'react';
import ReactDOM from 'react-dom/client';
import App from './App';
import reportWebVitals from './reportWebVitals';

const root = ReactDOM.createRoot(document.getElementById('root'));
root.render(
  <React.StrictMode>
    <App />
  </React.StrictMode>
);

reportWebVitals();
    
  

ファイル修正

React内のファイルの削除等を行います。

publicは以下とsrcは以下は以下の状態にします。

    
project/
 ┣ front/
 ┃ ┣ Dockerfile
 ┃ ┗ src/
 ┃   ┗ markdown-app/
 ┃     ┣ public/
 ┃     ┃ ┣ favicon.ico
 ┃     ┃ ┣ index.html
 ┃     ┃ ┣ manifest.json
 ┃     ┃ ┗ robots.txt
 ┃     ┗ src/
 ┃       ┣ App.tsx
 ┃       ┣ index.css
 ┃       ┣ index.tsx
 ┃       ┣ react-app-env.d.ts
 ┃       ┣ reportWebVitals.ts
 ┃       ┗ setupTests.ts
・・・略・・・
    
  

public/index.htmlを下記のように書き換えます。

    
<!DOCTYPE html>
<html lang="jp">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" href="%PUBLIC_URL%/favicon.ico" />
    <meta name="viewport" content="width=device-width, initial-scale=1" />
    <meta name="theme-color" content="#000000" />
    <meta
      name="description"
      content="Web site created using create-react-app"
    />
    <link rel="apple-touch-icon" href="%PUBLIC_URL%/logo192.png" />
    <link rel="manifest" href="%PUBLIC_URL%/manifest.json" />
    <title>Markdown App</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

    
  

public/manifest.jsonを下記のように書き換えます。

    
{
  "short_name": "Markdown App",
  "name": "Markdown App",
  "icons": [
    {
      "src": "favicon.ico",
      "sizes": "64x64 32x32 24x24 16x16",
      "type": "image/x-icon"
    }
  ],
  "start_url": ".",
  "display": "standalone",
  "theme_color": "#000000",
  "background_color": "#ffffff"
}
    
  

docker-compse起動

docker-compose upを使って各コンテナを起動します。

docker-compose.ymlファイルがある場所で以下のコマンドを実行します。

    
docker-compose up
    
  

起動したら以下のURLをブラウザに入力します。

http://localhost:3000

test test2が表示されます。

まとめ

今回からMarkdwonメモアプリ作成(TypeScript)を実施します。

まだ環境構築の段階ですが、次回からコーディングを進めます。

コメント

0 件のコメント:

コメントを投稿

コメントをお待ちしています。