Fork me on GitHub
#shadow-cljs
<
2022-01-31
>
barrell08:01:30

I’m trying to add entries to a module from a build hook (currently :compile-prepare). I update [shadow.build/config :modules :main :entries] and add the clojure namespaces there. I can confirm they are both on my build path and in the build config. However, when I make changes to these files, shadow-cljs does not recompile. 1. Is there something I need to do to add them to the watch? 2. The eventual goal is to set up different modules, but I was going for MVP by adding them to entries. Would it be possible to dynamically load different modules from a build hook? For context, I’m trying to set up something similar to next.js with directory based routing. So as I add more files, I read the classpath, build all the route into, then add files to the build. Modules would be great for code-splitting in the future but not needed for now

thheller16:01:49

sounds like what you are trying to do would require a custom :target. build hooks are definitely not meant to do any additional compilation and are not setup to do so

barrell08:02:33

Interesting. I guess I could spit to the shadow-cljs.edn file and run the watch command with nodemon - sounds like that might be the fastest solution? In the meantime do you have any info on writing a custom :target? I assume you mean a build would have :target :custom-browser ?

thheller08:02:05

but since you picked :browser you also picked the most complex one 😛

thheller08:02:13

:node-script is much simpler

barrell09:02:09

copies…. pastes 😂

barrell09:02:39

I will go through this in detail later this week but do you have something in mind you can point me towards? function or variable name that dictates what is rebuild for example 😄

thheller09:02:20

targets don't control rebuilds

thheller09:02:56

basically this function is called over and over again

thheller09:02:23

with a different :shadow.build/stage where the target impl can decide what it needs to do

thheller09:02:19

definitely very advanced stuff that is not documented anywhere

👍 1
thheller09:02:54

you could write a target that just delegates everything to the browser impl

👀 1
thheller09:02:19

but lets the user not write :modules at all and instead generate it

🙌 1
thheller09:02:28

I do not recommend doing so but it is possible

😅 1
barrell09:02:46

> targets don’t control rebuilds I’m confused - I just want to inject some namespaces into the entries and rebuild the module when those files change. That sounds like a custom target would be best?

barrell09:02:06

I think for my purposes it will just make better sense to write directly to the shadow-cljs.edn file and rebuild when that changes. It will only need to restart the process when a new file is added. If I need something more integrated it’s good to know where this is, thanks Quick question though - is it possible to specify a path to a shadow-cljs.edn file ? Or does it have to be in the dir that the command is run from

thheller09:02:34

must be at the root of the project

thheller09:02:07

sorry, not enough time to walk through a basic custom target right now

thheller09:02:17

it sounds to me like you want to generate a .cljs file instead?

thheller09:02:50

ie. you create a build {:target :browser :modules {:main {:init-fn }}} and then you generate either or some file it includes

thheller09:02:55

and just put it on the classpath

thheller09:02:11

that way the build automatically retriggers if you regenerate the file or make and other changes

thheller09:02:19

and you don't need to adjust the build config in any way

thheller09:02:43

imho maybe you just need a macro? never look at how js tools do something and replicate that

thheller09:02:18

imho you can do so much more in better ways with just macros sometimes

thheller09:02:13

I'm not sure I would actually recommend doing this but as an experiment for the shadow-cljs UI I did this

thheller09:02:23

create a regular defn and put some metadata on it

thheller09:02:47

then have a separate macro that collects all of the functions with such metadata and generate some code arround it

thheller09:02:02

sounds maybe like something you are trying to do?

thheller09:02:29

that would be the macro finding all the defn's with the metadata

thheller09:02:55

imho nothing should ever be done based on a filename or its location

thheller09:02:10

metadata allows so much more control and is so much more flexible

thheller09:02:19

the ns itself could also have metadata if needed

thheller09:02:27

all of it is accessible in a macro

thheller09:02:06

from the build side it is just a regular :browser build, nothing is ever generated elsewhere

thheller09:02:42

the macro is a little more complicated since I wanted it to be aware of :modules but it doesn't need to be

barrell09:02:50

I have cljs files on the classpath, they are not retriggering a build. Presumably because they are not part of the module. Metadata or filepath work fine for me, just need to get the code in those cljs files into the build without an explicit require

thheller09:02:22

well it needs to be part of the build. then it'll trigger a rebuild. it doesn't need to be directly part of the build config

thheller09:02:48

you need an explicit require. that is sort of the point of require 😛

thheller09:02:02

ie. only include what you actually need and nothing else

thheller09:02:14

if just everything was included because it was there that would create a big mess

thheller09:02:12

back to the macro example I still have my main ns require all the namespaces that have that metadata

barrell09:02:18

I guess I should say user-written require 😅 maybe the best way would be to just write to a manifest.cljs with a bunch of require statements

thheller09:02:28

I think this is totally fine and I wouldn't want it any other way

thheller09:02:57

its just a require, it is easily added or removed or renamed

thheller09:02:22

something like [shadow.cljs.ui.db.*] would make me feel extremely dirty 😛

thheller09:02:26

in your main app (:require [my.app.routes]) and then you generate (ns my.app.routes (:require [my.app.route-a] [my.app.route-b])) with some tool?

🙌 1
barrell09:02:48

this is a helper package to teach my friends how to code (starting with clojurescript). The time to first render is quite important for me - goal is to have a command to install then write a file and see it on the screen. Plenty of time to get to requires and metadata later 😄

barrell09:02:00

> in your main app `(:require [my.app.routes])` and then you generate `(ns my.app.routes (:require [my.app.route-a] [my.app.route-b]))` with some tool? this seems like the best way to do it!

barrell09:02:46

in the future if I wanted to support code splitting, could I add new modules to the build with a build hook, or would I need to adjust the shadow-cljs.edn file and restart the server?

thheller09:02:47

I'd argue that generation stuff is more complicated than writing it by hand

thheller09:02:50

but YMMV 😉

thheller09:02:23

modifications to the build config do not require restarts, they are just picked up and recompiled

barrell09:02:30

I don’t mind complicated, that’s why I’m trying to take on the brunt of it 🙂

thheller09:02:36

but I also wouldn't recommend modifying shadow-cljs.edn with tools

thheller09:02:56

no I'm saying that it makes things more complicated for everyone. the beginners too

barrell09:02:06

so I could see a file exists, add a module (with entries) to the build config in the pre-compile stage, and it would generate that new file?

thheller09:02:24

"you create a namespace and then require it". simple and straightforward

thheller09:02:40

"you create a file and then you run this other tool and wait for this other tool to pick it up" is that not simple in my view 🙂

barrell09:02:17

I’ve got ideas 😎 I appreciate the feedback but I’m building out a very specific curriculum. I know it’s not the way of the clojure world but I think it has value

barrell09:02:00

npm install captain-cljs
npx captain-cljs start
mkdir -p src/pages
echo "(ns pages.index) (defn +render [] [:div :hello-world])" > src/pages/index.cljs

barrell09:02:03

goal is to get that to load the component, and a css file alongside it to load locally scoped css module. They can start building in clojurescript while I teach them html, css, clojurescript, and eventually namespaces and requires, servers, shadow-cljs, etc

barrell09:02:55

I expect most people to graduate beyond the library but I’m trying to build as big of training wheel as possible for when they start so they can see something load from the get-go

thheller10:02:30

good luck 😉 just don't go too far off road with this. hiding important implementation details for too long will actually just create more problems in the long run IMHO

thheller10:02:13

I have talked to many create-react-app users that came to CLJS and didn't have a single clue how react actually works

barrell10:02:31

thanks, and thanks for all the support so far. I’ll try not to get too carried away but sometime I just like to make programming problems for myself 🤪

thheller10:02:33

I don't think that is a good thing 😉

barrell10:02:40

I’ll try to have an “offboarding” curriculum, would be interesting if one could gradually take off the training wheels. But make it work first and I’ll iterate! 😄

thheller10:02:18

I'm very interested to see what you come up with

thheller10:02:39

most people end up using a template that generates far too many files and never knowing what these files actually do

thheller10:02:48

so different approaches are definitely needed

barrell10:02:11

me too 😂 unless someone swoops in keep an eye out captain-cljs, I’m sure I’ll post here with questions and updates

barrell10:02:33

I’ll try not to use up more of your time than I have already 😂

thheller10:02:12

its fine. always happy to talk about cljs stuff 😉

barrell10:02:23

well if all goes well I’ll be funneling lots of members into the community to pester you with questions like “why do I have to require things?!”

barrell10:02:53

(first part was serious, second part was a joke 👼 )

Stefan10:01:20

Hi all, a few days ago we updated tools.deps.alhpa to the latest version (from 0.12.1109 to 0.12.1120). Now when I try to use shadow.cljs.devtools in my code (to start a shadow-cljs server and watch a target), I get errors like these:

; Syntax error compiling at (shadow/build/js_support.clj:1:1).
; namespace 'shadow.build.closure' not found
and:
; Execution error (NoClassDefFoundError) at jdk.internal.reflect.NativeMethodAccessorImpl/invoke0 (NativeMethodAccessorImpl.java:-2).
; Could not initialize class com.google.javascript.jscomp.DiagnosticGroups
Does this sound familiar to anyone?

thheller16:01:44

looks like a dependency conflict to me? this error you usually get when using an incorrect closure compiler version

Stefan20:01:08

I haven’t done lots of dependency debugging before, but I can’t find the issue. The tools.deps.alpha dependency update was the only thing that changed. When comparing the deps tree with the old and new version of tools.deps.alpha, this is the change set:

Stefan20:01:57

That doesn’t seem to point to anything related to closure / jscomp. The dependencies that you explicitly mention in the manual are identical.

thheller20:01:05

closure compiler uses guava so that might be the cause?

thheller20:01:58

this diff doesn't seem useful to me

thheller20:01:14

it might just be that the newer tools.deps version sorted things in a different order for some reason

thheller20:01:18

that already may cause issues

thheller20:01:48

what is the full stacktrace of the Could not initialize class com.google.javascript.jscomp.DiagnosticGroups exception

thheller20:01:15

guava is a common cause of issues and the closure compiler generally doesn't like having it on the classpath with any other version that it expects

thheller20:01:41

I also see a bunch of dependencies that you definitely don't need for a CLJS build, those should not be on the classpath while building CLJS

thheller20:01:53

thats why I generally recommend keeping CLJS stuff in shadow-cljs.edn

thheller20:01:09

or you can keep it in deps.edn but keep a CLJS and a separate CLJ alias

thheller20:01:16

:frontend and :backend or whatever

thheller20:01:43

putting all :backend deps in the root :deps and then adding CLJS stuff via alias is bad

Stefan20:01:30

Hmm maybe I’ll have to rethink my dev setup. I’m using polylith, which also adds some restrictions. But what I’m doing at the moment is that I start one single REPL running all backend servers and the (shadow-cljs-based) frontend. So basically something like:

(defn run-in-repl []
    (server1/start)
    (server2/start)
    (shadow.cljs.devtools.server/start!)
    (shadow-watch :frontend)
    :ready)

thheller20:01:22

you can do this but you have to deal with stuff like this conflict. its definitely fixable but you have to figure out where the problem comes from.

Stefan20:01:23

That requires having the jvm all dependencies at once if I understand things correctly, so that will then always (be likely to) cause such issues?

thheller20:01:42

generally it is a dependency conflict. if you give me the full stacktrace of the exception I can confirm that.

thheller20:01:10

I always recommend running CLJS stuff separately. you gain absolutely nothing by running it in the same JVM

Stefan20:01:14

Oh right sorry. I found the button in Calva to give it to me:

clojure.lang.Compiler/analyze (Compiler.java:6812)
clojure.lang.Compiler$InvokeExpr/parse (Compiler.java:3824)
clojure.lang.Compiler/analyzeSeq (Compiler.java:7113)
clojure.lang.Compiler/analyze (Compiler.java:6793)
clojure.lang.Compiler$BodyExpr$Parser/parse (Compiler.java:6124)
clojure.lang.Compiler$FnMethod/parse (Compiler.java:5471)
clojure.lang.Compiler$FnExpr/parse (Compiler.java:4033)
clojure.lang.Compiler/analyzeSeq (Compiler.java:7109)
clojure.lang.Compiler/analyze (Compiler.java:6793)
clojure.lang.Compiler/eval (Compiler.java:7178)
clojure.core/eval (core.clj:3202)
clojure.core/eval (core.clj:3198)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:87)
clojure.core/apply (core.clj:667)
clojure.core/with-bindings* (core.clj:1977)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:87)
clojure.main/repl (main.clj:437)
clojure.main/repl (main.clj:458)
clojure.main/repl (main.clj:368)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:84)
nrepl.middleware.interruptible-eval/evaluate (interruptible_eval.clj:56)
nrepl.middleware.interruptible-eval/interruptible-eval (interruptible_eval.clj:152)
nrepl.middleware.session/session-exec (session.clj:218)
nrepl.middleware.session/session-exec (session.clj:217)
java.lang.Thread/run (Thread.java:833)

thheller20:01:45

plz do it without calva

thheller20:01:58

just run clj with whatever aliases you have

thheller20:01:08

then (require 'shadow.cljs.devtools.api)

thheller20:01:13

that should already trigger the exception

thheller20:01:41

that exception trace has too much nrepl in it to be useful

Stefan20:01:28

user=> (require 'shadow.cljs.devtools.api)
Execution error (NoClassDefFoundError) at jdk.internal.reflect.NativeMethodAccessorImpl/invoke0 (NativeMethodAccessorImpl.java:-2).
Could not initialize class com.google.javascript.jscomp.DiagnosticGroups
user=>

Stefan20:01:16

#error {
 :cause "Could not initialize class com.google.javascript.jscomp.DiagnosticGroups"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error macroexpanding at (closure.clj:77:5)."
   :data #:clojure.error{:phase :execution, :line 77, :column 5, :source "closure.clj"}
   :at [clojure.lang.Compiler$StaticMethodExpr eval "Compiler.java" 1742]}
  {:type java.lang.NoClassDefFoundError
   :message "Could not initialize class com.google.javascript.jscomp.DiagnosticGroups"
   :at [jdk.internal.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2]}]
 :trace
 [[jdk.internal.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2]
  [jdk.internal.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.java" 77]
  [jdk.internal.reflect.DelegatingMethodAccessorImpl invoke "DelegatingMethodAccessorImpl.java" 43]
  [java.lang.reflect.Method invoke "Method.java" 568]
  [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 167]
  [clojure.lang.Compiler$StaticMethodExpr eval "Compiler.java" 1735]
  [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3705]
  [clojure.lang.Compiler$DefExpr eval "Compiler.java" 457]
  [clojure.lang.Compiler eval "Compiler.java" 7186]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 551]
  [shadow.build.js_support$eval15994$loading__6737__auto____15995 invoke "js_support.clj" 1]
  [shadow.build.js_support$eval15994 invokeStatic "js_support.clj" 1]
  [shadow.build.js_support$eval15994 invoke "js_support.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 619]
  [shadow.build.resolve$eval14164$loading__6737__auto____14165 invoke "resolve.clj" 1]
  [shadow.build.resolve$eval14164 invokeStatic "resolve.clj" 1]
  [shadow.build.resolve$eval14164 invoke "resolve.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 2793]
  [shadow.build.api$eval14156$loading__6737__auto____14157 invoke "api.clj" 1]
  [shadow.build.api$eval14156 invokeStatic "api.clj" 1]
  [shadow.build.api$eval14156 invoke "api.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 2793]
  [shadow.build$eval13806$loading__6737__auto____13807 invoke "build.clj" 1]
  [shadow.build$eval13806 invokeStatic "build.clj" 1]
  [shadow.build$eval13806 invoke "build.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 3204]
  [shadow.cljs.devtools.api$eval5278$loading__6737__auto____5279 invoke "api.clj" 1]
  [shadow.cljs.devtools.api$eval5278 invokeStatic "api.clj" 1]
  [shadow.cljs.devtools.api$eval5278 invoke "api.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [user$eval5274 invokeStatic "NO_SOURCE_FILE" 1]
  [user$eval5274 invoke "NO_SOURCE_FILE" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7136]
  [clojure.core$eval invokeStatic "core.clj" 3202]
  [clojure.core$eval invoke "core.clj" 3198]
  [nrepl.middleware.interruptible_eval$evaluate$fn__976$fn__977 invoke "interruptible_eval.clj" 87]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.AFn applyTo "AFn.java" 144]
  [clojure.core$apply invokeStatic "core.clj" 667]
  [clojure.core$with_bindings_STAR_ invokeStatic "core.clj" 1977]
  [clojure.core$with_bindings_STAR_ doInvoke "core.clj" 1977]
  [clojure.lang.RestFn invoke "RestFn.java" 425]
  [nrepl.middleware.interruptible_eval$evaluate$fn__976 invoke "interruptible_eval.clj" 87]
  [clojure.main$repl$read_eval_print__9110$fn__9113 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9110 invoke "main.clj" 437]
  [clojure.main$repl$fn__9119 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.main$repl doInvoke "main.clj" 368]
  [clojure.lang.RestFn invoke "RestFn.java" 1523]
  [nrepl.middleware.interruptible_eval$evaluate invokeStatic "interruptible_eval.clj" 84]
  [nrepl.middleware.interruptible_eval$evaluate invoke "interruptible_eval.clj" 56]
  [nrepl.middleware.interruptible_eval$interruptible_eval$fn__1007$fn__1011 invoke "interruptible_eval.clj" 152]
  [clojure.lang.AFn run "AFn.java" 22]
  [nrepl.middleware.session$session_exec$main_loop__1075$fn__1079 invoke "session.clj" 202]
  [nrepl.middleware.session$session_exec$main_loop__1075 invoke "session.clj" 201]
  [clojure.lang.AFn run "AFn.java" 22]
  [java.lang.Thread run "Thread.java" 833]]}
user=>

thheller20:01:17

I absolutely hate that they stopped printing the stacktrace by default 😛

Stefan20:01:56

Yeah I get your point 🙂

thheller20:01:54

try ( "com/google/javascript/jscomp/DiagnosticGroups.class")

Stefan20:01:27

#object[java.net.URL 0x736dd229 "jar:file:/Users/stefanmm/.m2/repository/com/google/javascript/closure-compiler-unshaded/v20211006/closure-compiler-unshaded-v20211006.jar!/com/google/javascript/jscomp/DiagnosticGroups.class"]

Stefan20:01:11

That seems right to me…

thheller20:01:17

and ( "shadow/build.clj")

Stefan20:01:28

#object[java.net.URL 0x60101212 "jar:file:/Users/stefanmm/.m2/repository/thheller/shadow-cljs/2.16.12/shadow-cljs-2.16.12.jar!/shadow/build.clj"]

thheller20:01:14

how does this exception trace still have nrepl in it?

thheller20:01:30

clj should not be using nrepl

thheller20:01:47

I really need you to type this all out into a regular CLJ. no calva, no editor, nothing extra, just the command line stuff

Stefan20:01:22

Oh sorry that’s indeed when I run outside of vscode but with the ability to jack-in, sorry

Stefan20:01:26

I’ll try again

thheller20:01:49

it seems to loose the cause exception

Stefan20:01:41

Clojure 1.10.3
user=> (require 'shadow.cljs.devtools.api)
Execution error (NoSuchMethodError) at com.google.javascript.jscomp.deps.ModuleLoader/createRootPaths (ModuleLoader.java:257).
'java.util.stream.Collector com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet(java.util.Comparator)'
user=> *e
#error {
 :cause "'java.util.stream.Collector com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet(java.util.Comparator)'"
 :via
 [{:type clojure.lang.Compiler$CompilerException
   :message "Syntax error macroexpanding at (closure.clj:77:5)."
   :data #:clojure.error{:phase :execution, :line 77, :column 5, :source "closure.clj"}
   :at [clojure.lang.Compiler$StaticMethodExpr eval "Compiler.java" 1742]}
  {:type java.lang.NoSuchMethodError
   :message "'java.util.stream.Collector com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet(java.util.Comparator)'"
   :at [com.google.javascript.jscomp.deps.ModuleLoader createRootPaths "ModuleLoader.java" 257]}]
 :trace
 [[com.google.javascript.jscomp.deps.ModuleLoader createRootPaths "ModuleLoader.java" 257]
  [com.google.javascript.jscomp.deps.ModuleLoader <init> "ModuleLoader.java" 147]
  [com.google.javascript.jscomp.deps.ModuleLoader <init> "ModuleLoader.java" 48]
  [com.google.javascript.jscomp.deps.ModuleLoader$Builder build "ModuleLoader.java" 139]
  [com.google.javascript.jscomp.deps.ModuleLoader <clinit> "ModuleLoader.java" 408]
  [com.google.javascript.jscomp.DiagnosticGroups <clinit> "DiagnosticGroups.java" 182]
  [jdk.internal.reflect.NativeMethodAccessorImpl invoke0 "NativeMethodAccessorImpl.java" -2]
  [jdk.internal.reflect.NativeMethodAccessorImpl invoke "NativeMethodAccessorImpl.java" 77]
  [jdk.internal.reflect.DelegatingMethodAccessorImpl invoke "DelegatingMethodAccessorImpl.java" 43]
  [java.lang.reflect.Method invoke "Method.java" 568]
  [clojure.lang.Reflector invokeMatchingMethod "Reflector.java" 167]
  [clojure.lang.Compiler$StaticMethodExpr eval "Compiler.java" 1735]
  [clojure.lang.Compiler$InvokeExpr eval "Compiler.java" 3705]
  [clojure.lang.Compiler$DefExpr eval "Compiler.java" 457]
  [clojure.lang.Compiler eval "Compiler.java" 7186]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 551]
  [shadow.build.js_support$eval10891$loading__6737__auto____10892 invoke "js_support.clj" 1]
  [shadow.build.js_support$eval10891 invokeStatic "js_support.clj" 1]
  [shadow.build.js_support$eval10891 invoke "js_support.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 619]
  [shadow.build.resolve$eval9061$loading__6737__auto____9062 invoke "resolve.clj" 1]
  [shadow.build.resolve$eval9061 invokeStatic "resolve.clj" 1]
  [shadow.build.resolve$eval9061 invoke "resolve.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 2793]
  [shadow.build.api$eval9053$loading__6737__auto____9054 invoke "api.clj" 1]
  [shadow.build.api$eval9053 invokeStatic "api.clj" 1]
  [shadow.build.api$eval9053 invoke "api.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 2793]
  [shadow.build$eval8682$loading__6737__auto____8683 invoke "build.clj" 1]
  [shadow.build$eval8682 invokeStatic "build.clj" 1]
  [shadow.build$eval8682 invoke "build.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 3204]
  [shadow.cljs.devtools.api$eval153$loading__6737__auto____154 invoke "api.clj" 1]
  [shadow.cljs.devtools.api$eval153 invokeStatic "api.clj" 1]
  [shadow.cljs.devtools.api$eval153 invoke "api.clj" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7170]
  [clojure.lang.Compiler load "Compiler.java" 7640]
  [clojure.lang.RT loadResourceScript "RT.java" 381]
  [clojure.lang.RT loadResourceScript "RT.java" 372]
  [clojure.lang.RT load "RT.java" 459]
  [clojure.lang.RT load "RT.java" 424]
  [clojure.core$load$fn__6856 invoke "core.clj" 6115]
  [clojure.core$load invokeStatic "core.clj" 6114]
  [clojure.core$load doInvoke "core.clj" 6098]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [clojure.core$load_one invokeStatic "core.clj" 5897]
  [clojure.core$load_one invoke "core.clj" 5892]
  [clojure.core$load_lib$fn__6796 invoke "core.clj" 5937]
  [clojure.core$load_lib invokeStatic "core.clj" 5936]
  [clojure.core$load_lib doInvoke "core.clj" 5917]
  [clojure.lang.RestFn applyTo "RestFn.java" 142]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$load_libs invokeStatic "core.clj" 5974]
  [clojure.core$load_libs doInvoke "core.clj" 5958]
  [clojure.lang.RestFn applyTo "RestFn.java" 137]
  [clojure.core$apply invokeStatic "core.clj" 669]
  [clojure.core$require invokeStatic "core.clj" 5996]
  [clojure.core$require doInvoke "core.clj" 5996]
  [clojure.lang.RestFn invoke "RestFn.java" 408]
  [user$eval149 invokeStatic "NO_SOURCE_FILE" 1]
  [user$eval149 invoke "NO_SOURCE_FILE" 1]
  [clojure.lang.Compiler eval "Compiler.java" 7181]
  [clojure.lang.Compiler eval "Compiler.java" 7136]
  [clojure.core$eval invokeStatic "core.clj" 3202]
  [clojure.core$eval invoke "core.clj" 3198]
  [clojure.main$repl$read_eval_print__9110$fn__9113 invoke "main.clj" 437]
  [clojure.main$repl$read_eval_print__9110 invoke "main.clj" 437]
  [clojure.main$repl$fn__9119 invoke "main.clj" 458]
  [clojure.main$repl invokeStatic "main.clj" 458]
  [clojure.main$repl_opt invokeStatic "main.clj" 522]
  [clojure.main$main invokeStatic "main.clj" 667]
  [clojure.main$main doInvoke "main.clj" 616]
  [clojure.lang.RestFn invoke "RestFn.java" 397]
  [clojure.lang.AFn applyToHelper "AFn.java" 152]
  [clojure.lang.RestFn applyTo "RestFn.java" 132]
  [clojure.lang.Var applyTo "Var.java" 705]
  [clojure.main main "main.java" 40]]}

thheller20:01:00

yes, that confirms guava as the cause

Stefan20:01:54

Because com.google.common.collect is in guava I assume?

thheller20:01:47

not actually sure which version you need since the closure compiler changed something in the way they bundle stuff

thheller20:01:58

not easy to tell anymore. its best to have none at all

Stefan20:01:28

I’ll try some combinations of excluding/overriding it then. Pfff. Complicated stuff. Huge thanks for helping me out Thomas!!

Stefan20:01:58

FYI: excluding guava in the tools.deps.alpha dependency seems to fix this issue. Not sure what other issues that’ll cause, but we’ll see…

👍 1
Rodrigo Mantica17:01:52

Hello. I’m running a next.js development server and a shadow-cljs watch on an :npm-module target build. I’m able to use my cljs output in my next.js files. However, as I am developing, the hot-module reload seems to pick up the cljs source files twice:

Error: Namespace "goog.debug.Error" already declared.
    at Object.goog.module (webpack-internal:///./cljs/cljs_env.js:163:13)
    at eval (webpack-internal:///./cljs/cljs_env.js:1891:8)
    at Object.goog.loadModule (webpack-internal:///./cljs/cljs_env.js:404:27)
    at eval (webpack-internal:///./cljs/cljs_env.js:1888:6)
I’ve seen similar issues other people have posted about and they all seem related to producing two cljs builds. This is not my current scenario, but rather using it in a js ecosystem with React Fast Refresh. Any tips on how to fix or debug here?

Nathan08:08:25

Hey @U02V40G5P9C 👋 Did you manage to find a solution for this error? I'm experimenting a bit with shadow and next.js and I'm stuck on the same scenario: the first load works well, but as soon as I change some code and save the file fast refresh comes into play and I get the error you described.

Nathan06:08:19

😕 ok, thanks, Rodrigo. I am still struggling with the same issue.

thheller17:01:52

I actually don't know if this can work at all. I think the fast refresh refreshes too much all the time which basically breaks all your code

thheller17:01:09

ie. it should never attempt to load goog.debug.Error twice since that definitely never changes between compiles

Nathan12:08:26

@U05224H0W do you know, by any chance, a workaround for this error? I tried to use your suggestion above, but still couldn't get it to work. I followed your proof of concept https://github.com/thheller/next-cljs and I can make shadow compile the pages as Next wants and works fine, but as soon as I change any CLJS I get the error Namespace "goog.debug.Error" already declared, same error happens if there is more than one page and in that case, it happens during the compilation already.

thheller13:08:32

in what context? I mean the error you fix by overriding what goog.provide does as shown in the link above?

Nathan13:08:28

I'm not sure exactly how/where to override goog.provide as you mentioned. I tried to use the snippet you shared in the entry point of the application/where pages are generated, but couldn't make the error go still.

Nathan13:08:54

I think my question is more: do you think it is possible to handle this error and get next.js working with shadow at the current version? Reading your past messages I understood that you were not sure if it would be possible to get by. I also checked with Next.js to see if it would be possible to turn off their fast refresh as you suggested, but apparently, it's not possible. PS: I'm able to generate the pages from CLJS as Next expects, etc. the integration works well, I'm just stuck with the error above being thrown on hot reload.

thheller15:08:34

yes, I think it is possible to get this working. shouldn't be much different from before

thheller15:08:49

but without more context I really cannot give any suggestions for what you might need to do

Nathan17:08:04

The context is that I'm trying to do is to run your proof of concept next.js repo here https://github.com/thheller/next-cljs It works fine without the error if I keep shadow CLJS in the version that is locked in the repo: 2.6.10, but as soon as I update the version, I'm using 2.19.8 now, I start to get the error above.

thheller17:08:23

that never had a working REPL as far as I can remember

thheller17:08:36

so I guess you are not talking about shadow-cljs doing the hot-reloading but webpack/next doing it?

thheller17:08:53

in that case you have to manually install the patch somewhere

Nathan06:08:24

Yes, the error starts when Next detects changes in the files generated by the hot reload from shadow-cljs. I'm unsure where/how I should install this patch. I tried to call this function in one of the entries of the application, but it doesn't seem to have any effect. Could you please elaborate where/how you imagine this patch is installed?

thheller07:08:28

shadow-cljs does no hot-reload in the next-cljs example repo you linked above. none. it will trigger a re-compile and I suspect that next is doing the hot-reload?

thheller07:08:41

I cannot tell you how to install or handle the patch since I don't know what you are building

thheller07:08:58

somewhere in the code that is getting executed you do that

thheller07:08:12

that could be from the code you generate in the hook, or in the CLJS code

thheller07:08:31

I haven't looked at next.js since I made that example

thheller07:08:24

if you share the repo that has the stuff that didn't work I can maybe tell you why it didn't work

Nathan07:08:58

I'm working exactly with your repo. The only difference is that I updated shadow-cljs, other than that it's the same repo.

Nathan07:08:52

Let me create a fork with the updated version.

thheller07:08:01

you probably also use a newer next.js? I mean otherwise the error should also happen with the older version?

Nathan07:08:51

Yes, I'm using a new version (12.2.3), the error doesn't happen with the version you used in the proof of concept (7.0.0).

thheller07:08:23

the older version just didn't have any hot-reload I think

Nathan07:08:31

You're right, they introduced what they call https://nextjs.org/docs/basic-features/fast-refresh as of version 9.4

Nathan07:08:11

Here's a fork with next and shadow-cljs versions updated: https://github.com/nathanqueija/next-cljs I updated the readme with instructions to run both shadow and next. What I'm doing to reproduce the error: • Start shadow build • Start next build • When all builds are ready and I go to localhost:3000 everything works fine • Change anything in the component, can be just a string that is being rendered • I assume that's when next hot reload comes into play and the error is thrown

thheller07:08:22

ok, so you made no attempt of adding the patch?

Nathan07:08:43

I did, I added a new entry and called the function you shared there, but no luck. Also tried to call directly in the page component, but still no luck.

Nathan07:08:58

Just didn't commit it because couldn't make it work.

thheller08:08:48

well, please add it

thheller08:08:04

one option would be to add import "../src/cljs/shadow.cljs.devtools.client.browser.js") here https://github.com/nathanqueija/next-cljs/blob/master/src/main/shadow/next_js.clj#L30

thheller08:08:17

but only do that for development builds

thheller08:08:28

however that means that shadow-cljs will also start hot-reloading

thheller08:08:39

having two separate hot-reloads is not a good thing and they will interfere with each other

thheller08:08:26

if there is a way to disable the hot-reload from next.js you should probably do that

Nathan08:08:44

I pushed a commit adding the patch in one of the entries and also adding the import you suggested in one of the pages but still got the error. From next perspective, it seems there is https://github.com/vercel/next.js/discussions/25712 to https://github.com/vercel/next.js/issues/13268#issuecomment-992463977.

thheller09:08:42

error - src/cljs/shadow.cljs.devtools.client.websocket.js (26:14) @ shadow$cljs$devtools$client$websocket$start
error - ReferenceError: WebSocket is not defined
    at shadow$cljs$devtools$client$websocket$start (webpack-internal:///./src/cljs/shadow.cljs.devtools.client.websocket.js:25:18)
    at shadow.cljs.devtools.client.shared.Runtime.attempt_connect_BANG_ (webpack-internal:///./src/cljs/shadow.cljs.devtools.client.shared.js:549:135)
    at Object.shadow$cljs$devtools$client$shared$init_runtime_BANG_ [as init_runtime_BANG_] (webpack-internal:///./src/cljs/shadow.cljs.devtools.client.shared.js:1117:20)
    at eval (webpack-internal:///./src/cljs/shadow.cljs.devtools.client.browser.js:1358:40)
    at ./src/cljs/shadow.cljs.devtools.client.browser.js (/mnt/c/Users/thheller/code/tmp/next-cljs/site/.next/server/pages/index.js:725:1)
    at __webpack_require__ (/mnt/c/Users/thheller/code/tmp/next-cljs/site/.next/server/webpack-runtime.js:33:42)
    at eval (webpack-internal:///./pages/index.js:5:106)
    at ./pages/index.js (/mnt/c/Users/thheller/code/tmp/next-cljs/site/.next/server/pages/index.js:198:1)
    at __webpack_require__ (/mnt/c/Users/thheller/code/tmp/next-cljs/site/.next/server/webpack-runtime.js:33:42)
    at __webpack_exec__ (/mnt/c/Users/thheller/code/tmp/next-cljs/site/.next/server/pages/index.js:1268:39) {
  page: '/'
}
  24 | shadow.cljs.devtools.client.websocket.start = (function shadow$cljs$devtools$client$websocket$start(runtime){
  25 | var ws_url = shadow.cljs.devtools.client.env.get_ws_relay_url();
> 26 | var socket = (new WebSocket(ws_url));
     |              ^
  27 | (socket.onmessage = (function (e){
  28 | return shadow.cljs.devtools.client.shared.remote_msg(runtime,e.data);
  29 | }));

thheller09:08:09

so the regular shadow-cljs devtools probably won't work due to it running in node and the browser I guess?

Nathan09:08:52

yes, if any browser APIs are used in the pages exported that wouldn't work because they go first through the server to be rendered by Next before being returned to the client.

thheller09:08:36

yeah sorry this is not an easy fix

thheller09:08:55

well, I guess you can hack it

thheller09:08:04

create a cljs ns with the patch call

thheller09:08:27

and import instead of the shadow.cljs.devtools.client ns in the hook output

thheller09:08:48

but getting websocket/repl to work is much more work

Nathan09:08:03

Tried to add the hack as you suggested but I guess the problem persists because any file exported has this statement in the first line var $CLJS = require("./cljs_env"); and it's exactly this file that throws the error online 1448 in this statement goog.module("goog.debug.Error"); . So as soon as the file with the patch is loaded the error will be thrown before any of the actual code from the pages being executed.

thheller09:08:04

yeah sorry I don't have time to look into this

thheller09:08:13

next seems to be doing a lot more than it previously did

thheller09:08:21

and I longer have the slightest clue what it is doing

thheller09:08:53

just gotta keep digging. I mean you can just modify the emitted cljs_env.js but not sure that changes anything

gratitude-danke 1
thheller17:01:18

thats the code you need to patch away that exception basically

1
thheller17:01:08

maybe its enough if you somehow do the same set! replacements somewhere but I don't know

thheller17:01:27

typically I'd say to just let shadow-cljs handle the reloading and have next ignore your CLJS output

thheller17:01:35

but dunno if thats even possible anymore

Rodrigo Mantica18:01:59

Ok I’ll have to figure out how react fast refresh works. Thanks for the insight.

zimablue21:01:57

I'm having an interesting problem where I get a stack overflow in shadow.umd_helper.js

zimablue21:01:02

at Object.get [as test_query] (/home/zimablue/projects/kangrok-ui/.shadow-cljs/builds/node/dev/out/cljs-runtime/shadow.umd_helper.js:11:16)

zimablue21:01:58

don't know why it is, I was trying to stably depend upon a local typescript project using "yarn link", that's the last thing I did so I think it's somehow related

zimablue21:01:25

just putting here in case it's obvious that it can only be one thing, or for the posterity of this slack once I work it out

olaf23:01:09

I’m having a problem with circular reference defining variables at compile time. I’m doing

:dev {:closure-defines {foo.core/DEV true}}
and inside src/cljs/foo/core.cljs
(ns foo.core)

(goog-define DEV false)

(def dev? (true? DEV))
Is working correctly but I cannot use dev? inside components. Since the application is loaded from that calls foo.core/init! and inside foo.core all the rest of the reagent components are loaded sequentially, if I (:require [foo.core :refer [dev?]]) inside a component is doing a circular reference. So the question is, how can I define variables at compile time that I can use inside components without creating a circular reference?