elm-pages/docs/7.0.0-elm-package-upgrade-guide.md
2020-10-26 13:10:00 -07:00

7.8 KiB

7.0.0 Elm package upgrade guide

Please ensure that you're on the latest elm-pages version of both the Elm package and the NPM package before following these steps.

There are two new beta features, which you can opt into by running a different build command (see 2) or calling a new generated function (see 3).

There are 3 broad areas of change in this release.

  1. Breaking API changes
  2. Beta build command
  3. Beta Template Modules feature

You can ignore (2) and (3) if you aren't interested in beta features. And even if you do choose to try these beta features, I recommend starting with (1) and getting things compiling without using any beta features first.

1 - Breaking API changes

Manifest.Config now has icons

  • The icons field in the manifest config will only be used for the beta, no-webpack build (see section 2). If you aren't using it, you can simply pass in an empty list for icons. The new field in the Manifest.Config has this type icons : List.List (Pages.Manifest.Icon pathKey).
  • Program model msg metadata view changed to Program model msg metadata view pathKey. That means there is a new type variable in Pages.Platform.Program. You can fix this by adding Pages.PathKey (a type defined in the generated Pages.elm module) as the last type variable wherever you had an annotation using the Pages.Platform.Program type.

The following functions in Pages.Platform.init have also changed:

            , onPageChange :
                  Maybe
                      (
                      { path : PagePath pathKey
                      , query : Maybe String
                      , fragment : Maybe String
                      }
                      -> msg
                      )
            , onPageChange :
                  Maybe.Maybe
                      (
                      { path : Pages.PagePath.PagePath pathKey
                      , query : Maybe.Maybe String.String
                      , fragment : Maybe.Maybe String.String
                      , metadata : metadata
                      }
                      -> msg
                      )
            , init :
                  Maybe
                      { path : PagePath pathKey
                      , query : Maybe String
                      , fragment : Maybe String
                      }
                  -> ( model, Cmd msg )
            , init :
                  Maybe.Maybe
                      { path :
                            { path : Pages.PagePath.PagePath pathKey
                            , query : Maybe.Maybe String.String
                            , fragment : Maybe.Maybe String.String
                            }
                      , metadata : metadata
                      }
                  -> ( model, Platform.Cmd.Cmd msg )
            , subscriptions : model -> Sub msg
            , subscriptions :
                  metadata
                  -> Pages.PagePath.PagePath pathKey
                  -> model
                  -> Platform.Sub.Sub msg

2 - Beta build command

You can run the regular build command and the beta build command side by side, and have the beta entrypoints living next to the current JS entrypoint you have (index.js). Hopefully that makes it easy to try out the beta and experiment with it without needing to change over right away.

  • elm-pages build and elm-pages develop use the index.js entrypoint.
  • A new command, elm-pages-beta (doesn't take any arguments) uses the beta-index.js and beta-style.css entrypoints.

Note that before you would use webpack to import CSS from the JS entrypoint (or something that was imported from there). Now there are separate entrypoints for JS and CSS.

Some key points about the no-webpack build:

---- Head - MINOR ----

Added:
    appleTouchIcon :
        Maybe.Maybe Basics.Int
        -> Pages.ImagePath.ImagePath pathKey
        -> Head.Tag pathKey
    icon :
        List.List ( Basics.Int, Basics.Int )
        -> MimeType.MimeImage
        -> Pages.ImagePath.ImagePath pathKey
        -> Head.Tag pathKey

3 - Beta Template Modules feature

Pre conditions to using template modules

  • Instead of using Pages.Platform.init directly, start building your app with TemplateModulesBeta.mainTemplate, see an example here: 3aa978578b/examples/docs/src/Main.elm (L61)
  • You must have a module called Shared.elm, like this example: dfa71340a2/examples/docs/src/Shared.elm. That module must expose a template value. You must also expose the following types from Shared:
    • RenderedBody -
    • SharedMsg - a union of all the Msg's that can be sent from a Template Module and handled by Shared to update the shared state.
    • Msg - the Shared Msg type for events that can happen and be received by the Shared module.
    • Model - the Shared module, which can also be accessed by Template Modules if the wire that in with the Template.elm builder functions to access that state.
  • You must have a module called TemplateType, which exposes a custom type called TemplateType.TemplateType, with a variant for each of your Template Modules (files in the src/Template folder) with a corresponding variant name. The variant must have exactly 1 argument, which is the metadata type for that Template. See this example: dd3f824e4e/examples/docs/src/TemplateType.elm (L6)
  • You must have at least 1 template module (see Generating a Template Module).

Generating a Template Module

Template modules live in the src/Template directory.

  • You can add a new Template Module using elm-pages-generate Recipe
  • The gen/Template.elm module provides a builder-style API for each Template. You can add complexity as needed, starting from the generated starting point.
  • Each module must expose a value called template, and a type called Msg and Model (they can be () and Never if you don't use them, as in the scaffolded code).
  • You can see the Elm docs for the generated gen/Template.elm module if you install elm-doc-preveiw (npm i -g elm-doc-preview), copy this file to your project, and run elm-doc-preview from the top-level folder.