2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AWS AmplifyとAWS×フロントエンド #AWSAmplifyJPAdvent Calendar 2023

Day 14

フロントエンドにElmを使ったアプリをAmplify Hostingで配信する

Last updated at Posted at 2023-12-18

AmplifyのおかげでWebアプリを爆速でデプロイ&公開できるようになりましたが、フロントエンドにElmを使った例が意外と少ないような気がします。
というわけで設定の仕方を共有したいと思います。

ざっくりとした手順

  1. ローカルの開発環境で作業:npmやyarnでビルドできる環境を作る
  2. AmplifyのWebコンソールで作業:「アプリの設定: ビルドの設定」→「アプリケーション構築の仕様」でAmplify上でのデプロイを設定
  3. AmplifyのWebコンソールで作業:「アプリの設定: リライトとリダイレクト」でSPA(Single Page Application)向けの設定を追加

ローカルの開発環境で作業:npmやyarnでビルドできる環境を作る

ここではyarnを使う想定で書きます。
フロントエンドをElmで構築したアプリをビルドするにはparcelがすごく便利です。

yarn add -D parcel

parcelを使うと、HTMLから直接Elmファイルを参照する書き方ができます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8"/>
    <title>フロントエンドにElmを使ったアプリをAmplify Hostingで配信する</title>
</head>
<body>
    <script src="./Index.elm"></script>
</body>
</html>

ただ、これだとElmプログラムにaws-exports.jsの内容を渡すことが出来ません。
なので、次のようにスクリプトを書きます。

<!DOCTYPE html>
<html>
<head>
    <meta charset="UTF-8" />
    <title>フロントエンドにElmを使ったアプリをAmplify Hostingで配信する</title>
</head>
<body>
    <main id="main">
        <p>loading...</p>
    </main>
    <script type="module">
        import awsExports from "./aws-exports";
        import { Elm } from "./Index.elm";
        Elm.Index.init({
            node: document.getElementById("main"),
            flags: {
                awsExports
            }
        });
    </script>
</body>
</html>

HTMLファイルに直接スクリプトを書くのはカッコ悪い気もしますが、配信には有利かもしれません。

Index.elmのサンプルも載せておきます。

module Index exposing (..)

import Browser
import Html exposing (..)
import Html.Events exposing (..)


main : Program () Model Msg
main =
    Browser.sandbox { init = 0, update = update, view = view }


type alias Model =
    Int


type Msg
    = Increment
    | Decrement


update : Msg -> Model -> Model
update msg model =
    case msg of
        Increment ->
            model + 1

        Decrement ->
            model - 1


view : Model -> Html Msg
view model =
    div []
        [ button [ onClick Decrement ] [ text "-" ]
        , div [] [ text (String.fromInt model) ]
        , button [ onClick Increment ] [ text "+" ]
        ]

これで最低限のアプリが出来ました。
起動するには以下のコマンドです。

npx parcel src/index.html

起動するとparcelは参照をたどって適切にビルドして、成果物をdistディレクトリに格納してくれます。

image.png

また、ビルドは以下のコマンドです。

npx parcel build src/index.html

ビルドの成果物は起動時と同じくdistディレクトリに格納してくれます。

package.jsonにbuildというスクリプトで上記コマンドを登録しておきましょう。

  "scripts": {
    "build": "npx parcel build src/index.html"
  },

AmplifyのWebコンソールで作業:「アプリの設定: ビルドの設定」→「アプリケーション構築の仕様」でAmplify上でのデプロイを設定

さて、Hostingの設定は終わっている前提で、Amplify上でのビルドを設定します。

yarn run buildでビルドを実行して、distディレクトリからコンテンツを配信するように設定することになります。
以下の場所で編集します。
image.png

編集後のYAMLファイルは以下のようになります。

version: 1
backend:
  phases:
    build:
      commands:
        - '# Execute Amplify CLI with the helper script'
        - amplifyPush --simple
frontend:
  phases:
    preBuild:
      commands:
        - yarn install
    build:
      commands:
        - yarn run build
  artifacts:
    # IMPORTANT - Please verify your build output directory
    baseDirectory: dist
    files:
      - '**/*'
  cache:
    paths:
      - node_modules/**/*

以下3つの設定値を書き換えました。

frontend > phases > preBuild > commands
frontend > phases > build > commands
frontend > artifacts > baseDirectory

これでビルドの設定は完了です。

AmplifyのWebコンソールで作業:「アプリの設定: リライトとリダイレクト」でSPA向けの設定を追加

Elmの構成によってはこの手順は不要かもしれませんが、SPAとして動作させることを念頭に、あらゆるURLへのリクエストをindex.htmlで受けるような設定を加えます。

以下の場所で設定します。
image.png

  • 送信元アドレス:</^[^.]+$|\.(?!(css|gif|ico|jpg|jpeg|js|png|txt|svg|woff|woff2|ttf|map|json|webp)$)([^.]+$)/>
  • ターゲットアドレス:/index.html
  • 入力:200(リライト)

これでElmで構築したWebアプリをAmplifyで配信することが出来るようになりました!

2
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?