Fork me on GitHub
#clojurescript
<
2019-10-24
>
kwladyka15:10:47

Sorry for copy the topic, but this group is more active. Anybody know this issue? I have this first time with figwheel-main https://clojurians.slack.com/archives/CALJ3BFLP/p1571930616030100

kwladyka15:10:46

I was trying with npx webpack --mode=production and npx webpack --mode=development - both work during figwheel developing

kwladyka15:10:06

So it has to be something about figwheel-main hmm

thheller15:10:07

@kwladyka that looks like an externs issue. try enabling :infer-externs. you can debug this a little by setting :pseudo-names true in your build config. that'll still error out but it'll make the "problem" easier to find

kwladyka15:10:52

thx I will try to debug it with your hints

kwladyka15:10:17

But still it is strange it works during developing, but not after compile

thheller15:10:56

that is completely expected and a side effect of the :advanced optimizations we want to have in CLJS

thheller15:10:16

you can switch to using :optimizations :simple which will make the problem go away

thheller15:10:29

but you build will also be a lot bigger, too big probably.

kwladyka15:10:11

hmm, what is going under the hood? I mean :advanced doesn’t detect dependencies or is it my bug?

kwladyka15:10:50

sorry, brb in 30 min.

kwladyka16:10:59

:infer-externs - added by automate with fighweel-main, so I already have this

kwladyka17:10:29

I can’t figure it out @thheller. Any hints?

thheller17:10:06

Missing externs for argv, looks like reagent 0.9 right?

kwladyka17:10:27

reagent {:mvn/version "0.9.0-rc1" :exclusions [cljsjs/react cljsjs/react-dom]}

kwladyka17:10:53

hmm probably shouldn’t use reagent RC…

thheller17:10:54

yeah. I think the externs you are missing are for props though. there was an open issue about that

kwladyka17:10:19

How could I figure out it myself from debugging?

thheller17:10:32

not sure how to add externs for figwheel anymore

thheller17:10:11

the code is telling you the it tried acessing $argv$ on something that was undefined

thheller17:10:30

so thing.argv before renaming when thing is nil/undefined

kwladyka17:10:06

yeah, but I wouldn’t never guess argv is about Reagent

thheller17:10:19

in this case I believe it is this.props.argv which is getting renamed to thing.$props$.$argv$ with pseudo-names

thheller17:10:37

you can set a breakpoint in the chrome devtools

thheller17:10:47

and it'll show you that its in the reagent ns somewhere

kwladyka18:10:13

hmm but breakpoint is to set on specific line of file. How can I achieve discovering reagent?

kwladyka18:10:13

on the last known line nr

kwladyka18:10:59

function $reagent$impl$component$props_argv$$($JSCompiler_temp_const$jscomp$115_c$jscomp$223$$,$JSCompiler_temp$jscomp$114_p$jscomp$69$$){var $JSCompiler_temp_const$jscomp$116_temp__5737__auto__$jscomp$7$$=$JSCompiler_temp$jscomp$114_p$jscomp$69$$.$argv$;if(null==$JSCompiler_temp_const$jscomp$116_temp__5737__auto__$jscomp$7$$){$JSCompiler_temp_const$jscomp$116_temp__5737__auto__$jscomp$7$$=$cljs$core$PersistentVector$EMPTY_NODE$$;$JSCompiler_temp_const$jscomp$115_c$jscomp$223$$=$JSCompiler_temp_const$jscomp$115_c$jscomp$223$$.constructor;

kwladyka18:10:21

but it is very not obviously and it is not even breakpoint. Is it you what you mean?

thheller18:10:36

in chrome debugger check the `pause on exceptions" thing

thheller18:10:44

that'll take you to whereever the error occurs

kwladyka18:10:21

sounds like this one. Still very not obviously for me. I mean for me it could mean everything what reagent try to load. But yeah, good you know and can share with me 🙂

thheller18:10:18

looks like that is somewhere inside the minified webpack parts maybe?

kwladyka18:10:55

to be honest I have no idea how to debug it deeper

kwladyka18:10:02

I am trying downgrade Reagent ver.

kwladyka18:10:20

and now it works

kwladyka18:10:39

Thank you @thheller. Without you I will stuck for ages with that. 🍻

kwladyka18:10:55

Whenever I will meet you I have to buy you a beer or two 😉

mikerod16:10:02

it seems difficult to figure out a supported/current cljs test runner tool.

mikerod16:10:16

Also, there are a ton of references out there to using phantomjs based ones - which is an unsupported, dying project

mikerod16:10:01

then there is karma+chrome /etc. which requires some node setup. that can work, but requires cooperation from the infrastructure - like travis

mikerod16:10:05

which is another hunt to find

Alex Miller (Clojure team)16:10:14

the annual clojure survey had a question about what people are using in cljs, in case those results are helpful

mikerod16:10:22

I thought lein-doo was the place to be now, but it looks to be falling behind too

mikerod16:10:41

I always do read the surveys! but don’t remember that one, will look

mikerod16:10:02

background is just trying to get clara-rules cljs-side a bit more up-to-date. it’s using phantom and facing troubles there

mikerod16:10:23

and I feel using phantom just really isn’t a good answer anymore

Alex Miller (Clojure team)16:10:02

I'm just glad "not running tests" isn't the highest anymore :)

mikerod16:10:24

haha 2nd place

Alex Miller (Clojure team)16:10:30

the open ended comments are useful here too

mikerod16:10:38

so there is “headless browser” @ #1, I think probably a karma-style setup then

mikerod16:10:46

#2 no tests, #3 doo

mikerod16:10:36

interesting this survey view says (64), but will only show me like 4

Alex Miller (Clojure team)16:10:38

and I would welcome feedback about what the available options should be in this question for 2020

👍 4
Alex Miller (Clojure team)16:10:57

can you scroll that pane?

mikerod16:10:08

doesn’t let me in chrome, will try something else - probably a UI quirk though

mikerod16:10:41

looks fine in firefox, maybe I just didn’t do it right in chrome

mikerod16:10:39

> Move code to cljc and test Clojure part - Getting testing to work for cljs is not a pleasant experience. this one speaks to me - I’ve done this a good deal hah (obviously not testing dom-side)

mikerod16:10:20

koacha is making a name for itself in the 64 comments though - interesting to explore

lilactown16:10:32

with shadow-cljs, I can’t use lein-doo or cljs-test-runner because shadow-cljs does a lot to add on top of the CLJS compiler that my application needs

mikerod16:10:52

yeah, I’d fear that

mikerod16:10:21

I was trying out lein-doo but pretty annoyed with some of it’s opaque issues - that have several github issues linked to it, but no details and I don’t think it is really actively maintained (at least it seems)

mikerod16:10:32

so if I’m going to move away from phantomjs issues, I don’t really want to move to another unmaintained thing

lilactown16:10:41

the current best practice with shadow is to install and use karma

mikerod16:10:11

In my specific case of clara-rules, don’t really care about DOM-like things anyways. It’s just a non-visual lib that can be used in JS. So just want to test it compiling and working in that way. So a bit nicer. I’m not trying to get carried away here and tests layout stuff etc

mikerod16:10:21

I know karma is big an popular

lilactown16:10:26

it has a :karma target that makes this pretty easy. but I don’t think this actually does a whole lot other than look for tests, spit them in a file and a simple runner ns

mikerod16:10:29

I guess I can figure out how to do this sort of thing in this travis setup

mikerod16:10:42

open-source github repo integration thing in this case

lilactown16:10:59

you might consider testing in node? if you think that gives you the confidence you want from your CI process

mikerod16:10:46

I think node would still be fine

mikerod16:10:51

will have to explore

Alex Miller (Clojure team)17:10:26

I'll just generally hand-wave around this and suggest cljs testing might be an area for clojurists together to help in

👋 8
danielcompton00:10:43

Agreed, we'd love to get an application from anyone working on a ClojureScript testing project.

Alex Miller (Clojure team)01:10:56

also, there was a discussion the other day about web session handling ala buddy/friend and that area that sounded like it would be a great area to fund

dominicm02:10:31

@U07QKGF9P would be cool to have someone with a real security background look at buddy properly perhaps 🙂 (thinking particularly on the crypto).

lvh19:10:06

I'd like to but there's a few problems there: 1. I'm on the board now and I'm the president of our new legal entity so there's a direct/obvious COI meaning CT can't fund me 2. Haha sure I'll go do that in my copious spare time even if you fund me 3. It's hard to say negative things about projects even though that's kind of what my job would be (I've looked at Buddy before, I have strong opinions on API design for security products (having been at the cradle of pyca/cryptography), so, uh, you know, it'd be lively :))

thheller17:10:39

FWIW the "design" for this in shadow-cljs separates out the compilation from the actual running of the tests

thheller17:10:28

so the karma route just runs the tests without it even knowing about shadow-cljs

thheller17:10:36

things are really simple when running tests in node is an option

mikerod17:10:56

interesting, I’ll read up on it

mikerod17:10:08

thanks for the links/advice

thheller17:10:23

testing is mostly complicated if you need to run them in a browser environment

thheller17:10:53

node is a whole lot easier since you just run node the-test.js and don't need to setup an entire headless browser and so on

👍 4
mikerod17:10:28

yeah, that makes sense indeed

borkdude18:10:43

has anyone noticed differences in advanced compilation with Java 11? we do...

thheller18:10:15

what kind of difference?

borkdude18:10:56

we get this error: Uncaught TypeError: http://SortableHOC.Sl is not a constructor while we didn't get that one with Java 8

thheller18:10:26

sounds like an externs problem but not sure how the java version would affect that

borkdude18:10:35

yeah, weird right?

thheller18:10:43

unless you also changed other dependencies while updrading the java version

borkdude18:10:46

looking at the code the error isn't weird. it's maybe weirder that it used to work in Java 8 😉

borkdude18:10:56

sorry I can't come up with a good repro now

borkdude18:10:07

just wanted to inform if anyone else had this problem

kwladyka19:10:09

I did an update of my library https://github.com/kwladyka/form-validator-cljs to validate form in cljs using spec and fn. I added a demo with example of code https://kwladyka.github.io/form-validator-cljs/ Now it is easier to see what library can do, but it has more use cases. What do you think about the library and the demo? Is it understandable? Is it useful for you?

borkdude19:10:55

@kwladyka cool! there is also a #announcements channel btw

kwladyka19:10:50

Yeah, really wanted to get this feedback if somebody will use it. Library exist a long time and I don’t even have idea if people really use it. Considering stats it is not popular 🙂

kwladyka19:10:57

But I don’t have influence (popular channel YT, blog, etc.)

kwladyka19:10:51

So thinking if library is not so needed or it is only about popularity and “advertisement”

kwladyka19:10:21

But yes, I should write it on #announcements . Sorry.

borkdude19:10:56

@kwladyka There are multiple ways to promote your library if you want to do that. Putting it in announcements is one thing, but you can blog about it, why it's great. You can post on Clojureverse to showcase your project. Also on Reddit.

👍 4
p-himik20:10:05

It's much easier to find something that has relevant topics.

kwladyka20:10:19

Heh and here is a point. I don’t even have an idea how to use Reddit. It is not popular in my country. First time I hear about https://clojureverse.org/ But thanks, I will learn this things

kwladyka20:10:18

By Reddit you mean Clojure / ClojureScript community?

kwladyka20:10:57

I have to make there account one day 🙂

borkdude21:10:12

yes /r/clojure. but ClojureVerse is more friendly probably

dominicm21:10:34

Is there an alternative to requiring-resolve in ClojureScript? Otherwise I have to create a whole other namespace for 1 function which uses a library conditionally.

thheller21:10:47

no. dynamic require isn't possible at all

dominicm21:10:32

I suppose in ClojureScript you pay the bulk of all your libraries anyway (until compilation), so there a top-level require would do the job?

dominicm21:10:12

oh, but it would need to be in a macro to be conditional on the namespace existing, boo

dominicm21:10:51

out of curiosity, if resolve can work, why not requiring-resolve? :thinking_face:

thheller21:10:35

resolve is fake and resolves at compile time. it cannot be used dynamically

dominicm21:10:54

Sure. But so could requiring-resolve.

thheller21:10:23

require can't be done dynamically because it requires blocking IO

thheller21:10:53

in JS all IO is async. so loading the namespace would require a callback before it can continue

borkdude21:10:03

also conditions around require would probably make advanced compilation and analysis much more tricky?

thheller21:10:27

the closure compiler doesn't support this at all too. that would be another reason yes

dominicm21:10:32

Maybe this is just for my case, but I would assume that all branches are accessible (except where google closure can assume otherwise)

dominicm21:10:58

I should probably try and understand a little better: how does clojurescript determine the dependencies? Doesn't it analyze the whole file? Couldn't all requiring-resolve be appended to the list of namespaces to goog.require?

dominicm21:10:22

I understand the general context of where I'm getting to if I want a semantic match. But the behavior I'm really looking for is: - If ns is known, then add to goog.require for the file, and call resolve on the sym. - if ns is unknown, do nothing unless function is called then blow up

thheller21:10:17

goog.require is basically a noop

thheller21:10:24

it does absolutely nothing.

thheller21:10:02

so if you think about this as just getting an extra goog.require in there you are looking at the wrong thing

dominicm21:10:32

I thought that was the magic for analysis. My mistake.

thheller21:10:54

the problem is that all dependencies have to be loaded before the actual file is loaded because of the async IO

thheller21:10:41

so the code would be loaded regardless of the goog.require being conditional or not

thheller21:10:54

but the closure compiler doesn't allow it anyways so it doesn't really matter

dominicm21:10:47

All dependencies have to be loaded before the js, but not the cljs, no? I must not be understanding

thheller21:10:08

at runtime there is only JS

dominicm21:10:12

I'm not really trying to prevent loading. I'm trying to make it so require didn't blow up.

andy.fingerhut21:10:17

What is the situation in which the namespace exists in some cases, but not in others? Different ClojureScript compilation runs with different environment variable settings (or similar), but at least some common source files in both compilation runs?

thheller21:10:57

I don't understand that question

thheller21:10:16

you can't reliably "mix" output from different compilation runs

andy.fingerhut21:10:32

My question was directed towards dominicm -- sorry if that wasn't clear

dominicm21:10:55

It's an optional dependency of the library that enables the use of one function.

thheller21:10:23

the only way to get "optional" dependencies right now is via :preloads

thheller21:10:47

but :require is completely static and cannot be dynamic in any way

thheller21:10:05

require in the REPL is completely different and has different rules

thheller21:10:23

require in a file is fake and not like the REPL at all

dominicm21:10:06

Sure. I know. It's there to be detected for static analysis right? Or wrong?

thheller21:10:46

it was added to allow files without an ns form and is completely static yes

andy.fingerhut21:10:12

So perhaps one way to achieve the goal is to have two source files foo1.clj and foo2.clj, where foo1.clj is compiled if the dependency is present, and calls the real function, and foo2.clj is compiled if the dependency is not present, and throws an exception if its function (with the same name) is ever called? Sounds a bit clunky, but possible.

dominicm21:10:45

So, just so I'm entirely clear, I'm not after deferred loading here. I understand the limitations there. What I'm thinking of is another lie. A static requiring-resolve that that does the same thing as require. But if it didn't find the namespace it would replace requiring resolve with something that would blow up at runtime. Otherwise, it replaces it with whatever resolve does right now.

thheller21:10:35

I don't really understand your goal or what require-resolve has to do with anything

thheller22:10:06

(def my-magic-function (atom nil)) (defn call-the-thing [a b c] (@my-magic-function a b c)

thheller22:10:23

then have the "optional" ns swap! into that atom

andy.fingerhut22:10:04

Is there a run-time cljs way to check whether a specific namespace exists?

thheller22:10:10

no, in fact namespace don't exist at all anymore in :advanced compiled builds

dominicm22:10:27

You only need compile time detection.

andy.fingerhut22:10:05

I guess. Is there an inside-cljs way at compile time to detect whether a namespace exists?

thheller22:10:46

define "exists", it is relative and time dependent

dominicm22:10:46

I think so. Else it couldn't tell you about requiring non existent name spaces

thheller22:10:10

if you don't have an explicit require for something it is not guaranteed to exist before the ns checking it is compiled

andy.fingerhut22:10:06

Right, so seems like catch-22 for an inside-cljs-language solution to the desire. Only alternative I can see is something in the compile/build infrastructure that does it.

andy.fingerhut22:10:16

(the previous comment is assuming that the optional dependency's source code is not under dominicm's control or ability to modify -- thheller your suggestion about the atom seems to work if the optional dependency's source code is under dominicm's control)

thheller22:10:46

we are working with the limitations of JS and somewhat the Closure Compiler here

thheller22:10:58

so it really doesn't help to compare to CLJ/JVM features

lilactown22:10:27

I think domincm is dancing around the idea of a macro or reader thing that looks at the classpath, sees if a particular namespace exists, then emits some code. but I don’t know if the compiler/analyzer lifecycle works like that

thheller22:10:47

it doesn't matter what is on the classpath

thheller22:10:26

the only way to affect what ends up in a build is via build config and :require in the actual sources

thheller22:10:54

macros can't do it

dominicm23:10:19

@thheller this is roughly what I was getting at

(defmacro require-resolves
  [body]
  (let [to-require
        (set
          (map #(namespace (second (second %)))
               (filter #(and (seqable? %) (= 'requiring-resolve (first %)))
                       (tree-seq seqable? seq body))))]
    (if (every? #(io/resource
                   (str (-> %
                            (string/replace "-" "_")
                            (string/replace "." java.io.File/separator))
                        ".cljs"))
                to-require)
      `(do ~@(map #(list 'require (list 'quote (symbol %))) to-require)
           ~(walk/postwalk
              (fn [x]
                (if (and (seqable? x)
                         (= 'requiring-resolve (first x)))
                  (list 'resolve (second x))
                  x))
              body))
      (walk/postwalk
        (fn [x]
          (if (and (seqable? x)
                   (= 'requiring-resolve (first x)))
            `(throw (ex-info (str "Unable to find " (first x)) {}))
            x))
        body))))

(require-resolves
  (defn foo
    []
    (let [x (requiring-resolve 'cljs.core/foo)]
      (x))))

dominicm23:10:43

obviously the detection of existence wouldn't just be doing io/resource on the file, I'm assuming there's some compiler internal for that.

danielcompton00:10:43

Agreed, we'd love to get an application from anyone working on a ClojureScript testing project.