Fork me on GitHub
#clojurescript
<
2018-10-25
>
kirill.salykin07:10:51

@jamie857 you need window or just global context?

kirill.salykin07:10:30

would js/Electron work for you?

dnolen08:10:52

that's assigned to the global context regardless of browser or Node.js

reset19:10:21

@U1V7K1YTZ appreciate the response here. I think I'm focusing on a symptom of an overall problem here. Been a tough go getting Electron & Figwheel main playing well together

Christian Johansen10:10:34

I ran into some issues trying to compile a ClojureScript node.js project. Basically, when I run cljsbuild with optimizations :none I get something that works, but any other optimizations produces Cannot find module "../moment", which comes from cljsjs.moment. The code that requires moment is already working in an existing browser app with advanced optimizations… Has anyone seen anything like this?

dnolen11:10:45

@christian767 I'm assuming you need compilation under Node.js for some reason? Like AWS Lambda?

dnolen11:10:32

did you try skipping advanced? There's not much benefit, try :simple

Christian Johansen11:10:56

yes, the problem is reproducible with :simple

Christian Johansen11:10:10

I wanted compilation in order to have a single file, and not use the goog module loading stuff

dnolen11:10:53

ok looked over your readme

dnolen11:10:04

the error is leading you towards the likely cause

dnolen11:10:17

Cannot find module \"../moment\"

dnolen11:10:24

isn't really a ClojureScript thing

dnolen11:10:40

you said you're using cljsjs.moment but that doesn't seem true based on that error

Christian Johansen11:10:14

more specifically, I tracked that line down to a moment locale

dnolen11:10:19

it looks like an attempted load of the moment node module

Christian Johansen11:10:30

yep, from cljsjs.moment.locale.nb

dnolen11:10:40

but that won't work

dnolen11:10:44

I don't see how that could work in the browser

Christian Johansen11:10:57

it got me stumped too…

Christian Johansen11:10:18

the strange thing is that I didn’t touch any of the code using moment - it’s just :required from an existing browser app

Christian Johansen11:10:32

maybe my node program is introducing another moment somehow? :thinking_face:

dnolen11:10:51

:npm-deps false in your build

dnolen11:10:01

we default to reading node_modules but that will change in the next release

Christian Johansen11:10:34

anyway - the build does work in the browser in the repo I posted above. even with optimizations

dnolen11:10:03

no idea about that, I don't use moment

thheller11:10:14

FWIW the problem is in the CLJSJS package

thheller11:10:43

it is a normal AMD wrapper that defaults to calling require when running in node

thheller11:10:58

