Trying js_of_ocaml with dune, unable to find module

Dear Ocaml Discourse,

Context

I am a hobbiest programmer who is an Ocaml novice but quite familier using dune to build Coq projects. Whilst I mostly use Coq for theorem proving, I do sometimes want to use the extracted .ml code in other projects. Furthermore I would like to build a small html file which can act as a REPL for some for testing emitted ml routines (and possibly other functionality at a later date).

Question

I am currently in the process of learning how to use js_of_ocaml with dune.
I’m trying to get a minimal working example of the process of:

  1. Defining a simple function in a an Ocaml .ml file
  2. Wrapping said function using the JS module of Js_of_ocaml into an object.
  3. compiling said object to a .js so that can be ingested into html document.

As well as the dune documentation, I’m using this question as a guide to structure my test-project.

I can write simple Ocaml functions, as can I use dune to successfully call js_of_ocaml and emit Javascript code from ml via an executable stanza. However, for some reason I am unable to open the module Js_of_ocaml in any .ml source to construct a proper wrapper / API for my ml methods in the ensuing JavaScript. The build fails because dune fails to locate Js_of_ocaml:

output of dune build

File "test_js_of_ocaml/test_ml.ml", line 1, characters 5-16:
1 | open Js_of_ocaml
         ^^^^^^^^^^^
Error: Unbound module Js_of_ocaml

I feel like I am making a silly config error somewhere, but I cant find how to fix it using the sources I have so I am extending the question here.

I also have reduced my question down into a little test git repo that isolates the problem, which might be helpful to look into. However the problem should be fully explained here also.

I have an Opam switch active (and enabled via eval $(opam env)) containing coq, dune, and, js_of_ocaml.

the example dune project set out like follows:

Dune project structure


* /
├ dune-project
â”” * /test_js_of_ocaml
  ├ dune
  â”” test_ml.ml

test_ml.ml

open Js_of_ocaml (* errors out here *)

dune

(executable
(name test_ml)
 (modes js)
 )

The dune-project file is just the default one one gets from running dune init so I won’t include it here.


I have tried putting a (libraries Js_of_ocaml) field in various places in the dune configs to no avail.

I Think the problem I am encountering us just one of dune not finding js_of_ocaml, but everything I find on this matter tells me that my config should just work, and likewise the documentation does not include anything further to be put in the dune configs when running js_of_ocaml. Thusly I’m a little confused about what is going wrong here, and would appreciate some assistance!

Try this dune stanza:

(executable
  (name test_ml)
  (modes js)
  (libraries js_of_ocaml))

I think the issues here is that compiling bytecode to js using js_of_ocaml (“jsoo”) compiling a program that depends on the Js_of_ocaml library are distinct. The dune docs on compiling with jsoo don’t cover the case of using the jsoo library as a dependency in a component. It’s possible that should be added as a special note there, but maybe its also reasonable to expect most people to know how to depend on libraries by the time they get to compiling for different targets? Not sure :slight_smile:

1 Like

Thanks for the explanation,

I did try doing that before I asked the question but still received errors, which I can only assume is down to me mistyping the libraries field or me misreading the output of the dune build operation and glossing over the fact that the error had changed to a error due to unused module.

Either way with copying-in your correct stanza setting up an env stanza in my dune-workspace to allow warning 33 allows me to now correctly load the module and I can proceed with my project.

Many thanks!


p.s. In fact looking at my original post it looks like I had capitalized the j js_of_ocaml and had not noticed. What a silly error of me. - thanks again!

1 Like

Yep, I noticed that! It’s not such a silly mistake, since the module name is upper case :slight_smile: These kinds of fiddly details and discrepancies are easy to stumble over in a new domain.

I think you’ve identified a hole in the documentation that would be useful to plug too.

1 Like