Fork me on GitHub
#clojurescript
<
2020-07-22
>
pmooser04:07:29

I don't understand the AST in the compiler, so I don't understand its role in generalizing my hack into a general fix. I'll try to dig into it if I have a bit more time. I need to figure out how to have my own debug build of cljs so I can modify it while I'm using it to get some insight into how things work.

Sam Ritchie14:07:33

Hey all! I'm about a day in to a pretty brutal struggle, trying to generate a cljsjs dependency for Complex.js. I figured it was time to tap out and report here. I can repro all of this, but first let me sketch...

Sam Ritchie14:07:31

I'm using "lein doo node main once" to run my tests; everything works wonderfully with :optimizations :none with the jar I've generated containing the code for complex.js https://github.com/infusion/Complex.js/

Sam Ritchie14:07:00

but when I move to :optimizations :simple, I get an error stating that Complex does not exist; ie, the js/Complex reference is now failing to pick anything up

Sam Ritchie14:07:44

(I've tried repackaging the dependency using an npm bundle; unfortunately with this method I can't get js/Complex to resolve at all)

Sam Ritchie14:07:53

happy to provide more info, but has anyone seen anything like this before?

isak14:07:55

Is there any syntax for creating js objects with symbols for keys rather than string literals? E.g., like #js {:foo "bar"}, except yielding {foo: "bar"} instead of {"foo" : "bar"}

thheller14:07:54

@isak there is no difference? all JS objects just have string keys

isak14:07:24

There is a difference for advanced compilation, no? @thheller

thheller14:07:16

if you want foo to be renamed yes?

thheller14:07:44

then you likely should just use (deftype Something [foo]) or so

AJ Jaro14:07:17

Is anyone using http://percy.io with puppeteer for UI-related tests? I’m struggling with getting a basic example working

isak14:07:37

Hmm, well since it is a parameter for a function defined in JS, it is easier to just create an object and call (set! (.-foo o) ...) on it, just wanted to know if there was syntax for it, but I guess not

Sam Ritchie15:07:08

If anyone does have any insight on the above... here is the code that gets built: 

Sam Ritchie15:07:10

the JS, that is

Sam Ritchie15:07:16

under simple optimizations

Sam Ritchie15:07:55

so, I DO see that there is no Complex object getting set...

Sam Ritchie15:07:53

I seem, actually, to not be able to get ANY cljsjs dependency to work

Sam Ritchie15:07:58

in more than :none mode

Sam Ritchie15:07:10

so, any tips or pointers to a project that can do this would be much appreciated!

dnolen15:07:50

@sritchie09 no pointers w/o something minimal - post something tiny that demonstrates your CLJSJS problem, I'm quite skeptical about that one

dnolen15:07:00

but maybe if someone can you straight about that, the rest will make more sense

dnolen15:07:57

also your problem seems tied up w/ testing - you haven't said if this only about testing and not in other cases

Sam Ritchie15:07:25

@dnolen yup, I've almost got a repro together

Sam Ritchie16:07:24

here's the cljsjs build;

Sam Ritchie16:07:39

and here's the minimal repro

Sam Ritchie16:07:12

@dnolen yes, so far this is only with the testing environment. only because I haven't yet tackled how to get a repl open pointing at an advanced compilation target

dnolen16:07:41

Not possible

dnolen16:07:17

For testing simple isn’t usually meaningful - advanced

Sam Ritchie16:07:48

yes, that fails as well, unfortunately. I've exported the top level function, let's see if I can get it running from phantomjs

Sam Ritchie16:07:48

no luck, just this test failure

Sam Ritchie16:07:51

@dnolen do you have any pointers to some other way I can attempt to run these tests? I promise I've been searching everywhere; it is not so obvious finding small examples. I suspect that I've got something busted in my project.clj, or the way I'm setting up the clojurescript compiler options;

Sam Ritchie16:07:12

