Search code examples
elmelm-reactor

Using elm-reactor with Elm embedded in HTML?


So I'm trying out Elm and WebRTC together. However for WebRTC I need some interop to javascript. So I created an index.html with the needed script includes, for both WebRTC and main.js.

However, I am using elm-reactor. Which is super nice. But there is no main.js. I can create it with elm-make, but then I would have to manually update it.

So, is there a way to have elm-reactor work together with embedded elm?

Note: I'm using Elm 0.18, latest as of writing.


Solution

  • If you're willing to hack a bit, it's perfectly possible to use your own index.html with elm reactor. Just put the following in an index.html file and open it in reactor (e.g. http://localhost:8000/src/index.html):

    <html>
    
    <head>
      <meta charset="UTF-8">
      <title>Title</title>
      <link rel="stylesheet" href="styles.css"><!-- Put your styles in folder with index.html -->
    </head>
    
    <body>
      <div style="width: 100%; height: 100%; display: flex; flex-direction: column; justify-content: center; align-items: center; color: #9A9A9A; font-family: &#39;Source Sans Pro&#39;;">
        <div style="font-size: 3em;">Building your project!</div>
        <img src="/_reactor/waiting.gif">
        <div style="font-size: 1em">With new projects, I need a bunch of extra time to download packages.</div>
      </div>
    </body>
    
    <!-- Fonts and external JS and styles are available, I've put Ace for example -->
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.4/ace.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.4/theme-chrome.js"></script>
    <script type="text/javascript" src="https://cdnjs.cloudflare.com/ajax/libs/ace/1.2.4/worker-lua.js"></script>
    
    <!-- Put the name of your app here (my sources place in `src` forder) -->
    <script type="text/javascript" src="/_compile/src/YourApp.elm"></script>
    
    <!-- Removes splash and starts elm app. -->
    <script type="text/javascript">
    while (document.body.firstChild) {
      document.body.removeChild(document.body.firstChild);
    }
    runElmProgram();
    </script>
    
    </html>
    

    If you want to use ports or flags, use the following example (you need Elm.App.fullscreen(flags) etc to use ports, but runElmProgram() to show errors):

    <!doctype html>
    <meta charset=utf-8>
    <title>a title</title>
    <link href=/bundle.css rel=stylesheet>
    <body></body>
    <script src="/_compile/Main.elm"></script> <!-- this will fail in production -->
    <script src="/elm-bundle.js"></script> <!-- this will fail in development -->
    <script>
    var app
    var flags = {}
    
    try {
      app = Elm.App.fullscreen(flags)
    
      /* app.ports is now available */
    } catch (e) {
      // this will run in case there are compile errors:
      var stylesheets = document.querySelectorAll('link')
      for (var i = 0; i < stylesheets.length; i++) {
        stylesheets[i].parentNode.removeChild(stylesheets[i])
      }
      runElmProgram()
    }
    </script>