At my workplace I’ve instigated a ClojureScript project (running on node and browser); to encourage acceptance I’ve promoted the fact that incorporating plain old JS is not a problem. I now find myself with a mix of cljs and js each calling functions from one to the other. It appeared to be working up to 1.9.1032 but the update to the Closure Compiler (72e2ab6e) appears to have broken my build (I used git bisect to pinpoint the breakage). I haven’t been able to exactly reproduce the problem in a minimal reproducible case, but this is my attempt: au-phiware/cljs-in-js-in-cljs. It exhibits some interesting behaviour between 1.9.1032 and 1.9.1033.

First off I’m not even sure my approach is the most sensible or if I’m pushing things in the wrong direction. The majority of the project is written in cljs, some of which calls upon some functionality in a es6 module, e.g.

Now, proir to 1.9.1033, the compiler would emit the expected goog.provide and transform the export statement. With 1.9.1033, the compiler emits goog.require("goog"); and an extra goog.require for the cljs ns, e.g.

Compiling with simple optimizations, the goog.require("goog"); appears to confuse the cljs compiler because it adds it itself (src/main/clojure/cljs/closure.clj line 2716) and winds up with two. I notice that there’s already an issue for this: CLJS-1677 but is a low priority.

I don’t think so? Thanks for sharing it. I haven’t seen a lot of cljs/js interop examples like this.

There’s been a lot of work on JS module support/interop. I would have made the same suggestion as @roman01la but if it doesn’t make sense you might try going forward to the latest (or really close). I’m pretty sure a few bugs in this area have been fixed along the way. Sorry I can’t be more helpful/specific.

This was probably caused by big Closure-compiler update, which changed how provides and requires are handled for module-processed JS (:module-type :es6). Previously Closure generated those goog.provide/require calls itself. We now generate them ourselves because Cljs compiler is written to read those.

Duplicate goog.requires to the cljs file don’t seem to cause problems. It might be easy to fix later, as I think the next Closure-compiler will add more information about require calls I can use to remove duplicates.

@thheller Mentioned that the correct way to require Closure or Cljs namespaces from ES6 is with goog: prefix:

There is still another problem. If hello.say is only used by Closure JS (:libs) or module-processed JS, the Cljs file is not compiled, due to how Cljs compiler checks for required Cljs files. But this didn’t work in previous versions either. To workaround this, you can require hello.say in your hello.core ns.

Thank you for taking the time to look into this and for your advice. I did not know about the goog: prefix (nor can I find it documented anywhere, I assume it’s a GCC thing?) and I can live with requiring the transitive dependencies (i.e. hello.say from hello.core). I have tried compiling my minimal project with the latest cljs (1.10.271) and it works with both simple and advanced optimisations: au-phiware/cljs-in-js-in-cljs#7f427e2

I haven’t had a chance to try it in my work project yet, which was vastly more complicated but I consider this set of issues solved!