This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2021-08-25
Channels
- # anglican (2)
- # babashka (53)
- # beginners (99)
- # brompton (1)
- # calva (28)
- # circleci (43)
- # clj-commons (4)
- # clj-kondo (176)
- # cljsrn (22)
- # clojars (7)
- # clojure (175)
- # clojure-australia (2)
- # clojure-europe (20)
- # clojure-germany (1)
- # clojure-uk (5)
- # clojurescript (195)
- # cursive (18)
- # datomic (13)
- # emacs (2)
- # farolero (9)
- # find-my-lib (6)
- # fulcro (8)
- # graalvm (12)
- # gratitude (5)
- # helix (11)
- # improve-getting-started (36)
- # introduce-yourself (3)
- # jackdaw (21)
- # jobs (2)
- # joker (2)
- # malli (65)
- # meander (24)
- # nbb (2)
- # off-topic (4)
- # pathom (2)
- # polylith (17)
- # portal (5)
- # react (3)
- # reagent (22)
- # releases (1)
- # ring (4)
- # shadow-cljs (79)
- # show-and-tell (2)
- # testing (5)
- # tools-deps (9)
- # xtdb (12)
I agree that I was surprised my file changes were causing a hot reload after requiring it from a REPL
So I am in the unfortunate situation of having to include some pre-minified javascript into my project. I am using the node-library target and trying to export something that another javascript library can consume.
{:target :node-library
:output-to "out/lib.js"
:compiler-options {:infer-externs :auto}
:exports {:hello react-cljs-poc.core/app}
I can run everything in dev fine, but when I go to do this build, closure is taking some of that already minified code and changing some keys in some objects. Those keys can't change sadly. The keys look something like this:
var Me = {
day: {},
week: {},
month: {},
year: {}
}
And after the closure compiler is done doing its magic it looks like this:
var Ij = {
day: {},
pd: {},
month: {},
year: {}
}
Short of turning off advanced compilation, is there anything I can do to make closure not do these sorts of transforms?I'm guessing there is some manual externing I could try to do prevent this. But anytime I get this new minified code I'd have to redo that, which feels suboptimal
:compiler-options {:infer-externs :auto}
is the default, you don't need to configure that
No, the object is in the pre-existing minified js
I don't directly touch that object at all. The js exports a react component. I call that react component. Right now that is literally it. No props, no nothing.
I had just straight it as a file and required it. I’m beginning to feel like I should have put it in node_modules. Will work on it again tomorrow.
what does "No, the object is in the pre-existing minified js" mean? how is it included in your build?
if you include it via https://shadow-cljs.github.io/docs/UsersGuide.html#classpath-js then it will end up going through advanced. so the only way to protect it there would be externs
Yeah, I was just straight up requiring a js file in the classpath. I moved it into node_modules and it worked. Figured that out after reading this > Resolves the JS via node_modules and includes a minified version of each referenced file in the build. It is the default for the :browser target. node_modules sources do not go through :advanced compilation. For me, I'd love to just be able to toggle that on a file level rather than having to put files in some particular location to get that behavior. But I get it and it is probably best that I go take this code and make it a package. (It is some propriety code that as shipped as a zip of poorly minified js. What I mean by the object being in the pre-existing minified js is that it is just an object literal in that js source file. I didn't realize requiring js files from node_modules vs requiring js files from elsewhere would have a behavior difference. I do admit I find that a bit strange.)
So I'd like to get a basic in-browser REPL going. Is this something I could leverage shadow-cljs for?
Yea kind of. If you start the build, then go to the shadow-cljs dashboard (localhost:9630 for me), then you can go to the Inspect Latest tab and use the "Runtime Eval" box at the bottom.
Hmm.. all I see there is No Taps yet. (tap> something) to see it here.
Guess I'll try updating shadow-cljs and see if that helps (I'm on 2.12.4).
what does "get a basic in-browser REPL going" mean? shadow-cljs browser-repl
does that?
if its in development you can build on top of cljs-eval
see https://clojureverse.org/t/status-update-inspect-cljs-eval/6074
only works while the watch
is running though. but besides that you can build all UI you want yourself
yeah exactly, in my app itself
I'll try building something on top of cljs-eval
, thanks
just to be clear: this is for local development only. this can't be part of a "release" app as shadow-cljs should never run in any production environment
right, yeah
but if you just want something you can add via :preloads
to aid local development that is totally fine
...on a related note, would it be possible to provide self-hosted CLJS (for eval) as a separate module, that can be loaded dynamically?
self-hosted is fine for now, but it sure would be useful to have something like this in production as well
no, not possible per se. you could run it in an iframe or so separately but not part of the main app running in the same context
alright
because of name mangling?
okay, shame
in theory, would it be possible to "co-mangle" the names for self-hosted/non-self-hosted code so they'd be compatible?
no. it is not just about mangling. :advanced
does so much more. removing dead code, inlining, collapsing namespaces, etc
ah okay
basically namespaces don't exist anymore with no way to restore them or map them back to anything meaningful
got it
...okay so how about this then
could I provide both simple and advanced builds?
so I'd default to advanced (for users) but somehow enable developers to run a (equivalent) self-hosted simple build
debugging in production
I use re-frame so if something is broken then I could just dump all my state and open it in the self-hosted build
yeah exactly
although I'm thinking I could use local storage to copy the state over to a new tab/window (that'd open something like
) to make the whole process completely transparent
(debug.my.domain would serve the self-hosted build to IPs in my VPN)
yeah but in my experience the problem isn't the data. the problem is "how did it get into this shape"
yeah sure
I'm already tracking and displaying re-frame state changes though so that's already solved
I'm embedding something similar to re-frame-10x in my app, so devs can see what's happening
for some situations though, I find it really useful to be able to manipulate data
so that's the main argument for having a REPL
(I mean, manipulate the data and have the changes reflected in the app)
sure, but just as the export you can also have a import thingy that just sets the new state
going full self-hosted means you are changing so much more about the structure of the code that you might not even run into the issues you are trying to debug in the first place
and if you are able to replicate the problem after switching to self-hosted mode you should also be able to replicated in a local watch?
yeah, but if I do it "in production" then it's trivial to reuse my session etc
I think replicating in a local watch would involve a lot of effort to work around stuff like my production CSP policy
still, if I had "dump/import data" buttons then I could support both those use-cases
for some problems access to the production backend probably isn't that important
yeah no clue what your app looks like. I have done the export thingy in the past and it helped debugging for sure but much less than first expected 😉
I was super excited at first and thought this is going to solve everything but ended up just being "hmm ok data is messed up but why?"
but I didn't have a track-all-changes thing so that would have helped a lot too I guess
heh alright
yeah I'm gonna go ahead and build this, and we'll see how useful it turns out to be 🙂
will do!