Fork me on GitHub

Hi, I am trying to use from shadow-cljs and am having a problem. I install the library all right with npm, but when I try to reproduce

import ForceGraph from 'force-graph';
with (:require ["force-graph" :as fg]) then fg/ForceGraph is nil (same if I use :refer)


(it works fine if I use it from a <script> tag)


The error I get is shadow-cljs - [reload failed] module$node_modules$force_graph$dist$force_graph_common.ForceGraph is not a constructor which makes sense given that force_graph.common does not contain ForceGraph


When you use (:require ["force-graph" :as fg]), what's the output of (js/console.log fg)?


A function object that seems to be quite empty


So it's a function. Maybe just (:require ["force-graph" :as ForceGraph]) then?


Alternatively, if that doesn't work, (:require ["force-graph" :default ForceGraph]) (but in this case I would've expected that fg object from before to have the default key).


For future reference, this is the relevant imports translation table: Note that in a few odd cases it doesn't work, so js/console.log is still useful.


It worked, thanks ! It's also that I was calling it wrongly 😅


(fg) indeed outputs what I wanted


So was it :as or :default?


Starting a mini series on my channel focusing on Clojurescript. Tune in for some laughing and learning you some lisp languages.. That's what I'm all about! 😜✌️ Also open to any requests for tutorials ^~^

Volodymyr Huzar15:01:30

Hi, I am trying to migrate ClojureScript tests from “Chrome Headless” to jsdom using Karma and shadow-cljs as test runners. The regular tests which require access to DOM or browser API work fine. But async test where cljs.core.async/go is used doesn’t work. Basically, nothing inside go is executed. Does anyone have some idea what could be wrong? Did I miss some configuration? Is it only jsdom issue or maybe it is cljs.core.async interoperability issue? I have put a simple test example below

(ns async-tests
  (:require [cljs.test :refer [deftest async]]
            [cljs.core.async :refer [go <! timeout]]))

(deftest async-go-test
  (async done
    (.log js/console "Before go is printed")
      (.log js/console "After go is never printed")
      (<! (timeout 1))
The result I get in console is
LOG: 'Testing async-tests'
LOG: 'Before go is printed'
WebKit 537.36 (undefined 0.0.0): Executed 159 of 185 SUCCESS (0 secs / 0.589 secs)
WebKit 537.36 (undefined 0.0.0) ERROR
Disconnected, because no message in 30000 ms.
I have create a StackOverflow issue with few more details


I'm guessing that the async mechanism used by core.async is either somehow affected by jsdom and doesn't execute at all

thheller15:01:36 this is the underlying code doing a bunch of browser detection stuff


maybe jsdom "pretends" that something is there but doesn't actually do anything

Volodymyr Huzar16:01:05

thank you for the response. I’ll create an issue for “jsdom”, maybe they can help as well to find the exact reason from their side. I also thought about order of .js files which are loaded by karma but I’m not sure if it makes sense at all

Volodymyr Huzar17:01:25

The ticket to jsdom wouldn’t be so easy. I have to figure out how to reproduce the behaviour without karma and other tools. I’ll see what I can do with that


you could first try to isolate whether it actually is core.async or the nexttick stuff



(ns async-tests
  (:require [cljs.test :refer [deftest async]]

(deftest async-go-test
  (async done
    (.log js/console "Before go is printed")
      (fn []
        (.log js/console "After go is never printed")

Volodymyr Huzar17:01:42

seems like it is nextTick I got the same error as before with go

Volodymyr Huzar17:01:08

Thanks for pointing that. With nextTick it should be easier to create a reproducible example as it is js and should run in node environment without all other tools I have right now.


also try with js/setTimeout just to be sure

Volodymyr Huzar11:01:42

(set! (.. js/window -goog -async -nextTick) js/setTimeout) does it job and makes cljs.core.async/go to work

Volodymyr Huzar14:01:21

@U05224H0W looking back on workaround you have proposed and which works what is you opinion about this defect. Is it more related to clojure/goog/async or jsdom or is it just colliding of tools and it would be hard to fix it inside any of them?


I don't know. I haven't looked at the code of nextTick in detail. I'd put the blame on jsdom in case it "pretends" to emulate something when it doesn't

👍 3
Volodymyr Huzar11:01:27

I have created a small Node demo where only jsdom and google-closure-library are used and they work fine together (unless I did some terrible mistake). My next assumptions that it could be either karma connector for jsdom or something related to the clojurescript ecosystem. I’ll try to create a simple clojurescript demo some time later to check that


Does (or should) require (the function, not the ns declaration arg) work differently in cljs than cj? When I do something like (require '[clojure.pprint :as pprint]) and then invoke (pprint/pprint "test") I get a warning in my repl along the lines of:

------ WARNING - :undeclared-ns ------------------------------------------------
 Resource: <eval>:1:2
 No such namespace: pprint, could not locate pprint.cljs, pprint.cljc, or JavaScript source providing "pprint"

------ WARNING - :undeclared-var -----------------------------------------------
 Resource: <eval>:1:2
 Use of undeclared Var pprint/pprint
This seems to happen with any dynamically required ns. If I add the required namespace to my ns in the :require block it works. Is this expected behavior?


@markbastian "dynamic require" in CLJS is not supported

👍 3
🙏 3

is there any way around the dynamic imports issue in a browser context? If a npm dependency is a hard requirement, is there any way to isolate that and work with it in javascript but still have your application primarily built in clojurescript?


thank you so much!!!


Is there a good way to capture the name of a function or it’s namespace when you throw an error inside a go block and propagate it?