type holyshared = Engineer<mixed>

技術的なことなど色々

js_of_ocamlをjbuilder(dune)で試してみた

OCamlバイトコードをJSに変換できるツール、js_of_ocamlを試して見ました。
とりあえず、jbuilder(dune)を使用して、JSを出力できるようにはなりました。
今回はビルドの方法だけの内容です。

必要なもの

opam経由で必要なパッケージをインストールします。
必要なパッケージは下記の通りです。
インストールされたバージョンは最新の3.1.0です。

opam install -y js_of_ocaml js_of_ocaml-ppx

jbuildファイルを用意する

ruleに出力するファイルの設定を追加します。
js_of_ocamlのオプションに--source-mapを追加して、ソースマップを出力するようにしています。

また、aliasにDEFAULTを追加して、依存しているファイルも用意するようにしています。
jbuildファイルがあるディレクトリをベースにindex.html、main.jsをコピーします。

(jbuild_version 1)

(executables (
  (names (main))
  (preprocess (pps (js_of_ocaml-ppx)))
))

(rule (
  (targets (main.js))
  (action
    (run ${bin:js_of_ocaml} --source-map ${path:main.bc} -o ${@} --pretty)
  )
))

(alias (
  (name DEFAULT)
  (deps (main.js index.html))
))

index.htmlの用意

main.jsのファイルを読み込む適当なHTMLファイルを用意します。

<!doctype html>
<html>
  <head>
    <title>example</title>
    <script src="main.js"></script>
  </head>
  <body>
  </body>
</html>

main.mlの用意

コードは簡単なものにして、デバッグしやすくします。
このコードは、DOMContentLoadedイベントにイベントハンドラを追加して、デバッグログを出力するだけのコードです。

open Js_of_ocaml

module Html = Dom_html

let document = Html.window##.document
let addEventListener = Dom.addEventListener
let domContentLoaded = Dom_events.Typ.domContentLoaded

let debug f = Printf.ksprintf (fun s -> Firebug.console##log (Js.string s)) f

(* DOMContentLoadedのイベントハンドラ *)
let dom_content_loaded evt =
  debug "debug: %s" "domContentLoaded!!";
  Js.bool true

let () =
  let event_handler = Dom.handler dom_content_loaded in
  ignore (addEventListener document domContentLoaded event_handler (Js.bool false))

Makefileを用意する

とりあえず、ビルドと成果物のクリーンアップをできるようにします。
jbuildのaliasにDEFAULTを指定しているので、@DEFAULTをコマンドの引数に追加するだけで、ビルドできます。

all:
    jbuilder build @DEFAULT

clean:
    jbuilder clean

JSのビルド

ビルドはmakeコマンドを実行するだけです。
__build/default の配下に出力されたJSファイル、index.htmlコピーがあるはずです。
index.htmlファイルをブラウザで開いて、コンソールにデバッグメッセージが出力されていればOKです。

make