diff --git a/doc/changes/12464.md b/doc/changes/12464.md new file mode 100644 index 00000000000..c23a8ec33ad --- /dev/null +++ b/doc/changes/12464.md @@ -0,0 +1,2 @@ +- melange support: don't emit empty JavaScript modules for generated module + aliases. (#12464, @anmonteiro) diff --git a/src/dune_rules/melange/melange_rules.ml b/src/dune_rules/melange/melange_rules.ml index bbd98d0246e..d16616471bd 100644 --- a/src/dune_rules/melange/melange_rules.ml +++ b/src/dune_rules/melange/melange_rules.ml @@ -127,9 +127,14 @@ let impl_only_modules_defined_in_this_lib ~sctx ~scope lib = ] | true -> () in - ( modules - , (Modules.With_vlib.split_by_lib modules).impl - |> List.filter ~f:(Module.has ~ml_kind:Impl) ) + let impl_only = + Modules.With_vlib.fold_no_vlib_with_aliases + modules + ~init:[] + ~normal:(fun m acc -> if Module.has m ~ml_kind:Impl then m :: acc else acc) + ~alias:(fun _m acc -> acc) + in + modules, impl_only ;; let cmj_includes = @@ -183,13 +188,15 @@ let compile_info ~scope (mel : Melange_stanzas.Emit.t) = let js_targets_of_modules modules ~module_systems ~output = List.map module_systems ~f:(fun (_, js_ext) -> modules - |> Modules.With_vlib.drop_vlib - |> Modules.fold_user_available ~init:Path.Set.empty ~f:(fun m acc -> - if Module.has m ~ml_kind:Impl - then ( - let target = Path.build @@ make_js_name ~js_ext ~output m in - Path.Set.add acc target) - else acc)) + |> Modules.With_vlib.fold_no_vlib_with_aliases + ~init:Path.Set.empty + ~alias:(fun _m acc -> acc) + ~normal:(fun m acc -> + if Module.has m ~ml_kind:Impl + then ( + let target = Path.build @@ make_js_name ~js_ext ~output m in + Path.Set.add acc target) + else acc)) |> Path.Set.union_all ;; diff --git a/test/blackbox-tests/test-cases/melange/emit-private.t b/test/blackbox-tests/test-cases/melange/emit-private.t index d71b031e501..db5c78a4147 100644 --- a/test/blackbox-tests/test-cases/melange/emit-private.t +++ b/test/blackbox-tests/test-cases/melange/emit-private.t @@ -47,7 +47,6 @@ Test dependency on a private library in the same package as melange.emit > EOF $ OCAMLPATH=$PWD/prefix/lib/:$OCAMLPATH dune build @dist --display=short 2>&1 | grep -v melange - melc b/dist/node_modules/pkg.__private__.a/a.js melc b/dist/node_modules/pkg.__private__.a/foo.js melc b/dist/b/bar.js diff --git a/test/blackbox-tests/test-cases/melange/empty-aliases-file.t b/test/blackbox-tests/test-cases/melange/empty-aliases-file.t new file mode 100644 index 00000000000..7f6d33f0572 --- /dev/null +++ b/test/blackbox-tests/test-cases/melange/empty-aliases-file.t @@ -0,0 +1,129 @@ + + $ mkdir lib + $ cat > dune-project < (lang dune 3.20) + > (package (name foo)) + > (using melange 1.0) + > EOF + + $ cat > lib/dune < (library + > (name foo) + > (modes melange)) + > EOF + $ cat > lib/bar.ml < let greeting = "hello" + > EOF + + $ cat > dune < (melange.emit + > (target dist) + > (libraries foo) + > (emit_stdlib false) + > (modules)) + > EOF + $ cat > lib/bar.ml < let greeting = "hello" + > EOF + + $ dune build @melange + +No `.js` file present for the library alias `foo.js` + + $ find _build/default/dist/lib -type f | sort + _build/default/dist/lib/bar.js + +Now write a foo.ml file + + $ cat > lib/dune < (library + > (name foo) + > (modes melange)) + > EOF + $ cat > lib/foo.ml < module Bar = Bar + > let x = "foo" + > EOF + + $ dune build @melange + +`foo.js` was manually written, therefore it's present + + $ find _build/default/dist/ -type f | sort + _build/default/dist/lib/bar.js + _build/default/dist/lib/foo.js + $ cat _build/default/dist/lib/foo.js + // Generated by Melange + 'use strict'; + + + const x = "foo"; + + module.exports = { + x, + } + /* No side effect */ + +`(include_subdirs qualified)` + + $ mkdir lib/sub + $ cat > lib/dune < (include_subdirs qualified) + > (library + > (name foo) + > (modes melange)) + > EOF + $ cat > lib/bar.ml < let hello = Sub.Hello.hello + > EOF + $ cat > lib/sub/hello.ml < let hello = "hello from sub" + > EOF + $ cat > lib/foo.ml < module Bar = Bar + > let x = "foo" + > EOF + + $ dune build @melange + +`foo.js` was manually written, therefore it's present. `sub.js` is an alias +file, and it's not present + + $ find _build/default/dist/lib -type f | sort + _build/default/dist/lib/bar.js + _build/default/dist/lib/foo.js + _build/default/dist/lib/sub/hello.js + + $ cat > lib/dune < (include_subdirs qualified) + > (library + > (name foo) + > (modes melange)) + > EOF + $ cat > lib/bar.ml < let hello = Sub.Hello.hello ^ Sub.world + > EOF + $ cat > lib/sub/sub.ml < module Hello = Hello + > let world = "world" + > EOF + $ cat > lib/sub/hello.ml < let hello = "hello from sub" + > EOF + $ cat > lib/foo.ml < module Bar = Bar + > let x = "foo" + > EOF + + $ DUNE_SANDBOX=none dune build @melange + +`foo.js` was manually written, therefore it's present. `sub.js` is an alias +file, and it's not present + + $ find _build/default/dist/lib -type f | sort + _build/default/dist/lib/bar.js + _build/default/dist/lib/foo.js + _build/default/dist/lib/sub/hello.js + _build/default/dist/lib/sub/sub.js + + diff --git a/test/blackbox-tests/test-cases/melange/include_subdirs.t/run.t b/test/blackbox-tests/test-cases/melange/include_subdirs.t/run.t index 50100d906db..c5962a2fb0e 100644 --- a/test/blackbox-tests/test-cases/melange/include_subdirs.t/run.t +++ b/test/blackbox-tests/test-cases/melange/include_subdirs.t/run.t @@ -10,7 +10,6 @@ source: $ find _build/default/$output -iname "*.js" | grep -v melange | sort _build/default/inside/output/inside/app/b.js - _build/default/inside/output/inside/app/lib.js _build/default/inside/output/inside/app/lib/a.js _build/default/inside/output/inside/c.js $ node _build/default/$output/inside/c.js