this is because I see the same error with other dependencies that already exist on cljsjs, like cljsjs/bn when I pull that in instead as a test. In that case, BN is not defined

Sam Ritchie16:07:40

I'd be thrilled to use a different test runner, for example, if you think that might be the issue, and have a pointer to something more maintained / newer

Sam Ritchie16:07:59

ERROR: JSC_MISSING_MODULE_OR_PROVIDE. Required namespace "cljsjs.complex" never defined. at /Users/samritchie/code/clj/complex-failure/out/example/core.js line 4 : 0

Sam Ritchie16:07:06

here's the error from the headless chrome runner

Sam Ritchie16:07:40

LOG: 'Testing example.core-test' Chrome 84.0.4147.89 (Mac OS 10.15.5) example.core-test complex FAILED FAIL in (complex) (/Users/samritchie/code/clj/complex-failure/test/example/core_test.cljs:6:7) (= 1 (.-re (core/complex 1 2))) failed with ReferenceError: BN is not defined

Sam Ritchie16:07:38

with a different cljsjs library, same error when I try to reference the main object available as js/BN. cljsjs's documentation seems very clear that this is the way to reference anything made available through that dependency mechanism, and it does indeed work well with :none optimizations

Sam Ritchie16:07:32

I've been searching for any project with tests that uses any dependency from cljsjs, which I'm sure exist, but the search is not easy. does anyone have a pointer toward some project with advanced tests that is successfully using a cljsjs dependency? if I can get that specific dependency, which I KNOW should work, then i should be able to debug my cljsjs dep more easily

Sam Ritchie16:07:50

amazing, @dnolen they seem to both actually work when using the chrome headless runner

dnolen16:07:33

huh ok - like I was trying to imply above this sounded like it might be something to do w/ your testing setup

dnolen16:07:38

probably not ClojureScript

Sam Ritchie17:07:13

yeah, no doubt, it's more the difficulty of finding example setups to copy

Sam Ritchie18:07:56

@dnolen interesting update

Sam Ritchie18:07:04

my failing repro works fine with [org.clojure/clojurescript "1.9.946"]

Sam Ritchie18:07:43

fails to execute with [org.clojure/clojurescript "1.10.773"]

Sam Ritchie18:07:38

ERROR: doo was not loaded from the compiled script.

Make sure you start your tests using doo-tests or doo-all-tests
and that you include that file in your build

Subprocess failed (exit code: 1)
with this error, with the phantomjs runner

Sam Ritchie18:07:17

@dnolen let me find the version where it cuts over to failing

dnolen18:07:20

@sritchie09 I probably won't look at personally look at something like this until it's determined that it isn't actually a problem with doo

Sam Ritchie18:07:52

yes, that makes sense. I'm so rusty at all this that I figured I'd just gather what I can

dnolen18:07:54

I believe those two versions are more than 1 1/2 apart and with changes outside of our control in Closure Compiler and GCL

Sam Ritchie18:07:02

1.10.597 works, 1.10.741 fails

dnolen18:07:22

those two version are probably two years apart - this is not informative 🙂

Sam Ritchie18:07:08

@dnolen but I hear you! I'll drop to something that works for me and hold off for a while, here

dnolen18:07:46

it's likely someone else encountered this - I don't use doo myself so I really can't be of any help

dnolen18:07:59

at least around the part of determining if the problem is in doo in that it relies on something it can't rely on anymore around loading stuff, really who knows

Sam Ritchie18:07:05

sg, thanks for the comments, in any case! the current project is converting the engine behind Sussman's Structure and Interpretation of Classical Mechanics to cljs https://github.com/littleredcomputer/sicmutils

Sam Ritchie18:07:31

so we can have an interactive advanced mechanics engine in the browser, with automatic differentiation in clojurescript coming along for the ride

dnolen18:07:14

my suggestion would be to just focus on what you're doing, unless you want to sink time into doo

dnolen18:07:31

if the logic is pure what is the point of running the tests in the browser

