60
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

ElmAdvent Calendar 2018

Day 2

Elm 0.19 の初期化方法 6 種類

Last updated at Posted at 2018-12-02

2019 年 Elm をはじめる人が次に読むページです。
(いえ、どこから読んでも良いです)

この記事では Elm 0.19 のプログラム初期化の方法を紹介します。
(Elm コードの書き方は紹介しません)

出力は HTML と JS の2種類

HTML を出力(デフォルトは index.html)。

elm make src/Main.elm

ただしこの方法では CSS ファイルへのリンクやメタ情報を埋め込むことができないので、大抵は次のようにして JS を吐き出して HTML から呼び出します。

elm make src/Main.elm --output=elm.js
<!DOCTYPE html>
<html>
<head>
    <script src="elm.js"></script>
    <title>Elm App</title>
</head>
<body>
    <script>
        Elm.Main.init();
    </script>
</body>
</html>

Node.js 環境ではこんな感じ。

const { Elm } = require("./elm.js");

静的な HTML

main に直接 HTML を書きなぐれます。

module Main exposing(main)

main : Html msg
main = a [ href "https://elm-lang.org/" ] [ text "Elm" ] 
Elm.Main.init({ node: document.getElementById("elm-node") });

Browser.*

Elm 0.19 では main を Browser モジュールを使って書きます。0.18 以前では Html.program とか書いてありますが捨ててください。
詳しくは公式ガイドとパッケージのドキュメントを見てください。

Browser.sandbox

HTTP などを使わない簡単なプログラムを作ります。

sandbox :
    { init : model
    , view : model -> Html msg
    , update : msg -> model -> model
    }
    -> Program () model msg

HTML から呼び出す場合にはノードに埋め込んで使います。

Elm.Main.init({
  node: document.getElementById("elm-node")
});

Browser.element

HTTP など副作用のある処理がある(ほとんど)場合はこちらを使います。

element :
    { init : flags -> ( model, Cmd msg )
    , view : model -> Html msg
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    }
    -> Program flags model msg

HTML から呼び出す場合にはノードに埋め込んで使います。

Elm.Main.init({
  node: document.getElementById("elm-node")
});

Flags や Ports の機能を使うと Elm <=> JS 間でデータのやりとりができます

var app = Elm.Main.init({
  node: document.getElementById("elm-node"),
  // フラグを渡す
  flags: { initializedAt : Date.now() },
});
// Elm から値を受け取る
app.ports.ping.subscribe(function (text) {
    // Elm に値を返す
    app.ports.pong.send(text);
});

Browser.document

element とほとんど同じですがタイトルを動的に切り替えることができます。

document :
    { init : flags -> ( model, Cmd msg )
    , view : model -> Document msg
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    }
    -> Program flags model msg

type alias Document msg =
    { title : String
    , body : List (Html msg)
    }

HTML から呼び出す場合は画面いっぱいに表示します。埋め込みはできません

Elm.Main.init();

Flags と Port はもちろん使えます。

Browser.application

最終進化形です。 組み込みの SPA ルーティング機能が使えます

application :
    { init : flags -> Url -> Key -> ( model, Cmd msg )
    , view : model -> Document msg
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    , onUrlRequest : UrlRequest -> msg
    , onUrlChange : Url -> msg
    }
    -> Program flags model msg

HTML から呼び出す場合は画面いっぱいに表示します。埋め込みはできません

Elm.Main.init();

Flags と Port はもちろん使えます。

注意点としては、埋め込み(element)+組み込みの SPA ルーティング機能を使うことはできません。理由と対策についてはこちらを見てください。

Platform.worker

画面なしのプログラムです。Node.js での使用が想定されています。

worker :
    { init : flags -> ( model, Cmd msg )
    , update : msg -> model -> ( model, Cmd msg )
    , subscriptions : model -> Sub msg
    }
    -> Program flags model msg
const { Elm } = require("./elm.js");
const app = Elm.Main.init({
  flags: { initializedAt : Date.now() },
});
app.ports.pong.subscribe(function (text) {
    console.log(text);
});
app.ports.ping.send(text);

worker は elm-test などで使われています。
(追記)Node.js で使えるとはいえ、実用できるのはせいぜい小さなツール程度です。プロダクションのサーバーサイドなどガチ用途で使うのは絶対にやめてくださいね!

まとめ

Elm でどんな初期化ができるのかをざっと紹介しました。
もりもりアプリを作っていきましょう。

60
23
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
60
23

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?