This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2019-09-19
Channels
- # announcements (1)
- # beginners (115)
- # calva (7)
- # cider (8)
- # clj-kondo (3)
- # cljdoc (12)
- # clojure (50)
- # clojure-europe (4)
- # clojure-italy (5)
- # clojure-nl (6)
- # clojure-spec (70)
- # clojure-uk (88)
- # clojurescript (54)
- # core-async (16)
- # cursive (5)
- # datomic (31)
- # editors (4)
- # emacs (4)
- # fulcro (29)
- # graphql (17)
- # luminus (1)
- # lumo (2)
- # off-topic (37)
- # pathom (16)
- # random (2)
- # re-frame (5)
- # reitit (3)
- # rum (2)
- # shadow-cljs (192)
- # sql (11)
Are you doing some sort of Closure-unsafe object access? Like (.-field something)
as opposed to (goog.object/get something "field")
?
this is outdated advice. for code it is absolutely fine to use (.-field something)
. you just need to "tag" it either directly or indirectly as js to tell the compiler to not rename it. so either (.-field ^js something)
or `(fn [^js something] ...). see https://code.thheller.com/blog/shadow-cljs/2017/11/06/improved-externs-inference.html
Oh, nice! My awareness of this was coming purely from the vanilla CLJS compiler. Don’t profess to know much about shadow-cljs yet 🙂
this is a standard CLJS feature as well. https://clojurescript.org/guides/externs#externs-inference
(ns app.core
(:require [reagent.core :as r :refer [atom]]
["react-native" :as RN :refer [AppRegistry]]))
(defn app-root []
[:> RN/View {:style {:flex-direction "column"
:margin 40
:align-items "center"
:background-color "white"}}
[:> RN/Text {:style {:font-size 30
:font-weight "100"
:margin-bottom 20
:text-align "center"}}
"Hi Shadow!"]])
(defn init []
(.registerComponent AppRegistry
"YsjApp"
#(r/reactify-component app-root)))
I don't know if this belongs here, but I have a problem with shadow-cljs and cider. I jackin with clj&cljs and everything works as expected. except when I want to add dependencies via cljr. Then I get a message The refactor-nrepl middleware isn’t available! Did you remember to install it?
From the code of clj-refactor it tests the availability of (cljr--op-supported-p "find-symbol")
. But I thought, CIDER is injecting all the relevant parts in its jackin call.
So anyone has a clue how I get this running?
I was wondering whether from that project I could somehow distribute and package it into a form that would be consumable by lein based projects
@pyr you best bet is to create cljsjs
packages that provide those npm modules. shadow-cljs would continue using npm directly but others would fall back to cljsjs
otherwise you can add instructions on how to do it via webpack but that'll require manual work on the consumer side
@thheller so i've got an interesting lsof
output from my shadow build which is failing with Too many open files
- https://gist.github.com/mccraigmccraig/230d72c25b3a36d31c57fc5369ad0aab
there are a tonne of vnode: FD unavailable
entries... don't know what they are yet
hmm. although that might just lsof
reading structures which are in the middle of initialisation
@mccraigmccraig I don't know what that is. you were using lein right? could you try without that?
no, we're not using lein - just the shadow-cljs cli (invoked as a child_process.spawn
from gulp)
yeah, that's gotten transitively from our model module - it's has both clj and cljs stuff in it
it's just pulled in as a jar in the shadow build though
well it doesn't matter too much. what is strange is that the clojure and clojurescript jars are open so many times
i've now upped my ulimit -n
to 262144
, which seems ridiculously overspecified, and i'm still seeing the error
nothing unusual - there are macros, but no side-effecting macros
we call shadow-cljs from gulp, but it's just a plain setup once running shadow-cljs
yep, trying that now
I don't really know. any obvious file leak would show up for me too but there aren't any
yep, still get the issue with the shadow-cljs
command issued manually
our command is this
shadow-cljs --config-merge '{:output-dir "target/yapster-web/js" :compiler-options {:closure-defines {er-webui.env/app-deployment-platform "web" er-webui.env/api-url "" er-webui.env/expected-api-version "2.6.0" er-webui.env/client-build-version "2.6.0.0" er-webui.env/sentry-release "yapster-2.6.0.0" er-webui.env/log-level "info"}}}' release yapdev
it's as if the ulimit on the build process is getting lowered
i'm on macos ... the maxfiles ulimit on my shell process is massive - 262144
if shadow-cljs is using a subshell, it could be getting reset on a per-subshell basis.
dunno what subshell means but I think not. shadow-cljs is a npm script which then starts the java process
doesn't seem to be @gerred - if i create a bash
or zsh
subshell it's still got ulimit -n
of 262144
@mccraigmccraig you can try setting :compiler-options {:parallel-build false}
in your build config
yeah, although i'm pretty sure java
doesn't reset max-open-files
I'm using https://nodejs.org/api/child_process.html#child_process_child_process_spawnsync_command_args_options
but if i could find out how to query the ulimits on another process on macos i could find out... so easy on linux, haven't yet found out how on macos
spawnSync will inherit from the ulimit in the shell it's run from so you're good there
and that's consistent with what @mccraigmccraig is seeing
dunno how it would leak anything. cache is definitely closed after is is read https://github.com/thheller/shadow-cljs/blob/10553565f796281ce5fdf1b569c0c7ea2f4dabe9/src/main/shadow/build/cache.clj#L35
:compiler-options {:parallel-build false}
didn't change anything
that's not at all what I expected to happen. going to run that in a docker container now..
uh, wat ?
so spawnSync
is maybe setting a ulimit
which makes sense from the docs since it's inheriting the pipes, not the current shell :thinking_face: but i'm still not expecting to get separate ulimits
however... for me the output of
const { spawnSync } = require("child_process");
spawnSync("ulimit", ["-n"], {stdio: "inherit"});
is 262144
which is inherited
yes, same
@mccraigmccraig hmmm thought.
@studio in which context? it doesn't support outputting ESM but for commonjs you can just do (def ^:export default ...)
@gerred yeah, i'm trying it on a deb container on a linux kernel now
I am trying to get Storybook's new format working which is based on ES6 modules:
storiesOf('atoms/Button', module)
.add('text', () => <Button>Hello</Button>)
.add('emoji', () => <Button>😀😎👍💯</Button>);
is now:
export default { title: 'atoms/Button' };
export const text = () => <Button>Hello</Button>;
export const emoji = () => <Button>😀😎👍💯</Button>;
(def ^:export default #js {:title "atoms/Button"})
(defn ^:export text [] (reagent/as-element [:button "Hello"]))
it might be that storybook is actually trying to parse the ESM however in which case this wouldn't work since we are outputting commonjs
Stupid question, why would I need to use that? This is just basic JS at this point? export const text
etc
We already use their React
(:require
["@storybook/react" :refer (storiesOf)]
["@storybook/addon-actions" :refer (action)]))
Hmm, sorry, I pasted old code from your original demo. It's now:
import React from 'react';
import { Button } from '@storybook/react/demo';
export default { title: 'Button' };
export const withText = () => <Button>Hello Button</Button>;
So in this scenario am I better to rely on Reagent or the React dependency in package.json?
(ns foo.bar
(:require
[reagent.core :as reagent]
["react" :as react]
["@storybook/react/demo" :refer (Button)]))
(def ^:export default #js {:title "Button"})
(defn ^:export withText []
(reagent/as-element [:> Button "Hello Button"]))
(ns foo.bar
(:require
["react" :as react]
["@storybook/react/demo" :refer (Button)]))
(def ^:export default #js {:title "Button"})
(defn ^:export withText []
(react/createElement Button nil "Hello Button"))
I guess either way I would need to reference react or reagent so better if the Story file matched the real cljs file I guess
you might have more fun with https://github.com/nubank/workspaces since its all cljs
So this works
(ns frontend.ui.component.button-stories
(:require
[reagent.core :as reagent]
["react" :as react]))
(def ^:export default #js {:title "Button"})
(defn ^:export withText []
(reagent/as-element [:button "Hello"]))
Ok, I must have misunderstood this https://cljs.info/cheatsheet - apologies
So if I change the title, for example, then the hot reload in Storybook breaks
can't redefine non-configurable property "default"
Storybook can't be trying to access the files directly if they worked on initial load?
Thanks for the help! Looks like Storybook might not be a good fit - too many abstractions and dependencies when used in a Clojure project 😞
[nREPL] Establishing direct connection to localhost:53629 ... [nREPL] Direct connection to localhost:53629 established error in process filter: user-error: The shadow-cljs ClojureScript REPL is not available error in process filter: The shadow-cljs ClojureScript REPL is not available
ok @thheller - found something interesting - downgrading shadow-cljs from 2.8.52 down to the version we were previously using, 2.8.39, seems to fix our too-many-open-files issue
nope, i've already run it half a dozen times
previously it was borking 2-3 runs after a cache clear
it's not a macos only issue either - one of my devs is on an ubuntu laptop, and he encountered the issue too
you are just running shadow-cljs release ...
right? there is no server-mode instance running prior?
this is just shadow-cljs release ...
- users have also seen the issue with watch
builds
yes but with release no server-mode is started. so half of the stuff isn't even running in that case
if you have too much time you can try running each try each version to see when it started failing
i'll do a binary chop - i certainly don't want to be stuck on an old release!
https://github.com/thheller/shadow-cljs/commit/a21c3fcc42c48aef1d3734fe4c88936d51775e43 thats the only thing thats potentially opening/closing many files
@thheller it looks like it's [email protected] where the issue first arises
which includes the commit you referenced earlier https://github.com/thheller/shadow-cljs/commit/a21c3fcc42c48aef1d3734fe4c88936d51775e43
a simple git revert
of that commit causes conflicts, which are beyond my ability to fix in a couple of minutes, so i haven't tested out the hypothesis that it's that commit which is to blame
@mccraigmccraig if you happen to run into this while watch
is running could you try shadow-cljs clj-repl
(separate terminal) and dump @shadow.build.macros/active-macros-ref
?
yep @thheller i can do that
@mccraigmccraig try [email protected]
. I added some caching so the macro stuff doesn't touch so many files. maybe that helps?
that seems to fix the problem @thheller - i ran about 6 builds consecutively without issue - i've switched our dev branch to [email protected]
, so i should get some more reports from my other devs tomorrow

ohhh... so was it the URLConnection
which is holding files for file:
URLs open then ?
no, that was fixed a while ago. the change was only that it caches those lookups for files in .jar
got a first report in from a non-me dev now @thheller - 2.8.54
is confirmed to resolve the too-many-open-files issue!
thank you for the excellent support
maybe also upgrade to .55
for the emacs users. I accidentally broke the cider detection mechanism
oh, cool - we're mostly CIDER users, so i'll do that
btw - what drives you on shadow ? is it part of your job, or a side-project ?
started out as something I needed for work myself. now fun side-project, maybe my job soon when I do consulting and stuff around it 😉
well i'm bought into it - if/when you are thinking about it, let's talk about how we (yapster) can contribute to your ongoing work on shadow
for now there is https://www.patreon.com/thheller maybe github sponsors when it becomes available. code and documentation contributions are also very welcome but not sure which parts of the code are easy to contribute to 😛