Sam Ritchie18:07:20

yes, node wasn't seeing any imported classes from cljsjs, ie, js/Complex, in anything other than :none compilation mode

dnolen18:07:26

running tests in any mode other than none is really only about one thing

dnolen18:07:37

that you didn't mess up externs somehow

dnolen18:07:55

but it's not really that meaningful otherwise

Sam Ritchie18:07:05

yes, for sure

Sam Ritchie18:07:26

oh, I see - you're saying, for tests, just stick to :none and move on

dnolen18:07:25

personally I never use anything but my own runners because whatever time is lost on setting that is less than the time to figure out what's wrong in my deps

Sam Ritchie18:07:41

I've learned that lesson viscerally today, I think

dnolen18:07:41

everybody has a different tolerance for this stuff, mine is very low

dnolen18:07:05

this isn't a knock against doo, it seems popular but I can't shed any light on it

Sam Ritchie18:07:33

I think I've discovered here that I can make it work if I need to with an older cljs version with no debugging, and I appreciate the time from you, really

Sam Ritchie18:07:53

and I did find one bug! I was doing some inspection of js-keys of functions to try and figure out function arity at runtime

Sam Ritchie18:07:05

which, of course, all gets munged away by the advanced compiler

Sam Ritchie18:07:36

I'm guessing that's not something that's possible to recover

Sam Ritchie18:07:01

without, say, a custom fn macro that snags the information at function definition time

dnolen18:07:15

yes you can't figure out arbitrary function arity at runtime

dnolen18:07:35

this is especially tricky because Clojure(Script) fns support more features than JS fns

dnolen18:07:51

(fn [f] (arity f ...))

dnolen18:07:53

impossible

dnolen18:07:03

(arity some-f) possible

dnolen18:07:27

because arity could be a macro that gets that info at compile time

👍 3
Sam Ritchie18:07:50

we're looking for the three cases of "exactly", "between", "at-least", so maxFixedArity gives us something, at least, with a fallback to assuming a single arg

dnolen18:07:57

another possible option is passing vars instead of direct fns

dnolen18:07:15

#'foo will dump something with the var meta - it will have a bunch of information

Sam Ritchie18:07:27

okay, that's excellent

Sam Ritchie18:07:00

thanks for the advice, and the larger, life advice of not spending too much time getting pulled into debugging build tools

Toni Dahl18:07:10

@sritchie09 I'm a bit late in this discussion, so I didn't read every bit of it. I wrote this blog post partially out of my own frustration. It might help you or not: https://dev.solita.fi/2020/06/25/taming-cljs-advanced-compilation.html

dnolen18:07:37

and I believe (#'foo) will work like in Clojure? I can't remember - if it doesn't that should be fixed

Sam Ritchie18:07:01

thanks, @toni.dahl , I think the bug I'm hitting is a more subtle problem with lein-doo

✔️ 3
thheller20:07:39

@sritchie09 your js/Complex missing issue is coming from the js file itself not always creating that global as far as I can tell

Sam Ritchie20:07:42

@thheller that makes sense, of course... that particular issue only occurs when lein-doo uses the node runner

thheller20:07:21

thats the common UMD style wrapper and in node it will take the typeof exports branch since it will exist

thheller20:07:39

as such it will not take the last branch which creates the global

Sam Ritchie20:07:16

@thheller so this change needs to happen back in the original dependency, I suppose?

Sam Ritchie20:07:19

to work with node

thheller20:07:55

to work with CLJSJS on node yes. it is not a fault in the library itself, it will likely work just fine in regular node.

Sam Ritchie20:07:06

got it! okay, that's a great note, and I'll cross that bridge in the future

gekkostate21:07:57

Hi all! Does anyone have experience using xmpp.js (we’re going to be using https://www.npmjs.com/package/@xmpp/client) with cljs? If so, what are your experiences? Any pitfalls you would advise others of? Thanks!