;(function (global, factory) {   typeof exports === 'object' && typeof module !== 'undefined'       && typeof require === 'function' ? factory(require('../moment')) :   typeof define === 'function' && define.amd ? define(['../moment'], factory) :   factory(global.moment)}(this, (function (moment) { 'use strict';

Christian Johansen11:10:33

still strikes me as odd that this would not fail with no optimizations

dnolen11:10:46

dynamic requires

Christian Johansen11:10:35

@dnolen sure, but my test actively loads the offending code and uses moment to print a formatted date

thheller11:10:55

it works in :none due to the way the debug loader is setup for node

Christian Johansen11:10:36

ok, thanks. definitely learned something today 🙂

thheller11:10:23

you could use shadow-cljs where its just (:require ["moment" :as moment]) for both node and the browser 😉

Christian Johansen11:10:54

haven’t looked into that yet

Christian Johansen11:10:38

my biggest problem right now is that I’m trying to reuse some existing code, so the moment require isn’t in my new code. and I’ve seen the same problem with React etc

Christian Johansen11:10:50

so I’ll probably just settle for no optimizations for now

thheller11:10:49

cljsjs.moment will work as well in shadow-cljs since the shim already exists https://github.com/thheller/shadow-cljsjs/blob/master/src/main/cljsjs/moment.cljs

Christian Johansen11:10:47

question: the unoptimized package (which is a CLI tool) seemed a little slow to me (longer startup times than I’m used to with pure node apps). I assumed this was due to loading lots of files, and that a simple compile to one file would alleviate it

Christian Johansen11:10:14

but this was just an assumption. would :simple optimized cljs be faster than :none?

thheller11:10:25

yes, and :advanced even faster

Christian Johansen11:10:06

you’re saying that I could even use cljsjs.moment successfully with optimizations with shadow-cljs?

Christian Johansen11:10:10

sounds like I need to finally check out shadow-cljs

thheller11:10:16

actually I'm not sure .. people just use (:require ["moment" ...]) usually

thheller11:10:30

cljsjs really is just a hack to get the browser working

Christian Johansen11:10:10

I’ll give it a shot, thanks

thheller11:10:05

I just confirmed that it works fine in both node and the browser

dnolen11:10:12

:advanced is not necessarily faster

dnolen11:10:22

in fact in some cases it can be worse

dnolen11:10:34

short story, we expose all the flags for actual runtime perf stuff

dnolen11:10:46

:static-fns true :optimize-constants true are the ones that matter

Christian Johansen11:10:21

that probably means I can opt out of name munging too?

dnolen11:10:27

:advanced just doesn't matter for Node.js in my opinion

dnolen11:10:34

:simple only munges internals

thheller11:10:40

where would it be worse?

dnolen11:10:59

in the past I would observe Closure creating shared fns for similar code

dnolen11:10:05

but this is a VM perf hole

thheller11:10:51

hmm would that not apply for v8 in the browser?

dnolen11:10:00

it applies to all engines

dnolen11:10:07

advanced isn't necessarily faster

dnolen11:10:27

but code size matters more so tradeoff

thheller11:10:31

I agree that its not all that useful to go for :advanced in node but it does make a difference in startup time

thheller11:10:46

(not that that matters)

thheller11:10:11

interested though. never explored that aspect

dnolen11:10:56

back in when there was ton of data structure work, I would benchmark both :advanced and :simple + the other needed bits

dnolen11:10:10

the later often had the edge

dnolen11:10:25

but not big enough to really care

Christian Johansen11:10:48

but there is significant gains from :none to :simple right?

dnolen11:10:21

we expose all the perf flags

dnolen11:10:32

so I think the biggest different is going to be loads

dnolen11:10:08

:optimize-constants doesn't make sense for :none so that is a big hit

Christian Johansen11:10:01

do I use these individual options in addition to, or in place of :optimizations?

dnolen11:10:36

:optimizations is just a Closure flag

dnolen11:10:45

all this other stuff ClojureScript

dnolen11:10:04

to dispel a common misconception - perf is almost entirely from ClojureScript

dnolen11:10:38

these flags control the ClojureScript compiler and take effect regardless of :optimizations

dnolen11:10:25

the one critical thing that Closure does under :simple and higher

dnolen11:10:42

removal of IIFE (immediately invoked function expressions)

Reily Siegel12:10:35

I'm having some issues with using reagent with cljsjs/material-ui. When using material-ui/Input (after adapting) as a controlled input, and using android irefox (desktop Firefox works fine), the input does not correctly fire events. Lets say I tried to type "example" into the input. When "e" is pressed, the input reads "e" When "x" is pressed, the input reads "eex" When "a" is pressed, the input reads "eexea" When "m" is pressed, the input reads "eexeaeexm" When "p" is pressed, the input reads "eexeaeexmeexeap" And so on. This bug only occurs on Firefox for android, and does not occur on Firefox Focus for android. Has anyone run into this before?

dnolen12:10:48

I suspect that problem probably affects direct usage from JS - if so, might want to check the material UI issues first?

Reily Siegel12:10:30

I haven't seen any issues on their github, and pure js material-ui on their example site seems to work fine.

dnolen12:10:24

and versions match?

Reily Siegel12:10:31

I did notice that the on-change function was called twice, although Im still not sure why that would cause problems, unless there is something wrong with the event itself.

Reily Siegel12:10:02

Not the latest version of material-ui, but didnt see any mentions of firefox in their changelog.

dnolen12:10:51

might not be Firefox specific - but ok

dnolen12:10:39

I would probably debug this a bit further then to make sure it's not something logic related or ClojureScript specific (which I'd be skeptical about)

Reily Siegel12:10:41

I got it down to a pretty simple failing example: (defonce text (reagent/atom "")) (defn input [] [material/Input {:value @text :on-change #(reset! text (-> % .-target .-value))}])

dnolen12:10:51

I would drop some printlns to validate my assumptions in Firefox

Reily Siegel12:10:17

It seems that in all other browsers, on-change is called once, with the correct event.target.value. In firefox it is called twice: once with event.target.value as "", and once with the screwy result.

Reily Siegel12:10:12

Not sure why this only happens in cljs, as I dont see anything cljs specific.

dnolen12:10:42

I doubt it has anything do with CLJS

dnolen12:10:47

just whatever else you are using

dnolen12:10:52

like Reagent, etc.

Reily Siegel12:10:23

Found the reagent channel, Ill ask there.

oddsor12:10:25

I have a question about figwheel! When I make a new reagent project using lein new reagent, how would I require a javascript file? I'm thinking of a hypothetical scenario where I wanna make a new clojurescript project but reuse my react components!

dnolen13:10:15

you can't really just require JS files since usually there's a lot of assumptions baked into your JS

oddsor13:10:41

ok thanks! I was hoping to be able to import js files in a less robust way just while I was experimenting I guess 😄

dnolen13:10:08

you can't because they aren't "just" JS files

dnolen13:10:33

in the old days when people shipped real "just" JS files like jQuery etc. this was trivial

artur13:10:00

Anyone have experience is dockerizing clojurescript app?

artur13:10:28

When figwheel is running and I modify a file, figwheel fails in docker and I receive exception: Exception in thread "AWT-EventQueue-0" java.lang.NullPointerException

valtteri14:10:24

However I’m not using that setup anymore. I’m running figwheel on the host because io is quite slow with mounted volumes and It’s a bit of a hassle. I run other parts of my dev setup (db, elasticsearch etc.) in docker still though.

valtteri14:10:19

..and if I were building a new setup, I’d use figwheel-main instead of lein-figwheel, for simplicity.

artur14:10:25

Turned out I had to turn :repl to false in :figwheel

Roman Tsopin15:10:20

Is there any way to start nrepl with cljs.main?

borkdude18:10:56

I’ve got an if syntax exception now manifesting itself as:

java.io.NotSerializableException: clojure.spec.alpha$regex_spec_impl$reify__2436
Not sure if that’s my tooling or something specific to cljs 🙂

borkdude18:10:12

I think it’s coming from adzerk.boot-cljs.util/serialize-object util.clj: 56

borkdude18:10:59

(so probably tooling specific then)

juhoteperi18:10:16

@borkdude https://github.com/boot-clj/boot-cljs/pull/181 & referenced issue, boot-cljs tries to serialize exceptions to move them from threads to another but that fails for some classes

juhoteperi18:10:56

@borkdude Hmh, as I haven't come up with proper solution ten months I think I'll just merge the workaround, so fix should be available soon

mikerod23:10:08

This is odd to me because I thought React started with using functions and was then starting to push for js classes (which I haven’t been a fan of). And now going back away from classes? Hah.

mikerod23:10:20

I hadn’t seen this. Will definitely need to think through it

lilactown23:10:50

it's always used classes. just for awhile, it had it's own "class" implementation 😅

mikerod23:10:04

Hmm. Maybe that’s it

lilactown23:10:05

hence the whole React.createClass

mikerod23:10:01

I just felt like there was more emphasis on using functions as components before and then a bunch of features kept becoming you could only do by defining your own class.

mikerod23:10:10

But yeah, I’m sure you’re right there.

lilactown23:10:15

functions as components actually came much later. I think it was version 15?

lilactown20:10:14

a little reagent in your React starting in 16.7 😏

thheller20:10:50

which is completely breaking the reagent model 😉

lilactown20:10:39

:thinking_face: I don't think it will break reagent? unless you mean something different

thheller20:10:29

hmm it might not. it relies on the order of the use calls and a binding basically

thheller20:10:51

and in reagent things are in weird order because it first constructs the hiccup vectors

thheller20:10:04

and then translates those to ReactElements later

thheller20:10:25

might cause issues? not sure

lilactown20:10:27

yeah. It's not clear to me how we would use this in reagent today

lilactown20:10:11

but I see it as providing a lot of the same ergonomics as what the reagent + ratom API gives us today, in bare React

thheller20:10:16

it certainly looks a bit like reagent

lilactown20:10:49

the part I really like is that it doesn't require that finnicky form-2 stuff 😂

thheller20:10:19

I certainly like the class-less nature too

lilactown20:10:55

yeah I'm ridiculously excited for this

thheller20:10:32

a bit skeptical about the reconstruct everything on every render part

lilactown20:10:10

yeah that seems weird

lilactown20:10:05

but IME creating new functions on each render is a pretty low-value optimization compared to many other things

thheller21:10:35

but you have to love them unconditionally 😉

tomc20:10:07

In the clojurescript compiler config for a reagent project, I have :foreign-libs with one of the libs having :global-exports of {create-react-class preactCompat.createClass}. This was working w/ earlier cljs but isn't working now - the generated js looks like $goog$global$$["preactCompat.createClass"], but to be able to read an object property for an export, it should be $goog$global$$["preactCompat"]["createClass"] or something equivalent. Does this look like a bug or is there another way we're supposed to export object properties as namespaces?

tomc21:10:42

Ah, I see - this is a bug in the latest released version of cljs but it's fixed in master.