This page covers Elm 0.18
Multiple modules
Our application is going to grow soon, so keeping things in one file will become hard to maintain quite fast.
Circular dependencies
Another issue we are likely to hit at some point will be circular dependencies. For example we might have:
- A
Main
module which has aPlayer
type on it. - A
View
module that imports thePlayer
type declared inMain
. Main
importingView
to render the view.
We now have a circular dependency:
Main --> View
View --> Main
How to break it?
In this case what we need to do is to move the Player
type out of Main
, somewhere it can be imported by both Main
and View
.
To deal with circular dependencies in Elm the easiest thing to do is to split your application into smaller modules. In this particular example we can create another module that can be imported by both Main
and View
. We will have three modules:
- Main
- View
- Models (contains the Player type)
Now the dependencies will be:
Main --> Models
View --> Models
There is no circular dependency anymore.
Try creating separate modules for things like messages, models, commands and utilities, which are modules that are usually imported by many components.
Let's break the application in smaller modules:
src/Messages.elm
module Messages exposing (..)
type Msg
= NoOp
src/Models.elm
module Models exposing (..)
type alias Model =
String
src/Update.elm
module Update exposing (..)
import Messages exposing (Msg(..))
import Models exposing (Model)
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
NoOp ->
( model, Cmd.none )
src/View.elm
module View exposing (..)
import Html exposing (Html, div, text)
import Messages exposing (Msg)
import Models exposing (Model)
view : Model -> Html Msg
view model =
div []
[ text model ]
src/Main.elm
module Main exposing (..)
import Html exposing (Html, div, text, program)
import Messages exposing (Msg)
import Models exposing (Model)
import Update exposing (update)
import View exposing (view)
init : ( Model, Cmd Msg )
init =
( "Hello", Cmd.none )
subscriptions : Model -> Sub Msg
subscriptions model =
Sub.none
-- MAIN
main : Program Never Model Msg
main =
program
{ init = init
, view = view
, update = update
, subscriptions = subscriptions
}
You can find the code here https://github.com/sporto/elm-tutorial-app/tree/018-03-multiple-modules
There are lots of little modules now, this is overkill for a trivial application. But for a bigger application splitting it makes it easier to work with.