Skip to content

Instantly share code, notes, and snippets.

@danneu
Last active May 9, 2022 06:17
Show Gist options
  • Save danneu/77d9000d390098064cc30f66353a5562 to your computer and use it in GitHub Desktop.
Save danneu/77d9000d390098064cc30f66353a5562 to your computer and use it in GitHub Desktop.
Elm quickstart with Parcel

Elm quickstart with Parcel

Create project boilerplate:

mkdir my-elm-project
cd my-elm-project
elm init
touch src/Main.elm # This is where we put our Elm app

echo '{}' > package.json # Empty package.json to install NPM libs

npm install -g parcel # Or install project-locally with `npm install --save-dev parcel`

touch example.scss # Just to show that Parcel automatically handles things like .scss
touch index.html
touch index.js

npm install uuid # Let's use an NPM library for demonstration

Project structure so far:

.
├── elm.json
├── example.scss
├── index.html
├── index.js
├── package.json
└── src
    └── Main.elm

Save Elm boilerplate to src/Main.elm: (See attached 1-Main.elm file)

Save this to index.html:

<!DOCTYPE html>
<head>
  <link rel="stylesheet" href="./example.scss" />
</head>
<body>
  <main></main>
  <script type="module" src="index.js"></script>
</body>

Inside index.js we mount our Elm app to <main> and can import NPM libraries and use them:

// index.js
import { Elm } from './src/Main.elm'
import * as uuid from 'uuid'

const app = Elm.Main.init({
  node: document.querySelector('main'),
  flags: {
    // Example of using npm library to pass value into Elm via flag
    initDraft: uuid.v4()
  }
})

Use parcel to run dev server:

parcel index.html
# Navigate browser to http://localhost:1234

(Or use npx parcel index.html if you installed parcel locally with npm install --save-dev parcel. npx uses the parcel binary found in your project's ./node_modules/.bin since it otherwise isn't in your $PATH.)

When you're ready for a production build:

parcel build index.html
# Creates ./dist folder with html, js, css files

Parcel docs: https://parceljs.org/getting-started/webapp/

module Main exposing (main)
import Browser
import Html exposing (..)
import Html.Attributes exposing (..)
import Html.Events exposing (..)
type alias Model =
{ draft : String
}
type alias Flags =
{ initDraft : String }
init : Flags -> ( Model, Cmd Msg )
init flags =
( { draft = flags.initDraft
}
, Cmd.none
)
type Msg
= DraftChanged String
update : Msg -> Model -> ( Model, Cmd Msg )
update msg model =
case msg of
DraftChanged value ->
( { model | draft = value }
, Cmd.none
)
view : Model -> Html Msg
view model =
div []
[ textarea
[ onInput DraftChanged ]
[ text model.draft ]
]
main : Program Flags Model Msg
main =
Browser.element
{ init = init
, view = view
, update = update
, subscriptions = \_ -> Sub.none
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment