Fork me on GitHub
#clojurescript
<
2021-01-11
>
Nazral09:01:01

Hi, I am trying to use https://github.com/vasturiano/force-graph 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)

Nazral09:01:32

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

Nazral09:01:24

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

p-himik09:01:14

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

Nazral09:01:28

A function object that seems to be quite empty

p-himik09:01:37

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

p-himik09:01:38

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).

p-himik09:01:41

For future reference, this is the relevant imports translation table: https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages Note that in a few odd cases it doesn't work, so js/console.log is still useful.

Nazral09:01:59

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

Nazral09:01:09

(fg) indeed outputs what I wanted

p-himik09:01:31

So was it :as or :default?

lambduhhh14:01:15

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 ^~^ https://youtu.be/ZMB-M_XDotE

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")
    (go
      (.log js/console "After go is never printed")
      (<! (timeout 1))
      (done))))
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 https://stackoverflow.com/questions/65669171/clojurescript-cljs-core-async-go-doesnt-work-inside-jsdom

thheller15:01:48

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

https://github.com/google/closure-library/blob/master/closure/goog/async/nexttick.js this is the underlying code doing a bunch of browser detection stuff

thheller15:01:03

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

thheller17:01:27

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

thheller17:01:43

try

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

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

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.

thheller18:01:57

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?

thheller15:01:02

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 https://github.com/Valdermeyder/jsdom-google-closure-library 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

markbastian15:01:30

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?

thheller15:01:48

@markbastian "dynamic require" in CLJS is not supported

👍 3
🙏 3
GHvW16:01:07

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?

GHvW16:01:14

thank you so much!!!

grounded_sage22:01:08

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?