Azure Static Web Apps にReactアプリをデプロイする方法

技術情報

簡単なサンプルアプリを作成してデプロイする手順のメモ。
※2020年11月時点で未だにプレビュー版なので、手順は大きく変わる可能性もあり

前提条件:

  • nodeがインストール済み
  • VS Codeがインストール済み
  • Azure Functions Core Toolsがインストール済み

Reactアプリの作成

プロジェクトのルートを作成。

$ mkdir hello-static-webapps-sample && cd hello-static-webapps-sample

create-react-appでサクッと作成。

$ npx create-react-app hello-app

VS Codeを開いてロゴとか使わないファイル消す。こんな感じで残った。

index.html

<!DOCTYPE html>
<html lang="ja">
  <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"
    />
    <title>Hello</title>
  </head>
  <body>
    <noscript>You need to enable JavaScript to run this app.</noscript>
    <div id="root"></div>
  </body>
</html>

index.js

import React from 'react';
import ReactDOM from 'react-dom';
import './index.css';
import App from './App';

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

index.css

body {
  margin: 0 auto;
  text-align: center;
  font-family: "メイリオ", sans-serif;
  background-color: darkslategray;
  color: white;
}

App.js

function App() {
  return (
    <div>
      Hello!
    </div>
  );
}

export default App;

ここまでで一旦画面が表示されるか確認する。
hello-app フォルダにて

$ npm start

ブラウザで画面が表示されればOK。

次にHelloコンポーネントを作る。

import { useState } from 'react';

const Hello = () => {
  const [name, setName] = useState('');
  const [greeting, setGreeting] = useState('Hello!');

  const handleNameChange = (e) => setName(e.target.value);

  function getGreeting() {
      //TODO: APIコール
      return "Hi!";
  }

  const handleButtonClick = (e) => {
      setGreeting(getGreeting());
  };

  return (
      <>
          <div>
              <input type="text" value={name} onChange={handleNameChange} placeholder="Enter your name" />
              <input type="button" onClick={handleButtonClick} value="Greet" disabled={!name} />
          </div>
          <span>{ greeting }</span>
      </>
  );
}

export default Hello;

App.js を修正。

import Hello from './Hello';

function App() {
  return (
    <div>
      <Hello />
    </div>
  );
}

export default App

画面は以下のようになる。

APIの作成

プロジェクトルート直下に api ディレクトリを作成する(Azure Functionsのプログラムや設定ファイルを格納)。

以下のVS Code拡張をインストールしておく。

  • Azure Functions
    Azure Static Web Apps (Preview)

※Azure Static Web Apps拡張を入れると、VS Code側からプロジェクトの作成が行えるようだが、今回の手順では不要。

VS CodeのAZUREタブの、フォルダのアイコン(Create new project)をクリック。

Azureのアカウント認証が求められたらブラウザでログイン後、以下の順に入力していく。

  1. ディレクトリ:apiディレクトリを選択
  2. 言語:JavaScript
  3. テンプレート:HTTP Trigger
  4. ファンクション名:GetGreeting
  5. 認証レベル:Anonymous

api ディレクトリ配下に各種ファイルが生成される。

index.js

module.exports = async function (context, req) {
    const name = context.bindingData.name;
    const greeting = `Hello, ${name}`;

    context.res = {
        status: 200, /* Defaults to 200 */
        body: {greeting: greeting},
        headers: {
            'Content-Type': 'application/json'
        }
    };
}

function.json

{
  "bindings": [
    {
      "authLevel": "anonymous",
      "type": "httpTrigger",
      "direction": "in",
      "name": "req",
      "methods": [
        "get"
      ],
      "route": "greeting/{name}"
    },
    {
      "type": "http",
      "direction": "out",
      "name": "res"
    }
  ]
}

URLパスの一部で名前を受け取るため、 greeting/{name} というルート設定を行っている。

F5を押すと、Azure Functions Core Toolsによってローカルで関数が起動する。

ブラウザで http://localhost:7071/api/greeting/Taro にアクセスし、結果がJSONで取得できることを確認。

APIの呼び出し

Hello.js の実装を修正。fetch APIでGetGreetingをAjaxコールして、データを取得する。

  async function getGreeting() {
    const response = await fetch(`/api/greeting/${name}`, {
      method: 'GET'
    });
    const json = await response.json();
    return json.greeting;
  }

  const handleButtonClick = (e) => {
    getGreeting()
      .then(value => {
        setGreeting(value)
      })
      .catch(err => {
        console.log(err);
      });
  };

このままではローカルでAPI連携できないので、package.json (React側)に一行追加してプロキシ設定を行う。

"proxy": "http://localhost:7071",

ブラウザから名前を入力して「Greet」をクリックし、以下のように名前入りのメッセージが表示されればOK。

デプロイ

ルートディレクトリで git init する。
.gitignore は最低限以下を記述。

node_modules
build

コミットする。

$ git add .
$ git commit -m "first commit"

GitHubのWeb画面から、リポジトリを新しく作成する(リポジトリ名:hello-static-webapps-sample)
…or push an existing repository from the command line で画面に表示されるgitコマンドをローカルで叩いてpushする。

GitHubの画面から、正常にpushされたことを確認する。

次にAzureポータルにログインし、リソースの作成(+)をクリックし、 Static Web App (preview) を選んで「作成」。以下の順に入力していく。

  1. サブスクリプション、リソースグループ:任意のもの
  2. 名前:HelloStaticWebAppsSample
  3. 地域:任意
  4. GitHubアカウント:サインインする
  5. 組織:GitHubアカウント
  6. リポジトリ:hello-static-webapps-sample
  7. 分岐:main
  8. ビルドのプリセット:Custom
  9. アプリの場所:/hello-app
  10. APIの場所:/api
  11. アプリの成果物の場所:build

入力したら「確認および作成」をクリック。確認画面で内容を確認して「作成」をクリック。
しばらく待ってデプロイが完了したら、「リソースに移動」をクリック。

「GitHubアクションの実行」をクリックすると、別タブで Azure Static Web Apps CI/CD のワークフローの進行状況が表示されるので、完了するまで待つ。

CIが通ったら、先ほどのAzureポータル画面で表示されたURLにアクセスすると、ローカルで動かしていた画面が開き、ちゃんと動作するはず!

お・わ・り。

タイトルとURLをコピーしました