3.2 KiB
A tool to generate HTML code from Elm source in the terminal using QuickJS.
Requirements
- depends only on elm compiler, quickjs cli and a posix shell
- do not alter elm compiler
- do not alter quickjs cli
- do not patch elm compiler output
- provide acceptable performances (500ms for a big script)
Design
QuickJS (Qjs) is a JavaScript runtime, similar to V8 or SpiderMonkey, but lighter and faster.
As any runtime, Qjs can interpret JavaScript code, but it is not a web browser. It has no concept of an HTML document.
To bridge this gap, we add a minimal DOM implementation.
Next, we concatenate this with the Elm JavaScript output and an app launcher snippet, then ask Qjs to interpret all of it.
Limitations
- No event loop
- Hence, no TEA; no
updatecan be triggered - Hence, no Time, no Random, no Http
- Nodes can only have one parent (this should always be the case)
- Does not scale well : creating thousands of Nodes consumes a lot of RAM
Usage
- Clone this repository and navigate into your local copy
- Run
elm init. - Create
src/Hello.elmwith the following content:
module Hello exposing(main)
import Html exposing (text)
main = text "Hello World!"
- Run
./elmscript.sh src/Hello.elm
This produces the expected output:
Hello World!
passing input
Input content can be passed to the script via the standard input. The content is then passed to the Elm script as "flags". The script must then use Browser.element and implement init flags function.
Create src/Greet.elm with the following content:
module Greet exposing (main)
import Browser
import Html exposing (text)
main =
Browser.element
{ init = \f -> (f, Cmd.none)
, update = \m _ -> (m, Cmd.none)
, view = \m -> text ("hello " ++ m)
, subscriptions = always Sub.none
}
Run ./elmscript.sh src/Greet.elm <<< 'Elm'
This produces the expected output: hello Elm.
I's even more natural when passing file :
- run
elm install elm-explorations/markdown - create
src/MdRender.elmwith the following content:
module MdRender exposing (main)
import Browser
import Html.Attributes exposing (class)
import Markdown
main =
Browser.element
{ init = \s -> (s, Cmd.none)
, update = \m c -> (m, Cmd.none)
, view = \m -> Markdown.toHtml [class "content"] m
, subscriptions = always Sub.none
}
- run
./elmscript.sh src/MdRender.elm < README.md > README.html
Performances
Acceptable for small scripts : 250ms on a modest x86_64 CPU and 64MB RAM for a 500 records into a table ; but is does not scale well as everything is loaded before processing ; no streaming contrary to the usual Unix way.
Generate 500k "li" loop took 17s and 900MB RAM.
Prior Work
There are more complete tools for generating static sites with Elm:
You should probably consider using one of them instead of this one. :)