A few years ago, while picking up basic OCaml, I found this site by Andrew Ray: https://andrewray.github.io/iocamljs/full402.html . This page has in-browser OCaml notebook. I was trying to modernise it and compile with OCaml 4.06.1. The vital part of the page is an ability to evaluate OCaml at run time in Javascript inside your browser. This is done by Js_of_ocaml. Learn basics of Js_of_ocaml in this post.
Let’s do tradition “hello world” exercise, create a new file hello.ml
:
let () =
let oneArgument (a: int) = a + 100 in
Js.Unsafe.global##.jsOneArgument := Js.wrap_callback oneArgument;
(* This will go to console.log *)
print_string "Hello from Js_of_ocaml!\n";
This file does 2 things: 1) Update the global scope and inject a new function jsOneArgument which returns input + 100
; 2) print the string Hello from Js_of_ocaml!
Now compile it into byte-code file (one line):
ocamlfind ocamlc -g -o hello.byte -linkpkg -package js_of_ocaml,js_of_ocaml-ppx hello.ml
Notice the usage of PPX for syntax enrichment here. The byte-code file hello.byte
won’t give you much fun. Here we compiled it with debug flag -g
which gives large output size of 1,313,781 bytes
. Let’s try running it and see what happens:
$ ./hello.byte
Unimplemented Javascript primitive caml_pure_js_expr!
Nothing to see here, move on to compilation of the byte-code file into a Javascript target:
js_of_ocaml -o hello.js hello.byte
Now you need to create an HTML file to witness the miracle:
<?xml version="1.0" encoding="utf-8"?>
<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN"
"http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">
<html xmlns="http://www.w3.org/1999/xhtml">
<head>
<title>Js_of_ocaml - Hello</title>
<script type="text/javascript" src="hello.js"></script>
</head>
<body>
</body>
</html>
Open in your browser and then JS console (F12 for Chrome), you will see the expected string in console.log
:
Hello from Js_of_ocaml!
Now you can type in console to see if the function jsOneArgument was injected:
jsOneArgument(1)
> 101
Voila! So we have successfully compiled a OCaml file into Javascript! Learn more from https://ocsigen.org/js_of_ocaml/3.1.0/manual/overview and https://github.com/ocsigen/js_of_ocaml/tree/master/examples .