This example shares a toy function between client and server using Melange. The function is in common/common.re:
let greet = fun
| `Server => "Hello..."
| `Client => "...world!";The server, in server/server.eml.re, prints the first part of the message:
let home = {
<html>
<body>
<p><%s Common.greet(`Server) %></p>
<script src="/static/client.js"></script>
</body>
</html>
};
let () =
Dream.run
@@ Dream.logger
@@ Dream.router([
Dream.get("/",
(_ => Dream.html(home))),
Dream.get("/static/**",
Dream.static("./static")),
]);...and the client, in client/client.re, completes it!
open Webapi.Dom;
let () = {
let body = document |> Document.querySelector("body");
switch (body) {
| None => ()
| Some(body) =>
let text = Common.greet(`Client);
let p = document |> Document.createElement("p");
Element.setInnerText(p, text);
body |> Element.appendChild(p);
}
};To run, do
$ cd example/w-fullstack-melange
$ opam install --deps-only --yes .
$ npm install esbuild --no-save
$ dune build --root . @melange
$ mkdir -p static
$ npx esbuild _build/default/client/client/client/client.js --bundle --outfile=static/client.js
$ dune exec --root . server/server.exe
Then visit http://localhost:8080, and you will see...
As a footnote, it is also possible to write both the server and client in this example in OCaml syntax.
See also:
w-watchsets up a development watcher.w-one-binarybundles assets into a self-contained binary.7-templatediscusses the templater, including security. The example is in OCaml syntax.r-templatethe code of the template example in Reason syntax.
