Previously I used
elm-static-html static-html-from-elm for this, but in combination with
Html.Styled from elm-css the output was not exactly the same as when running the Elm code in a browser and there were encoding problems. Hence, why not use a browser to generate the static HTML?
We can do this using Selenium.
First, we make an HTML file which works in your local browser, say
render.html: See also the Elm guide about Embedding in HTML.
Second, we use Selenium to control a “headless”, i.e. invisible, Chrome to open the HTML file, run the Elm script and print out the innerHTML. For example, save the following as
from os import getcwd from selenium import webdriver options = webdriver.ChromeOptions() options.headless = True driver = webdriver.Chrome(options=options) url = "file://" + getcwd() + "/render.html" driver.get(url) divContent = driver.find_element_by_id('MyApp').get_attribute('innerHTML') driver.quit() print(divContent)
Finally, the following
Makefile will build the
.static.html files. For
.min.js we follow the Elm guide about minification.
all: MyApp.js: src/*.elm elm make --optimize --output=$@ MyApp.min.js: MyApp.js uglifyjs $< --compress \ 'pure_funcs="F2,F3,F4,F5,F6,F7,F8,F9,A2,A3,A4,A5,A6,A7,A8,A9",pure_getters,keep_fargs=false,unsafe_comps,unsafe' \ | uglifyjs --mangle --output=$@ MyApp.static.html: render.html MyApp.min.js python3 static-via-selenium.py > $@
You can now use the content of
MyApp.static.html as a static replacement by putting it inside the
<div id="MyApp"></div> in
index.html. We leave it as an exercise for the reader to also automate this last step.