Fork me on GitHub
#shadow-cljs
<
2020-04-15
>
mauricio.szabo00:04:53

Is there any problem with the latest version? I just upgraded, and I'm not being able to watch a project, it fails with:

failed to parse websocket message {:type :repl/init, :repl-state {:shadow.cljs.repl/repl-state true, :current-ns ....

Pavel Klavík00:04:14

The piece of code where this is failing looks like this in the minified version:

Wh = function(a, b) {
        var c = oaa[a];
        if (void 0 !== c)
            return c;
        try {
            Th.push(a);
            var d = Uh[a]
              , e = shadow$provide[a];
            if (void 0 === d) {
                if (void 0 === e)
                    throw "Module not provided: " + a;
                d = {
                    exports: {}
                };
                Uh[a] = d
            }
            if (e) {
                delete shadow$provide[a];
                try {
                    e.call(d, $APP.Vh, Wh, d, d.exports)
                } catch (k) {
                    throw console.warn("shadow-cljs - failed to load", a),
                    k;
                }
                if (b) {
                    var f = b.globals;
                    if (f)
                        for (c = 0; c < f.length; c++)
                            window[f[c]] = d.exports
                }
            }
        } finally {
            Th.pop()
        }
        return d.exports
    }

David Pham05:04:23

Can you try to output to ES6? I think I had a similar issue and that resolved it.

thheller07:04:40

try :compiler-options {:output-wrapper false} too. looks like it has an issue with scoping somewhere?

Pavel Klavík10:04:36

Cool, switching to ES6 worked. For some reason, I was using es3 before.

awb9900:04:14

question: is there a plan to allow (require [ns]) to be available ?

awb9900:04:06

So that namespaces can be required outside the ns declaration

awb9900:04:29

I am trying to define different configs, so say :with-a :with-b :with-c or a combination thereof

awb9900:04:48

the different profiles will have different include sets

awb9901:04:28

I am currently ns-alias to get it done.

awb9901:04:52

But this turns out to be quite difficult as the project gets bigger

dpsutton02:04:23

Require doesn’t exist at runtime in cljs

dpsutton02:04:43

So the code couldn’t work in prod. Or is this for node?

awb9903:04:38

for browser

awb9903:04:58

I am talking build time.

David Pham05:04:43

You can use deps.edn to have different profiles, or google closure variables and dispatch on these

thheller07:04:28

@hoertlehner require must always be completely static so even if it was allowed outside the ns you still can't do anything that you can't do with ns anways

thheller07:04:12

you can't make anything conditional regardless

Aron07:04:42

If I ever disliked anything, it was the idea of conditional dependencies in javascript. Abuse of the abstraction : (

Aron07:04:36

never needed it but some people at previous jobs hated me for this opinion and tried to convince me why it should happen

thheller07:04:28

it is very useful to do sometimes ... just can't do it easily in an async context. thats really what makes everything difficult.

Aron07:04:09

There is nothing wrong with dynamic conditional require/import if it uses different syntax/semantics as the static/sync version : )

brunex09:04:41

Hi, question related with clojurescript macros: Given a list of `(def data [:foo :bar :baz])`, I want to dynamically generate:

(def foo (some-fn foo))
(def bar (some-fn bar))
(def baz (some-fn baz))
for some reason I'm not able to resolve the symbol data in a clojurescript macro 😕

brunex10:04:03

in clojure, I got something like this doing the job:

(def data ["foo" "bar" "baz"])

(defmacro test-macro
  [data]
  `(do
     ~@(map (fn [e]
              (let [e-name (symbol e)]
                `(def ~e-name (some-fn ~e))))
         (deref (resolve data)))))

