Fork me on GitHub
#clojurescript
<
2018-07-09
>
souenzzo02:07:00

[FIXED] just disable parallel build I'm using the "webpack method" and it's working ok for dev, but when I try "advanced" build, it warns about some goog's namespaces.... I can safely ignore it?

Compiling ["resources/public/javascript/main.js"] from ["src"]...
Jul 08, 2018 10:58:29 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: target/cljsbuild-compiler-0/inferred_externs.js:39: WARNING - name goog is not defined in the externs.
goog.DEBUG;
^^^^

Jul 08, 2018 10:58:29 PM com.google.javascript.jscomp.LoggerErrorManager println
WARNING: target/cljsbuild-compiler-0/inferred_externs.js:40: WARNING - name goog is not defined in the externs.
goog.string;
^^^^

biscuitpants08:07:21

has anyone else encountered this error during closure compilation?

Jul 09, 2018 8:21:42 AM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: /out/cljs/core/async.js:7197: ERROR - Parse error. '}' expected
cljs.core.async.t_cljs$core$async61681.getBas
                                             ^
 
Jul 09, 2018 8:21:42 AM com.google.javascript.jscomp.LoggerErrorManager println
SEVERE: /out/js/radiant/test-runner/out/cljs/spec/alpha.js:1120: ERROR - Parse error. ',' expected
cljs.core._STAR_print_fn_STAR_ = ((function (_STAR_print_newline_STAR_61674_61684,_STAR_print_fn_STAR_61675_61685,sb__4432__auto__,ed,arg_spec,temp__5459__auto__,spec
                                                                                                                                                                      ^
 
Jul 09, 2018 8:21:42 AM com.google.javascript.jscomp.LoggerErrorManager printSummary
WARNING: 2 error(s), 0 warning(s)
ERROR: JSC_PARSE_ERROR. Parse error. '}' expected at /out/js/radiant/test-runner/out/cljs/core/async.js line 7197 : 45
ERROR: JSC_PARSE_ERROR. Parse error. ',' expected at /out/js/radiant/test-runner/out/cljs/spec/alpha.js line 1120 : 166
java.lang.Exception: Closure compilation failed

biscuitpants08:07:49

using: [org.clojure/clojurescript “1.10.126”]

thheller08:07:49

@biscuitpants looks like that CLJS output files were truncated or did not finish writing. closure probably has nothing to do with this. I have seen similar strange results like this when running 2 instances of the CLJS compile in parallel that write to the same output-dir. or maybe the disk is just full? should get an exception during CLJS compilation then though so I'm just guessing

biscuitpants08:07:27

interesting thanks @thheller - i don’t think more than one instance of the compiler is running. is it possible that a logger could be messing with the writer to the file?

biscuitpants08:07:31

i don’t think the disk is full

thheller08:07:25

no logger no but if you can check the /var/lib/buildkite-agent/builds/BuildkiteSlave-i-08751208534127368-1/cognician/monolith-develop/out/js/radiant/test-runner/out/cljs/core/async.js if it actually ends in .getBas

biscuitpants08:07:47

ok i’ll do that, trhying another build now

biscuitpants09:07:25

@thheller so it looks like if i turn off :language-in :ecmascript5 :language-out :ecmascript 5 compilation works again 🙂 we had that turned on for a bug in one of our dependencies. luckily, that bug has since been fixed upstream

thheller09:07:39

I don't see how that would produce the above situation but when it works it works 😉

biscuitpants09:07:36

neither, but with an entirely clean build with the option ON, it breaks. with a clean build, with it OFF, it works

thheller09:07:27

did you check if the files are actually truncated on disk?

biscuitpants09:07:04

not yet. trying to reproduce the broken situation again. i cleared .cljs/ and now i can’t hit that closure compilation issue again

jmckitrick11:07:28

What’s the state-of-the-art for re-frame table views, with sortable columns, filtering badges, etc?

jmckitrick11:07:00

Is there a component or group thereof that would be a good start?

thheller11:07:29

I use https://react-table.js.org which works well. I do not use re-frame though so can't comment on that

jmckitrick11:07:24

@thheller I’ll check it out.

vinai12:07:46

I'm looking to get a node based cljs.main repl with deps.edn up and running with an nrepl server, so I can connect from cider or proto-repl or anything. Seems like a common need, but I'm flailing 😞 I'm trying to move to deps.edn for new projects, after using lein project.clj until now. Does someone have a pointer to a gist or such maybe?

bhauman12:07:18

@vinai I'm going to recommend figwheel.main and CIDER here

bhauman12:07:57

There isn't a write up on how to do it yet, but it's pretty straight forward

bhauman12:07:24

I'll be happy to help if you have hiccups

wilkerlucio12:07:16

@vinai you can also try shadow-cljs, it has a good integration with deps.edn and its strait forward to use a node repl with it: https://shadow-cljs.github.io/docs/UsersGuide.html#deps-edn / https://shadow-cljs.github.io/docs/UsersGuide.html#_node_repl

vinai12:07:44

@bhauman Even with node? This is for a non-browser project. I thought figwheel was intended for browser use (at least that's how I've been using it).

vinai12:07:09

@wilkerlucio Thanks! I will check it out. Would have liked to use plain cljs.main to be honest, just for the sake of understanding the setup better. Still, will try it out.

vinai12:07:11

This seems like good advice for a cljs + figwheel browser repl, but like I said, no luck with node yet. https://gist.github.com/reedho/302fabea63ab3416200462e192c39827

bhauman12:07:17

@vinai figwheel.main works great with node

bhauman12:07:40

and with figwheel.sidecar you will need to launch node manually

bhauman12:07:52

after you complie

vinai12:07:13

So it would be responsible for recompiling changes and loading them into cljs?

bhauman12:07:30

you can use it with or without auto reloading

bhauman12:07:01

but it will watch and compile files and notify you when you get things wrong

vinai12:07:10

Brilliant!

bhauman12:07:14

and it will autoload them as well

mfikes12:07:35

I have this set up in one of my deps.edn-based projects. The one bit I haven’t explored is the nREPL aspect.

:aliases {:repl       {:main-opts ["-m" "figwheel.main" "-co" "compile-opts.edn" "-co" "{:main,my-project.core}" "-ro" "repl-opts.edn" "-d" "target/dev" "-t" "node" "-r"]}
           :build-dev  {:main-opts ["-m" "cljs.main" "-co" "compile-opts.edn" "-d" "target/dev" "-t" "node" "-c" "my-project.core"]}
           :test       {:main-opts ["-m" "cljs.main" "-co" "compile-opts.edn" "-d" "target/test" "-re" "node" "-m" "my-project.runner"]}
           :build-prod {:main-opts ["-m" "cljs.main" "-co" "compile-opts.edn" "-d" "target/prod" "-O" "simple" "-t" "node" "-c" "my-project.core"]}}}

mfikes12:07:08

This gets you a figwheel.main running reloading in node with clojure -Arepl

bhauman12:07:46

@mfikes I really reccomend the build file route 🙂

mfikes12:07:12

Yeah, I’m willing to try that @bhauman. Just exploring different ways to do this myself. 🙂

bhauman12:07:32

its just that having a stable unique name makes repl connections and automatic output-dirs easier to isolate

bhauman12:07:41

and maintain

bhauman12:07:36

@vinai I have figwheel.main working quite nicely in cider

bhauman12:07:49

with a pretty simple set up

bhauman12:07:59

@vinai there is also a #figwheel-main channel

vinai12:07:15

Thank you very much, this is great. I am unfortunately on a meeting call atm, but am eager to try it out!

vinai12:07:23

Noted down all the information.

mfikes12:07:36

@bharathmuraleedharan There is also a #cljsrn channel if you don’t get help here

Bharath12:07:48

okay thanks @mfikes, will try there too

schmandle13:07:34

Hi. Am I right in assuming that the :pseudo-names flag should not make any difference to the dead code elimination?

schmandle13:07:51

I have a situation where my app runs fine with :pseudo-names true, but fails with a "is not a function" error when its false. Stepping through the code in the browser debugger seems to suggest that the error happens in a React function, but there should be no UI stuff involved at this point. Stepping through with pseudo-names on, React is nowhere to be seen

schmandle13:07:08

The code in question is pretty simple:

schmandle13:07:41

(merge validated-word
            (if (contains? (:next validated-word) :end)
               (parse accumulated-words)
               {:valid-cmd false}))

dnolen13:07:42

:pseudo-names is a debugging feature

dnolen13:07:56

it’s not really meant to be used

schmandle13:07:09

yes, I enabled it in an attempt to debug 🙂

dnolen13:07:09

your issues sounds like an externs problem to me

schmandle13:07:41

yes, but there is no javascript dependenies involved here

schmandle13:07:28

the parse function is a javascript thing, but I can tell it finishes its job by littering the code with console.log statements. The failure seems to happen in merge itself

dnolen13:07:46

does parse have an extern?

schmandle13:07:25

just three lines:

schmandle13:07:43

var parser;
parser.parse;
parser.parseError;

schmandle13:07:49

and they have been working fine for a long time

schmandle13:07:41

I can try moving the call to parse out into a let binding to see if it fails earlier

dnolen14:07:59

did you try :pseudo-names false :pretty-print true?

schmandle14:07:00

Yes, it ran passed the parser, and I printed the result of the parsing which is just a map. It still crashes in the call to merge

dnolen14:07:08

to confirm it’s not renamed?

dnolen14:07:28

“and crashes in the call to merge” is lacking in detail 🙂

schmandle14:07:34

yes, I've tried all combinations of pseudo-names and pretty print

dnolen14:07:50

also how can merge work if parse is a JS thing?

schmandle14:07:02

I realize that. sorry. I am not able to make a small example

schmandle14:07:11

well, its a js thing wrapped in a cljs function

dnolen14:07:29

but what is the actual error message?

schmandle14:07:02

TypeError: v.j is not a function

dnolen14:07:20

what does this mean “its a js thing wrapped in a cljs function”

dnolen14:07:27

is parse a js thing or not?

dnolen14:07:48

v.j seems to indicate exactly what I guessed - externs aren’t working

dnolen14:07:11

I would ignore that “it worked before”

schmandle14:07:12

this is the actual function called

schmandle14:07:19

(defn validate-with-parser
  "transform result of parsing s into a predictable hash"
  [s]
  (let [parser-js-response (build-cmd (string/trim s))

        parser-response    (js->clj parser-js-response :keywordize-keys true)]
    (when-not (helpers/d "parser-response type " (:type parser-response))
      (helpers/error-log! "WARNING! Parser disagrees with Rose"))
    {:command    parser-response
     :type       (:type parser-response)
     :valid-cmd  (not (nil? (:type parser-response)))}))

dnolen14:07:38

still not enough information

dnolen14:07:44

what is parse?

dnolen14:07:55

what you’re showing is very disconnected

dnolen14:07:14

is parse parser.parse??

schmandle14:07:18

sorry, I renamed validate-with-parser to parse in the first snippet. "validate-with-parser" is the actual function called, and build-cmd is an even thinner wrapper:

schmandle14:07:22

(defn build-cmd
  "Wrap the javascript RAIRD syntax parser. Returns cmd objects that can be
  sent to server. Makes exceptions look like regular responses"
  [s]
  (helpers/d "Calling parser with " s)
  (try
    (.parse js/parser s)
    (catch :default e e)))

dnolen14:07:42

so build-cmd is what’s failing, yes or no?

schmandle14:07:07

no, build-cmd is returning a map, like expected

dnolen14:07:04

then did you get nitty gritty and try to log right before the failure?

dnolen14:07:12

in validate-with-parser

dnolen14:07:28

to find the offending line

schmandle14:07:17

yes, I log the response from validate-with-parser (which is now run before the merge in a let), and it prints out the expected map

dnolen14:07:43

trying to avoid talking in circles here 🙂

dnolen14:07:47

if it prints, then what’s wrong?

schmandle14:07:27

after it prints, I get the v.j is not a function error

dnolen14:07:44

so it can’t be in validate-with-parser

dnolen14:07:53

that invalidates the path you’re leading us down

dnolen14:07:25

so it has to be somewhere else

dnolen14:07:30

I would stop looking here

dnolen14:07:37

or get ready to at least

dnolen14:07:12

do you believe it’s validate-with-parser because source maps points there?

schmandle14:07:22

But if this is an externs thing, should it not fail even with :pseudo-names enabled?

dnolen14:07:35

I would stop thinking about :pseudo-names

dnolen14:07:44

ignore whatever other variables that might be introducing

dnolen14:07:02

just fine the actual location of the error

schmandle14:07:05

no, because I've littered the code with console.logs, and then searched for those strings in the compiled code, placed breakpoints and stepped through

dnolen14:07:55

:pseudo-names really can’t tell you anything - in general i find it works only if it fails with :pseudo-names too

dnolen14:07:03

if it doesn’t - don’t worry about it - you can’t use it

schmandle14:07:26

ok. good to know

dnolen14:07:58

one trick I’ve used that could help find the source of the error, more so than printing

dnolen14:07:07

you want to find the last log before the error

dnolen14:07:14

the error should prevent logging after

dnolen14:07:31

then you can search the advanced compiled code :pretty-print true for your debug string

dnolen14:07:55

Closure won’t move side-effects

schmandle14:07:52

I have logging before and after the call to merge. The one before prints, the one after does not. both maps that are fed to merge prints fine

dnolen14:07:05

I think this is probably the clue

dnolen14:07:16

you’re not using JS values in the map keys are you?

dnolen14:07:36

map keys should be immutable JS values (booleans, strings, numbers) or ClojureScript values only

schmandle14:07:23

this is the map returned from the parser:

schmandle14:07:29

{:command {:type "statOp", :command "tabulate", :variables ["kjon"], :subset nil, :options []}, :type "statOp", :valid-cmd true}

dnolen14:07:04

that’s merged?

schmandle14:07:41

no, that is before the merge. Its the second parameter to merge

dnolen14:07:10

and the other map is the same? Also what is v in the debugger? null? something else?

schmandle14:07:32

the other map is just s cljs map. not touched by any external js libraries. v looks like a map also

schmandle14:07:38

its not null

dehli14:07:10

Hi all, I'm trying to run a cljs function using the cli like: clj -m cljs.main -re node -m seeds.core however I'm getting that it can't find a node dependency (even though it is inside of the node_modules folder). Anyone know what I might be doing wrong?

bhauman14:07:45

@dehli you can't use npm dependencies without declaring them first to the compiler

dehli14:07:04

Would that be using npm-deps?

bhauman14:07:29

@dehli actually it depends on how you are requiring it

dehli14:07:42

I'm using node/require

bhauman14:07:35

hmmmm try (js/require and make sure that you are launching from the root dir of your project

bhauman14:07:44

which I'm sure you are doing

schmandle14:07:16

@dnolen I replaced the call to build-cmd with a hardcoded map, and that made the problem disapear. I am somewhat confused, but at least I now know that the problem is indeed the js parser 🙂 Thank you for pointing me in the right direction, and sorry for wasting your time.

dehli14:07:18

Thanks! Using js/require gives the same error. Note that I don't get this problem when I use cider-jack-in-cljs and I can build the project fine. It just throws this error when I'm trying to run that individual main

bhauman14:07:12

@dehli what is the specific error you are getting

dehli14:07:42

Error: Cannot find module 'aws-sdk'
    at Function.Module._resolveFilename (internal/modules/cjs/loader.js:594:15)
    at Function.Module._load (internal/modules/cjs/loader.js:520:25)

bhauman14:07:49

yeah so this is getting out of my area of expertise

bhauman14:07:16

it does look like main is doing something differrent

dehli14:07:21

No worries 🙂 Thanks a lot for your help! I'll keep poking around

akond15:07:50

guys, does somebody know why i get false here

(extend-type object
	IPrintWithWriter
	(-pr-writer [obj writer _]
		(write-all writer "blah-blah")))
(print (implements? IPrintWithWriter (js-obj))) ;; => false

mfikes15:07:44

@akond implements? doesn’t check native objects like satisfies? does. In short, since the printing code doesn’t check satisfies? you can’t override printing of object

akond15:07:29

is it made for a purpose?

akond15:07:24

i mean the fact that i cannot override printing of object?

mfikes15:07:40

I don’t know the rationale for why printing doesn’t fall back to satisfies?

mfikes15:07:38

Perhaps it was an oversight, with the last revision in the commit referenced above. Evidently prior to that change it was possible.

akond15:07:18

you think i should ask david?

mfikes15:07:24

@akond I’ve posed the question in #cljs-dev

akond15:07:36

oh, thank you, pal.

dnolen16:07:02

@akond @mfikes this seems like a misunderstanding about the original question

dnolen16:07:13

no your example will not work, intentionally

dnolen16:07:37

but you can still customize object printing and that should work

dnolen16:07:10

consider implements? a performance footgun - satisfies? should be preferred

akond18:07:23

@dnolen you mean i am not allowed to extend js base types?

dnolen18:07:45

@akond no, I’m just talking about implements? don’t use it

dnolen18:07:14

@akond there is a bug here, @mfikes filing a minor issue etc.

akond18:07:25

ok. thank you.

colindresj20:07:56

What’s the best way to elide some code in Clojurescript? I’ve been using goog-define, but am wondering if I could do so with a macro

mfikes20:07:21

@colindresj For library code, goog-define is better because it is compatible with the AOT cache feature. (See the note at https://clojurescript.org/news/2018-03-28-shared-aot-cache)

dhruv120:07:06

I’m running into a funny problem: I am building a small Tic Tac Toe page to get familiar with basic web design, react, ant design, and clojurescript. Here is the snippert of my code: [antizer.reagent/button {:value i :on-click #(do (println “Button: ” (.-value (.-target %))) (re-frame/dispatch [::events/square-clicked (-> % .-target .-value)]))} (or @sq “foo”)] Here is the translated HTML <button value=“7” type=“button” class=“ant-btn”> <span>foo</span> </button> So the text foo is a “span” tag in the button. What i see: Now if i click on the “foo”, the “on-click” handler on the button get triggered, but the “value” is nil. If i click outside the “foo” text (on the actual button) then the value is what i am expecting, in this case “7” I think this is becasue when i click on “foo” text, i am picking up the attributes of the “span” tag and it doesn’t have a “value” attribute attached to it. In this case, why does the “:on-click” handler still get activated? What i want: click anywhere on the button, and extract the correct “value” attribute.

dhruv120:07:13

reason for adding a “value” attribute to each button: i have 9 squares for “Tic Tac Toe”, and I am associating a value to each square from 1 to 9. when a square is clicked, I know which square from reading the value attribute is clicked and I can update my DB accordingly and calculate a winner after each click.

manutter5120:07:49

@dhruv1 First a tip: if you put triple backticks around your code, it will format nicely in Slack. Second, I’d recommend passing in value as a parameter to your component code, like this (or similar)

(defn my-tic-tac-toe-button [value]
  [antizer.reagent/button {:on-click (fn [e] 
                                       (println "Button:" value)
                                       (rf/dispatch [::events/square-clicked value]))}
   (or @sq "foo")])

dhruv120:07:47

ahh that’s right, i forgot about tripple backticks. thank you!

dhruv120:07:47

@manutter51 thanks. the value is associated with the button so I know which button was clicked if you’re asking me to pass in the value, then i am recording the value somewhere else. then how do i know which button was clicked?

manutter5120:07:59

What you do is make a button component (which you’ll probably call something nicer than my-tic-tac-toe-button like I did in my example). Then you’ll build your tic-tac-toe matrix using [my-tic-tac-toe-button 1], [my-tic-tac-toe-button 2], and so on

manutter5120:07:27

Each button will have its own value, which you passed in as the argument to my-tic-tac-toe-button

dhruv120:07:08

hmm. that’s actually what I’m doing here is the whole functino:

(defn square [i]
  (let [sq (re-frame/subscribe [::subs/square (str i)])]
    
    [ant/button {:value i
                 :on-click #(do
                              (println "Button: " (.-value (.-target %)))
                              (re-frame/dispatch [::events/square-clicked (-> % .-target .-value)]))}
     [:i {:class-name "far fa-circle"}]])) 

dhruv120:07:13

sorry ignore the [:i …] in the end. it was me trying something else

manutter5120:07:19

Ok, good, but when you dispatch your event, don’t get value from .-target .-value, get it from your argument i

lilactown22:07:28

is there a way to tell the closure compiler not to eliminate a namespace?

lilactown22:07:10

atm I'm having to add in very explicit side effects like a println in order for it to do what I want <_<