This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-06-11
Channels
- # announcements (1)
- # architecture (23)
- # beginners (189)
- # boot (1)
- # calva (62)
- # clj-kondo (23)
- # cljs-dev (9)
- # clojure (336)
- # clojure-dev (11)
- # clojure-europe (2)
- # clojure-italy (17)
- # clojure-nl (25)
- # clojure-uk (53)
- # clojurescript (12)
- # core-async (29)
- # data-science (1)
- # emacs (6)
- # fulcro (23)
- # garden (3)
- # graphql (2)
- # jobs (1)
- # joker (7)
- # off-topic (17)
- # om (2)
- # qlkit (1)
- # reagent (15)
- # reitit (18)
- # rewrite-clj (7)
- # shadow-cljs (176)
- # sql (1)
- # test-check (4)
- # vim (32)
- # xtdb (30)
Did something change with respect to modules that isn’t documented? I can build a code-split app with the last of the shadow 2.7 series, but if I use latest it tells me it cannot find my module.
It does build an output file though:
SHADOW_ENV.load({}, ["book.demos.dynamic_ui_main.js","shadow.module.ui-main.append.js"]);
@tony.kay only the initialization logic changed. in general that should only be an issue if you use shadow.loader
before it was initiated
But I was using cljs.loader, so I thought that didn’t apply. It’s ok I guess. I’m making shadow-cljs a requirement in Fulcro 3, so it won’t matter 🙂
Ah, is this new?
You only need to add :module-loader true to your build config. The loader will always be injected into the default module (the one everything else depends on).
hmm yeah it should be optional but I need to figure out a better way to see if its needed automatically first
otherwise you might need to call (shadow.loader/init "")
manually wherever your init happens?
@stefan.age font files are not related to CLJS compilation in any way so any non-webpack example of adding fonts will work
I just an interesting error on a new project:
The required JS dependency "process" is not available, it was required by "node_modules/prop-types/checkPropTypes.js".
The peculiar thing is that in an old project, prop-types
is also used by some library, but it works fine.Although I have no idea how it's all supposed to work given that the apparent source of the error is this line: if (process.env.NODE_ENV !== 'production') {
.
I think process.env
is available only for nodejs targets, not for browser targets. And yet the old project somehow works.
That worked, thank you.
But how is that supposed to work in production, given that the manual recommends installing shadow-cljs
as a dev dependency?
I don't think that's the case.
I just removed node_modules
, ran npm i --production=true
, and finally shadow-cljs release main
.
It gave me the same error about missing process
.
Oh, right. I remember now reading somewhere that you don't agree with the split of prod and dev dependencies because CLJS compilation deals with dead code anyway. But there's some virtue to it still. E.g. there are dependencies required only for testing, profiling, debugging, tracing. And while they won't end up being in the released JS file, their installation takes time. And if we think about CLJ dev dependencies, they also take space when you don't ship your whole app in a single uberjar.
think about it for one second. assuming you don't have the global shadow-cljs install (which you shouldn't rely on anyways) and you only have shadow-cljs in your dev dependencies (which you should)
having shadow-cljs installed in the project was pretty much ALWAYS required. it just sort of worked sometimes if you had the global install
production=true
is only for runtime for node apps, nothing that requires building will ever work with that
I see, thanks.
> how would you invoke shadow-cljs with npm i --production=true
lein yada-yada-yada
. Or via the code, in my case: juxt/kick.apha
- we've talked about it some time ago.
> having shadow-cljs installed in the project was pretty much ALWAYS required
So ideally, we should have 3 scopes instead of just prod and dev: running in production, running in development, building. And the shadow-cljs
dependency would fit only in the building scope, right?
to be accurate here. it isn't the missing shadow-cljs that causes the issue here. it is the missing https://github.com/webpack/node-libs-browser which shadow-cljs depends on (eg. for process
)
dunno why you'd split development and building. "development" seems to cover that in my mind
in case of browser things. NOTHING is required for "running in development" since the produced build output contains everything
Yeah, I probably described it poorly. I meant it more like a composition thing. The building scope is extracted to a separate one because it's common for every other scope. And the development scope just always includes the building one, yes.
> just keep it at prod/dev
But that's exactly what I'm trying to do! 😄 I just didn't realize that including shadow-cljs
as a dev dependency doesn't mean that it's useful only during the development.
So in my case, I'll probably just move it to the main list of dependencies, to make the dev list contain only the things that are not even supposed to be downloaded for the production build.
well .. I guess you can but it wouldn't be idiomatic in case you ever build a node app
shadow-cljs release
is still a development thing. only the output is a production thing.
Oh. I must admit I've never touched node. And hopefully, never will.
> shadow-cljs release
is still a development thing
So the production image building process is considered a development step? And "production" is only "running the production build"?
See, that's why the three hypothetical scopes are still somewhat useful. I guess it's just profiles in terms of lein
/`deps.edn`, but AFAIK package.json
doesn't support anything like it.
I just remembered another point towards not downloading dev dependencies during the production build. Apart from the saved space, it's also a safeguard against including something dev in the production env.
if you want to split into more profiles you can do that but even for deps.edn
you can't build an uberjar without some kind of dev dependency
and putting things into dev dependencies IS you safeguard against installing dev stuff in production
we are talking about the browser here anyways so it doesn't make sense to talk about production deps in any way
> you can't build an uberjar without some kind of dev dependency
Interesting point, thanks. Looking into all kinds of uberjars is still on my radar. So far, the experience has been far from pleasant.
> since the browser can't use your node_modules
folder anyways
> doesn't matter whats in it
Yes, I realize that. But I don't quite realize how that could ever work without profiles and without dead code elimination.
So, generally speaking, how does that even work in the browser JS world? Suppose I have some... I don't know, React debugging library that must be built into the application code in order to work. Obviously, you don't want to use it in production at all.
But at the same time, if you have to use dev dependencies during the release image build process, how do you prevent that debugging library from ending up in the production code?
That's why I wrote "and without dead code elimination" 🙂 Is the DCE our only hope here? Did things not work at all before it has been brought into the JS ecosystem?
hehe the fun times are ahead of us since with ESM you can't do the conditional require anymore
I feel like something like that is going on in the Python world right now, with requirements.txt
. Since there are no scopes and profiles anywhere, people just write multiple files with all kinds of suffixes, and then write scripts to use different files in different environments.
yeah. so far it looks like this is our future https://github.com/WICG/import-maps
Well at least they bring this point there. > JS is a complete mess 😞 And it pains me to see that CLJS cannot avoid some of it, even if we forget about imports at all. But to be honest, I'm still reluctant to just throw everything together during the release process. Imagine you have hundreds of MBs of libraries that are only useful during debugging. And that DCE has some bugs. What would you do?
So if a library is in node_modules
and nothing ever imports that library, it won't end up in the release JS files even if DCE is not used?
Anyway, thank you for the discussion. It has definitely been fruitful for me - now I know how to shave this yak a bit better.
Does uberjar'ing include only the dependencies that are explicitly imported? So if I use conditional imports, do I somehow have to explicitly make sure that the required dependencies end up being in the uberjar? Regarding single classes, or functions in case of CLJ - yes, Rich Hickey had a talk on it, a quite good one.
Ah. So it's even worse. If I forget to remove something from deps.edn
and never use it, it will still be there.
i'm currently looking at moving my boot driven cljs compilation over to shadow... and wondering whether to keep boot around or not. what other tools do people use for doing things like [a] dynamic configuration of closure-defines (from e.g. envvars) and [b] less compilation
this lets you override closure-defines from the CLI, similar to env vars I guess https://shadow-cljs.github.io/docs/UsersGuide.html#config-merge
ah, cool, i can definitely use that
and for things like less/sass compilation, do people generally use node stuff directly ?
is there an equivelant to webpacks copy-webpack-plugin
thay copies over static assets to the output directory? I want to put some ES6 node_modules during build over there
actually I suppose I need the html plugin... the one that recursively converts imports in html files. but then again, I may be able to simply use webpack :thinking_face:
Hi! I’m trying to get a project working using shadow-cljs and the cli/deps tools. It’s a re-frame app. Everything seems to be working as expected… except I can’t get the actual browser DOM to update when I make changes to the source files.
(ns alexandria.core
(:require
[reagent.core :as reagent ]
[re-frame.core :as rf ]
[day8.re-frame.http-fx]
[alexandria.events]
[alexandria.subs]
[alexandria.routes :as routes]
[alexandria.views :as views]
)
)
(defn main-panel
[]
[:h1 "Alexandria"]
; (let [active-panel (rf/subscribe [:active-panel])]
; [views/show-panel @active-panel]
; [:div [:h2 "Alexandria "]]
; )
)
(defn mount-root
[]
(rf/clear-subscription-cache!)
(println "mounting root")
(reagent/render [main-panel]
(.getElementById js/document "app")
))
(defn ^:export init
[]
; (routes/app-routes)
(println "Initializing")
(rf/dispatch-sync [:initialize-db])
(mount-root))
I’ve reduced it to just putting a h1 on the page. That works. When I change the string “Alexandria”, or change the h1 to an h2, shadow compiles it fine, the shadow-cljs dashboard page shows a compilation, and the shadow-cljs icon at the bottom left of the browser window appears. But the text on the page doesn’t change - the actual DOM doesn’t get updated.
I’m making some boneheaded mistake or omission, but I haven’t been able to find it.
@credulous in your shadow-cljs.edn, do you have something like {:devtools {:after-load alexandria.core/mount-root}}
?
in case you don't already have that key, the path is [:builds <something> :devtools ...]
hey folks, I'm using re-frame with shadow-cljs, when i update my component code and save it, hot code reload works and i can see in the console that my namespace re-evaluates but the dom doesn't update, i have to do a full refresh to see the dom changes
@lxsameer see the above conversation. do you have a lifecycle (ie. after-load
) configured to re-render your app? https://shadow-cljs.github.io/docs/UsersGuide.html#_lifecycle_hooks
actually it doesn't work in my case, apparently it's a caching issue, i changed the namespace but the log messages are still for the old one
look at the browser console. shadow-cljs will tell you what its doing. the rest is up to you
this is my browser log, http://dpaste.com/1934KF3
i don't get what you mean by "shadow-cljs will tell you what its doing. the rest is up to you"
the interesting this here is that , I removed the console.log expression for line 4 and 5
apparently if I want to use macros with side effects i should black list the namespace right
ok in this case it make sense to let the developer invalidate the cache for that ns in specific cases
for example I know when my macro would do the side effect and i can just invalidate the cache in that situation otherwise i still can benefit form the cache