(macroexpand-1 '(test-macro  data))

brunex10:04:01

the main issue is the resolve part

brunex10:04:05

I guess 😕

David Pham10:04:33

How do you guys manage headless (end to end testing)? I would interested to have a solution where I could define a sequence of some re-frame events and that snapshot the results? Does it exists?

mkvlr10:04:33

and have a function to check that the re-frame event queue is empty

mkvlr10:04:24

(defn ^:export ready
  "Returns true the tick after no events are left to process in the re-frame queue"
  []
  (let [state (.-fsm-state (:event-queue re-frame/default-frame))
        dr @deferred-ready]
    (cond
      (and (= state :idle) (not dr))
      (do
        (if (exists? js/requestIdleCallback)
          (js/requestIdleCallback   #(reset! deferred-ready true))
          (js/requestAnimationFrame #(reset! deferred-ready true)))
        false)
      (and (= state :idle) dr)
      true
      :else
      (reset! deferred-ready false))))

mkvlr10:04:31

this is for our re-frame fork https://github.com/nextjournal/freerange

👀 4
mkvlr10:04:58

this should work in regular re-frame:

mkvlr10:04:02

(defn ^:export ready
  "Returns true the tick after no events are left to process in the re-frame queue"
  []
  (let [state (.-fsm-state re-frame.router/event-queue)
        dr @deferred-ready]
    (cond
      (and (= state :idle) (not dr))
      (do
        (if (exists? js/requestIdleCallback)
          (js/requestIdleCallback   #(reset! deferred-ready true))
          (js/requestAnimationFrame #(reset! deferred-ready true)))
        false)
      (and (= state :idle) dr)
      true
      :else
      (reset! deferred-ready false))))

David Pham10:04:27

So once you events are done you export it to png and compare the images?

thheller11:04:08

@brunex it is very uncommon do write macros that depend on values of other vars. usually they should be self-contained and take all they need as an argument

Prometheus16:04:49

Anybody here use reitit in conjunction with shadow-cljs having issues with hot reloading? I’m struggling a bit

Aron17:04:29

I am a bit confused about the whole repl nrepl prepl socket repl situation... I realize it would be a bit much to ask for a complete picture, so can please someone just give me some hints on what are already fully working options for neovim/shadow-cljs? I have never done "repl driven development" but I like the sound of "auto-complete" 🙂

Spaceman17:04:28

shadow-cljs doesn't seem to hot-reload in iPhone simulator safari localhost

Spaceman17:04:32

what to do about it?

Spaceman17:04:00

it's working now

Prometheus19:04:57

I’m pretty sure it’s not a shadow-cljs problem

thheller19:04:11

reitit example often have this

Prometheus19:04:26

Hmm thank you i’ll look into it 🙂

thheller19:04:08

you can try :devtools {:reload-strategy :full} in your build config

thheller19:04:30

its slower but a bit more forgiving on architecture issues

Prometheus19:04:18

I got it to work 🙂

Prometheus19:04:23

Had to refactor my hooks

thheller19:04:07

@ashnur I don't know neovim or which kind of REPLs it supports. most editors use nREPL.

Aron19:04:41

Thanks, I am just checking out vim-iced. Sadly, cider comes with so many complications that I am way too anxious to try it 🙂

knubie00:04:06

@ashnur I use vim-iced with shadow-cljs and it works quite well

👍 4
Aron00:04:27

Thanks, seems like the way to go : )

Ivan Fedorov19:04:48

Having issues importing a js module dom-utils.js from a js module js-main.js which is required by a root.cljs . js-main.js is loaded just fine, but dom-utils.js isn’t.

;root.cljs
(ns website.main
  (:require ["./js-main" :as main]))

(defn init []
  (main/onDomReady))

; js-main.js
import {func1} from "./dom-utils.js"
export const onDomReady = () => func1("bar")

; dom-utils.js
export const func1 = (x) => foo(x)
All js files are laying in the same dir/package as main.cljs. In shadow cljs target is
:dev
{:target :browser
 :modules {:main {:init-fn website.main/init}}
 :output-dir "resources/public/website"
 :asset-path "/website"
 :compiler-options {:output-feature-set :es8}}
___________ Issue Browser says TypeError: Cannot read property 'func1' of null --------- I see dom-utils.js file in sources tab, by the path /website/cljs-runtime/website/dom-utils.js So perhaps I misconfigured output path or import.

thheller19:04:31

and whats the issue?

Ivan Fedorov19:04:51

updated the post

thheller19:04:16

dunno about all the fat arrows. not exactly sure how the closure compiler handles those

thheller19:04:58

try export const function func1(x) ... or so?

Ivan Fedorov19:04:51

yes, this works

Ivan Fedorov19:04:02

I can post this somewhere if that would be of any use

thheller19:04:02

frankly I forgot the exact semantics of => so I don't know if it should be considered a bug or not

Ivan Fedorov20:04:44

Hmm, I wasn’t fully honest. I also had

:compiler-options 
{:output-feature-set :es8}

Ivan Fedorov20:04:34

I disabled this :output-feature-set :es8 part. Arrows work now. If I re-enable that it doesn’t matter arrows or not, nothing from dom-utils.js will be visible in js-main.js

thheller20:04:46

yeah probably best to stay a bit conservative with JS features

thheller20:04:00

not everything is fully supported all the time

thheller20:04:16

getting it all to play nice with CLJS already requires several hacks 😛

simple_smile 4
Aron20:04:31

use babel to convert js first to ES5 then I am sure everything will work. 🙂

thheller20:04:41

it is more likely that causes more issues actually

Aron21:04:26

Is this because of some of Polyfills?

Aron21:04:49

or babel's version of es5 is buggy?

thheller21:04:00

the style of code it generates is different than what the closure compiler does

thheller21:04:07

so it might contain duplicated polyfills and stuff

Aron21:04:06

Maybe I am biased as a long term babel user, and honestly, I don't even like it or the whole situation, even so, it sounds like someone would purposefully write js instead of cljs (or maybe a colleague) and then they would use babel to make it more compliant, but then they would have to forget about what closure does and configure babel in an incorrect way. Plausible, of course, but if someone is in that specific situation, I think it's unfair to assume that they will make mistakes : )

Aron21:04:55

The way I use babel is to allow specific features, not in a blanket, solve everything at once way.

thheller21:04:35

the point is that closure is able to rewrite most JS features when needed and the code is guaranteed to work with the further optimizations closure does. the babel code is not.

Aron21:04:54

That is your point which I didn't debate. I just added a corollary. But let me stop here since I don't intend to argue minor thing, I respect both of our times more : )

Ivan Fedorov19:04:53
replied to a thread:and whats the issue?

Thanks again! 🍺❤️sheepy