Alchemyはシングルページアプリケーションを作るための実験的なコードジェネレータです。
The Elm Architectureはシングルページアプリケーションに適したシンプルでわかりやすいアーキテクチャですが、アプリケーションにページを追加するときには、退屈なボイラープレートをたくさん書く必要があります。たとえば、Mainモジュールで、インポート文を追加し、
You need to add import declarations, add data constructor to hold Msg
from child in parent Msg
, add routes in routing and so on. alchelmy try to generate those boilerplates automatically.
In PHP, to add a new page, all you need is adding a single Foo.php
in your project. In a like manner, in Alchelmy, all you need is adding only <PageName>.elm
and writing few codes in it. You don't need to tweak a lot of huge case-of
branches by hand any more.
In essense, the behavior of Alchelmy is very simple: alchelmy generates only one source file named Alchemly.elm
. This is the Elm codes that orchestrates Web pages written in Elm.
This project is highly experimental, so your comments or suggestions are welcome.
Please see example and the automatically generated Alchelmy.elm for more information. You can also check out the example app at the following url:
alchelmy isn't in NPM yet. You can use npm i aratama/alchelmy
to install alchelmy locally and npx alchelmy
to execute alchelmy from CLI. You can also run alchelmy via npx aratama/alchelmy
. You also need to install elm/browser
, elm/json
and elm/url
in your project dependencies in advance.
alchelmy has a command line interface:
alchelmy init <application>
will generatesrc/<Application>
directory and make some scaffolds.alchelmy update
will (re)generatesrc/<Application>/Alchemy.elm
.alchelmy new <page>
will generate a new page named<page>
.
$ npx alchelmy new <page>
たとえばコマンドnpx alchelmy new Hello
を実行すると、デフォルトではsrc/Page/Hello.elm
が作成されてページとして追加されます。
ページを削除するには、当該モジュールを削除します。
ページは各モジュールで次のようなデータ型Page
の値として定義されます。
type alias Page model msg route a =
{ init : Value -> Url -> Key -> route -> ( model, Cmd msg )
, view : model -> Document msg
, update : msg -> model -> ( model, Cmd msg )
, subscriptions : model -> Sub msg
, onUrlRequest : UrlRequest -> msg
, onUrlChange : Url -> route -> msg
, route : Parser (route -> a) a
, session : model -> Value
}
このPage
型はBrowser.applicationに渡す最初の引数と一部が共通していますが、いくつかプロパティが追加されています。route
プロパティはページごとのルーティングを行います。URLに対してこのroute
を使ったパースが成功すると、そのページへ遷移してinit
関数が呼ばれてページが初期化されます。
アプリケーションが起動された直後の最初に表示されるページでは、init
の最初の引数にはフラグが渡されます。他のページから遷移してきた場合は、他のページで生成されたセッション情報が渡されます。
各ページではこのPage
型を使ってページを型注釈を付けることが推奨されますので、何らかの共通モジュールを用意してそこにこのPage
を定義し、各ページから参照するといいでしょう。Alchelmy.elm
はこのPage
型を参照しないので、どこに記述しても構いません。
ページ間を遷移するには、pushUrl
コマンドを呼び出します。pushUrl
でURLを変更した場合、そのページのonUrlChange
メッセージが送信されて、状態の更新とコマンドの実行が行われます。ここまでは通常のアプリケーションと同様です。そのあと、そのURLに対してそのページのpage.route
でそのURLのパースを試みます。もしパースが成功すればページは遷移しません。それに対して、パースが失敗した場合は再度ルーティングが行われ、遷移先のページが選定され、遷移先のpage.init
が呼び出されてページが初期化されます。
ページの遷移が発生すると、まず遷移前のページのpage.session
を呼び出してセッション情報を取得します。そのセッション情報が遷移先のpage.init
へと渡されてページが初期化されます。
ページ間でのデータの受け渡しに使われるデータ型はJson.Encode.Value
であるため、JSONデータとして表現できないデータは遷移先のページへと引き継ぐことはできません。
Alchelmyは、各ページで共通のview
やupdate
などを提供しません。複数のページで共通の振る舞いが必要であれば、example
を参考にしてください。
通常、Alchelmy.program
を使用してアプリケーション全体を初期化しますが、Alchelmy.elm
はupdate
やview
などもエクスポートしており、これらを直接インポートしてアプリケーションを構成することもできます。
$ npm i
$ npm run build
- You can't specify order of precedence of routes. You should take care not to overlap routings.
There are some simillar projects: