This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2023-06-23
Channels
- # announcements (3)
- # aws (1)
- # beginners (44)
- # biff (6)
- # calva (31)
- # cider (26)
- # clerk (12)
- # clj-kondo (9)
- # clojure (17)
- # clojure-dev (18)
- # clojure-europe (13)
- # clojure-norway (45)
- # clojure-uk (4)
- # clojurescript (34)
- # datomic (54)
- # dev-tooling (14)
- # emacs (19)
- # events (7)
- # honeysql (2)
- # hyperfiddle (51)
- # lsp (34)
- # malli (24)
- # matrix (1)
- # missionary (5)
- # off-topic (27)
- # re-frame (6)
- # reagent (18)
- # releases (2)
- # sci (6)
- # shadow-cljs (88)
- # vim (9)
Hey all, seeing a new error in my shadow-cljs repl: INTERNAL REPL ERROR: Got an unexpected reply from relay, check Inspect when inspecting a re-frame app-db (it is a lot of data, like maybe 200k, but its never been a problem before). Any clues of places to start looking for trouble would be appreciated.
Aha, to those that may run into this.. the app hit a runtime error and the state of the JS was wonky. A reload fixed it up.
I'm currently using @heroicons/react
for icons where I import with (:require ["@heroicons/react/24/outline" :as hero])
and then use it like [:div hero/ListBulletIcon]
but the full 400k icon set ends up in my production build. I've been trying to import just an individual icon in case that helps but struggling. The JS looks like this:
// node_modules/@heroicons/react/24/outline/index.js
module.exports.ListBulletIcon = require("./ListBulletIcon.js")
...
// node_modules/@heroicons/react/24/outline/ListBulletIcon.js
const React = require("react");
function ListBulletIcon(...) {...}
const ForwardRef = React.forwardRef(ListBulletIcon);
module.exports = ForwardRef;
I've tried to import with (require '["@heroicons/react/24/outline/ListBulletIcon$default" :as ListBulletIcon])
, but that obviously not quite right as ListBulletIcon
is nil
. Any suggestions? If I was able to get the import working, would it likely help the bundle size?If an ESM version exists, then try using that instead. IIRC the CJS modules are simply impossible to tree-shake
Thank you! After discovering that there was an esm
subdirectory in that NPM package, I was able to require the icons individually with:
(require ["@heroicons/react/24/outline/esm/ListBulletIcon$default" :as ListBulletIcon])
I also tried importing the whole ESM module to see if it was able to tree-shake that, but it wasn't.
(require ["@heroicons/react/24/outline/esm" :as hero])
Thanks again for the tip @U0479UCF48H - I would never have found that "esm" directory!
no problem… also shadow-cljs lets you write default imports with a :default
keyword
e.g.
(require '["@heroicons/react/24/outline/esm/ListBulletIcon" :default ListBulletIcon])
FWIW consider :default
deprecated. the official way to access default exports is "@heroicons/react/24/outline/esm/ListBulletIcon$default"
you can create a build report https://shadow-cljs.github.io/docs/UsersGuide.html#build-report
Does setting :jvm-opts
in shadow-cljs allow us to increase the stack size when invoking google-closure?
well, it does allow you to increase the stack size yes. just for everything, not just closure
That’s exactly what I need, thanks. As you can probably guess, it’s that stupid highlight.js file nobody ever hears of until java throws a StackOverflowException in CI builds…
not only is it crashing the build, it'll also bloat your build needlessly since those files are quite big and probably unused 😉
Yeah, my specific case involves a private deployment where bundle size is not a concern. I tried using custom resolves in :js-options
at first, but the file was still somehow being included, and build reports weren’t making it clear where this file is being required. So for now, I’m taking the stack size option and making a note to get rid of the one thing in my codebase requiring highlight.js
Getting shadow-cljs - failed to load module$node_modules$$js_joda$locale_en$dist$index
when attempting to use js-joda formatting https://js-joda.github.io/js-joda/manual/formatting.html
Any ideas?
portal.js:1288 TypeError: Cldr.load is not a function
at new WeekFields (index.js:317213:12)
at WeekFields.ofFirstDayOfWeekMinDays (index.js:317193:17)
at WeekFields.of (index.js:317167:27)
at eval (index.js:317255:33)
at eval (index.js:8:66)
at shadow$provide.module$node_modules$$js_joda$locale_en$dist$index (index.js:7:1)
at shadow.js.jsRequire (js.js:66:18)
at shadow.js.require (js.js:113:20)
at eval (blue.strategic.porta…shared.time.js:3:65)
at eval (<anonymous>)
yeah, that's what I'm thinking. Seems https://clojurians.slack.com/archives/C6N245JGG/p1682533852824579 saw it before
the strange thing is this all works fine for the unit tests, whose target is :node-test
as opposed to :browser
could just be that node is loading different dependencies than shadow-cljs is trying to bundle
All I did was
npm install @js-joda/core
npm install @js-joda/timezone
npm install @js-joda/locale_en
and then added these imports to starter.browser
:
(:require
["@js-joda/core" :as joda]
["@js-joda/locale_en" :refer [Locale]]
["@js-joda/timezone"])
Hey fellas, Is there any working example of full-stack ClojureScript application to demonstrate Server-Side Rendering (SSR)? When I try to import my view, it gives me an error:
import React, { useContext, useRef, useEffect, createElement, useState, useMemo, Fragment, useCallback } from 'react';
^^^^^^
SyntaxError: Cannot use import statement outside a module
at internalCompileFunction (node:internal/vm:73:18)
at wrapSafe (node:internal/modules/cjs/loader:1175:20)
at Module._compile (node:internal/modules/cjs/loader:1219:27)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1309:10)
at Module.load (node:internal/modules/cjs/loader:1113:32)
at Function.Module._load (node:internal/modules/cjs/loader:960:12)
at Module.require (node:internal/modules/cjs/loader:1137:19)
at require (node:internal/modules/helpers:121:18)
at /Users/sckn/projects/closed-source/lunara/cls/.shadow-cljs/builds/lunara.cls.backend/dev/out/cljs-runtime/shadow.js.shim.module$$ionic$react.js:3:38
at global.SHADOW_IMPORT (/Users/sckn/projects/closed-source/lunara/cls/target/backend/main.js:64:44)
(comment
;;;server-side rendering:
(reagent.dom.server/render-to-string [c/application]))
All I did is importing the namespace.Yeap. I wanna render my whole application inside my nodejs runtime (Shadow-CLJS Node application).
can't really help you, this is a node error. could be that the packages are just not compatible with node?
you can try setting :js-options {:js-provider :shadow :keep-native-requires true}
in the build config, that'll make shadow-cljs bundle more than it usually would for node builds
Let’s say I wanna render some piece of React in Back-End with Shadow-CLJS, what is the highly-overview steps of this in order to render it to string, so handler can send it?
@scknkkrer I think #sitefox does something along these lines, according to the Reamde: https://github.com/chr15m/sitefox/blob/main/README.md#templates (edited)
It does use react through reagent, don't know if you want to use react directly
Thanks for the help, so far @thheller. I was really looking deep to your works these days. Thanks for everything man!
I have an optimization question - If a namespace is declared as such:
[devcards.core :as dc :refer [defcard defcard-rg]
and the symbols defcard & defcard-rg are used, but not the alias dc -
Is it possible that not using the alias dc/
will lead to the namespace being ignored while doing a release build?I'm pretty sure devcards defaults to not emitting anything when optimizations are enabled
The devcards weren’t ending up rendering - but when I wrote out the namespace declarations very explicitly (not including :as dc
or un-used symbols, they did render.
They didn’t end up in the compiled javascript
seems like it shouldn’t be
this happens with :devcards set to true,
it’s really odd
:compiler-options
it works now, but only because I changed the require for namespaces where the cards were defined
{:builds
{:app
{:target :browser
:compiler-options {:devcards true}}}}
abbreviatedto answer your question: no, it is not possible that not using :as dc
causes code to be removed/unused. what however is possible is that the code is removed if nothing is actually used from that namespace. it is also a possibility that the code just gets moved/inlined if its only used once/a few times.
:advanced
output can be tricky to analyze manually, but I assure you that :as dc
has no effect whatsoever on the build output
Hello everyone, I have two different builds, one for development and one for testing. In my development build I have some devtools, but I remove those in my test build. I expect the tests to run without the devtools, but the tools end up appearing. I thought separating the builds would prevent this. Is there something I am misunderstanding about constructing builds?
need more details about the setup to answer. in general the build will include whatever is required. so if any of your namepaces require those devtools directly, then they'll be part of the build
Sorry about not giving enough detail. It turns out that I was looking in the wrong directory for the compiler output. Thank you for responding.
@scknkkrer I have a basic example of some server-side rendered react apps, but with Helix, not with Reagent. The idea is to just use whatever React already provides OOTB for rendering. I don’t think it’s possible to use SSR with reagent since it requires running an interpreter to dynamically create react elements, and it is almost certainly going to use react client API, not react server API. I’m probably wrong though since I’ve only ever done Node SSR with Helix
Hello @U0479UCF48H, Is it open-source, can I inspect your example? Also, is it an example or a POC, to be specific?
not open source, yet, and I was still trying to get emotion to server-side render CSS together with react, but havent gotten it working yet with that said, i can server-side render material ui components and use macchiato-core + a shared reitit router to resolve what pages to pre-render and serve
Are you using re-frame to handle state? Because I’ve just found out a really good flaw in it’s design. It can’t handle async. It uses a shared resources to handle things.
State is handled with refx instead. I follow a similar approach to SSR with Redux, where you share an initial app-db across client and server code and the server renders whatever it can with the initial app-db. Then when client-side loads JS, initialize app-db, hydrate, and continue rendering from there
You can probably get away with dispatching events on the server-side and embedding the app-db into the rendered HTML, but I haven’t tried this yet. For now I’ve followed an implicit rule where I do not use reitit’s route interceptors at all in this app, so that I can avoid having to modify the app-db as long as possible. Likewise, the routing data is stored outside of the app-db and instead in react context.
> I don’t think it’s possible to use SSR with reagent since it requires running an interpreter to dynamically create react elements, and it is almost certainly going to use react client API, not react server API. One way to get SSR in Reagent/Re-frame without a Node.js runtime is to write components in CLJC and use a Reagent-flavored Hiccup library on the server. Then you use the same "client-side loads JS, initialize app-db, hydrate, and continue rendering from there" approach. I'm hoping to write a blog post on how to do this sometime soon
It's a bit different way of thinking but it allows me to improve the First Content Paint of a Reagent/Re-frame app using only a JVM-based shadow-cljs setup. I can also export my Reagent/Re-frame app as a static site using only the JVM REPL
Here's an example I just finished working on for SSR with Reagent/Re-frame without a Node.js runtime: https://github.com/rads/rain.examples.todomvc https://todomvc.rads.dev
@scknkkrer I think #sitefox does something along these lines, according to the Reamde: https://github.com/chr15m/sitefox/blob/main/README.md#templates (edited)