a node-script generated output needs a node_modules folder too?
i have some dependencies in package.json and after shadow-cljs release the generated file errors saying the dependencies are missing
(dependencies are missing = Error: Cannot find module)
In Cursive, I connect to the remote repl for shadow-cljs. Then I have to type (shadow/repl :app)
. Can I set this up to run that command by default when I connect to the remote repl?
@vale yes, node-script does not bundle dependencies by default. you can post-process the file with something like https://github.com/vercel/ncc to make it standalone. or just include the node_modules whereever you are publishing (recommended)
@caleb.macdonaldblack I don't think so. problem is that cursive needs to create the second nrepl session for CLJS, can't start out the REPL that way.
Ah ok. No worries.
I can’t seem to get shadow-cljs 2.14.0 working in my deps.edn setup. I do have the required dependencies at the correct versions (Clojure, ClojureScript, closure-compiler-unshaded), but somehow I end up getting this error every time I try to run shadow-cljs watch app
:
11:22 $ shadow-cljs watch app
------------------------------------------------------------------------------
WARNING: shadow-cljs not installed in project.
See <https://shadow-cljs.github.io/docs/UsersGuide.html#project-install>
------------------------------------------------------------------------------
shadow-cljs - config: /Users/rqf595/Code/louis-hjelmslev/shadow-cljs.edn
shadow-cljs - starting via "clojure"
--- SHADOW-CLJS FAILED TO LOAD! ----------------------
This is most commonly caused by a dependency conflict.
When using deps.edn or project.clj you must ensure that all
required dependencies are provided with the correct version.
You are using shadow-cljs version: 2.14.0
The important dependencies are:
org.clojure/clojure "1.10.3"
org.clojure/clojurescript "1.10.866"
com.google.javascript/closure-compiler-unshaded "v20210505"
Please verify that you are loading these versions.
You can find all required dependencies here:
<https://clojars.org/thheller/shadow-cljs/versions/2.14.0>
Please refer to the Guide for more information:
<https://shadow-cljs.github.io/docs/UsersGuide.html#failed-to-load>
-----------------------------------------------------
The error encountered was:
Syntax error macroexpanding at (closure.clj:78:5).
at clojure.lang.Compiler$StaticMethodExpr.eval(Compiler.java:1742)
at clojure.lang.Compiler$InvokeExpr.eval(Compiler.java:3705)
at clojure.lang.Compiler$DefExpr.eval(Compiler.java:457)
at clojure.lang.Compiler.eval(Compiler.java:7186)
at clojure.lang.Compiler.load(Compiler.java:7640)
at clojure.lang.RT.loadResourceScript(RT.java:381)
at clojure.lang.RT.loadResourceScript(RT.java:372)
at clojure.lang.RT.load(RT.java:459)
at clojure.lang.RT.load(RT.java:424)
at clojure.core$load$fn__6856.invoke(core.clj:6115)
at clojure.core$load.invokeStatic(core.clj:6114)
at clojure.core$load.doInvoke(core.clj:6098)
at clojure.lang.RestFn.invoke(RestFn.java:408)
at clojure.core$load_one.invokeStatic(core.clj:5897)
at clojure.core$load_one.invoke(core.clj:5892)
at clojure.core$load_lib$fn__6796.invoke(core.clj:5937)
at clojure.core$load_lib.invokeStatic(core.clj:5936)
at clojure.core$load_lib.doInvoke(core.clj:5917)
at clojure.lang.RestFn.applyTo(RestFn.java:142)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$load_libs.invokeStatic(core.clj:5974)
at clojure.core$load_libs.doInvoke(core.clj:5958)
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.core$apply.invokeStatic(core.clj:669)
at clojure.core$require.invokeStatic(core.clj:5996)
at clojure.core$require.doInvoke(core.clj:5996)
at clojure.lang.RestFn.invoke(RestFn.java:551)
at shadow.build.js_support$eval11454$loading__6737__auto____11455.invoke(js_support.clj:1)
at shadow.build.js_support$eval11454.invokeStatic(js_support.clj:1)
at shadow.build.js_support$eval11454.invoke(js_support.clj:1)
at clojure.lang.Compiler.eval(Compiler.java:7181)
at clojure.lang.Compiler.eval(Compiler.java:7170)
...
...
...
at clojure.lang.RestFn.applyTo(RestFn.java:137)
at clojure.lang.Var.applyTo(Var.java:705)
at clojure.main.main(main.java:40)
Caused by: java.lang.NoSuchMethodError: 'java.util.stream.Collector com.google.common.collect.ImmutableSortedSet.toImmutableSortedSet(java.util.Comparator)'
at com.google.javascript.jscomp.deps.ModuleLoader.createRootPaths(ModuleLoader.java:257)
...
...
...
at java.base/java.lang.reflect.Method.invoke(Method.java:564)
at clojure.lang.Reflector.invokeMatchingMethod(Reflector.java:167)
at clojure.lang.Compiler$StaticMethodExpr.eval(Compiler.java:1735)
... 211 more
@simongray thats a dependency conflict on guava
I see. How do you know that, though?
com.google.common.collect.*
is a guava package
aha
Thank you. Hm, still kinda puzzled why this is now seemingly an issue.
do you have your server-side CLJ stuff in the default deps.edn
:deps
? might make sense to move them to a :server
alias or so
yes
so that they aren't loaded when running CLJS, kinda helps avoiding such conflicts
Makes sense!
(also why I typically recommend keeping your CLJ and CLJS setups apart)
but keeping it all in deps.edn with aliases is totally fine
I guess I’ll make a split into a :backend and :frontend aliases and then keep CLJC libs in the root
Yeah, I like the utility of a single file
Ok, so moving the deps into aliases worked! 😄
Thank you, once again
i went with ncc because i couldn't figure out how to make my node_modules "minimal"
BTW @thheller the link in this message
WARNING: shadow-cljs not installed in project.
See <https://shadow-cljs.github.io/docs/UsersGuide.html#project-install>
doesn’t seem to lead anywhere (the #project-install part specifically).Just FYI
oh right. I guess I forgot to write that section 😉
Haha
It seems to work fine anyway, so why the warning?
installing npm shadow-cljs ensures that some runtime dependencies are also installed. ie. ws
for node builds or node-libs-browser
for browser polyfills. can work without but may fail.
I see.
oh and of course it also ensures that you are not dependent on some global shadow-cljs install, which may drift in versions and so on.
In a macro, I need to check if a symbol resolves to an undefined var. Calling (cljs.analyzer/resolve-var env sym nil false)
triggers an error :
> Wrong number of args (2) passed to: shadow.build.cljs-hacks/shadow-resolve-var
Is this a known bug, is there a workaround or a better way ?
@leonoel just call it with 2 args?
arity 2 works but then how to reliably check that the var is undefined ?
hmm I must have missed the change where the extra arity was introduced. that only used to have 2 or 3
should I open an issue ?
already fixed in master
just trying to find a place where the 4th arity is actually used anywhere 😛
ah, its only used once internally. I guess you are the first trying to use it in what way 😛
awesome, thanks !
just released 2.14.1 with that fix
Hello! is there a way to support modules when :target :karma
is used? Now I am getting
“Uncaught Error: shadow.loader API was called before shadow.loader.init!
You are probably calling module loader too early before shadow-cljs got fully initialized.”
not sure karma allows that
From what I saw we need to append shadow.loader.init("");
somehow to the output, but have no idea how to do that properly
that is true in theory but not enough
since no modules are configured it'll then just fail wherever you are calling load
how do you use the loader? typically that code should not be part of tests?
I mean the code should just be loaded directly in the test?
another component is loaded in component I’m testing, so I’m not calling it directly but it is called on certain test scenarios
actually I have tried it with :browser-test
and only adding `
:module-loader true
was enough, without specifying modules. Also I’m requiring the namespace which should be loaded in tests directly, so maybe it is a reason why they are not failingsomething must be calling something from shadow.loader
. otherwise you wouldn't get that error.
in :browser-test
you can set :module-loader
since it is built on the :browser
target. :karma
is not so that won't work there
but :browser-test
still won't be able to actually use the shadow.loader
api in any way
@thheller I haven’t prepared an example yet, but it seems I have found workaround for my issue by adding js file with next content
(function () {
goog.global.shadow$modules = {infos: {test: null}, uris: {test: []}}
shadow.loader.init("");
})();
to karma.conf.js -> filesstill don't know why you need that but looks fine
@thheller https://github.com/Valdermeyder/karma-modules-support/tree/master I have created a small but enough to reproduce example
well yeah but that is missing the entire context? I mean why do you call the loadable in the test in the first place? is that rendering actual UI code or what are you doing?
I am not calling it in the first place. It is called by the function which is tested. I understand you concern that in this example it looks like a first call but in my real case it is one of the things which happen. In general the context is when user have certain permissions call this method from another module. It was split by modules to load this additional code only for users which have this certain permission. I’ll not argue that it is the best solution which can be implemented but it is already done and I’m not in charge to change it right now.
Anyway I think the problem of running karma tests when modules and lazy load are used is not related to the context. As you can see it fails even in very simple example.
(ns my.app-spec
(:require
[cljs.test :as ct :refer [deftest is]]
[shadow.loader :as sl]
[<http://my.app|my.app> :as app]
[my.core]))
(ct/use-fixtures :once
(fn [test]
(sl/init "")
(test)))
may also workI'm really unsure how to treat loader related things in tests. since it can't actually load a module the test using it becomes kind of pointless
The example above will work only once, the next test suite will fail at least from what I saw in the code.
yeah, it is probably hard to achieve fully but when your require lazy loadable namespace in the test (e.g. my.core
), lazy loader works fine, so I think here is only a matter of not failing :karma
target when modules are used
I am not big fun of mocks but probably with-redefs
can be used somehow to stub parts of the lazy loaded namespaces in case we don’t want to require them explicitly
@thheller are you okay to open issue in GitHub for that case?
sure
hey 👋 does this error ring a bell on someone?
❯ node_modules/.bin/shadow-cljs watch webapp
shadow-cljs - config: /Users/wcalderipe/dev/foo-project/shadow-cljs.edn
shadow-cljs - updating dependencies
#
# A fatal error has been detected by the Java Runtime Environment:
#
# Internal Error (sharedRuntime.cpp:531), pid=17169, tid=5635
# Error: ShouldNotReachHere()
#
# JRE version: OpenJDK Runtime Environment (16.0+14) (build 16+14)
# Java VM: OpenJDK 64-Bit Server VM (16+14, mixed mode, tiered, compressed oops, g1 gc, bsd-aarch64)
# No core dump will be written. Core dumps have been disabled. To enable core dumping, try "ulimit -c unlimited" before starting Java again
#
# An error report file with more information is saved as:
# /Users/wcalderipe/dev/foo-project/hs_err_pid17169.log
#
# If you would like to submit a bug report, please visit:
# <https://bugreport.java.com/bugreport/crash.jsp>
#
===== ERROR =================
ENOENT: no such file or directory, open '/Users/wcalderipe/dev/foo-project/.shadow-cljs/classpath.edn'
=============================
os macOS 11.4 (20F71)
shadow-cljs: 2.11.11
java
openjdk version "16" 2021-03-16
OpenJDK Runtime Environment (build 16+14)
OpenJDK 64-Bit Server VM (build 16+14, mixed mode)
odd. no clue.
do you also get that error with lein or deps.edn? it happens during dependency downloading? so even before shadow-cljs even starts?
yeah, I also get that just by running clj
on the terminal. definitely not related to shadow-cljs
thanks!
What is the correct way of including firebase into a cljs project?
npm install it and require it in your ns
And how would the require look like? (:require [“firebase”]) ?
I am really confused about the js/ prefix and why using it
you don't use js/
for this
js/
is for accessing global variables
maybe this helps https://github.com/jacekschae/shadow-firebase
my project cannot see the firebase imported, like your examples, and I don’t know how to fix this
@thheller Yes, I think I follow it
don't know how you imported it or how you accessed it, so can't say
its in a package.json
thats the only place where it is ref.
that doesn't do anything without requiring it in your code
(:require [cljs-bean.core :refer [->clj ->js bean]]
;["firebase/app"]
;["firebase"]
;["firebase" :as firebase]
;["@firebase/app" :refer (firebase)]
some of my attempts
https://github.com/jacekschae/shadow-firebase/blob/master/src/app/fb/init.cljs
I’ll try
usually helps if you have JS examples, those translate 1:1 regarding the requires
I think there is something else, not the requires
something with my config
but I have no grasp of it because there are so many loose ends right now
this requires no extra config at all
unless I’ve done something stupid in my shadow-cljs.edn
hard to say without seeing it or the code 😉
{:deps {:aliases [:dev]}
:dev-http {8000 "classpath:public"}
:nrepl {:port 7002
:middleware []}
:builds {:test {:target :browser-test
:test-dir "resources/public/js/test"
:ns-regexp "event2-test$"
;:runner-ns tests.client-test-main
:devtools {:http-port 8021
:http-root "resources/public/js/test"}}
:app { :git-inject {:version-pattern "^v/(.*)$"
:ignore-dirty? true}
:target :browser
:build-hooks [(shadow-git-inject.core/hook)]
:compiler-options {:closure-defines {app.system.config/version :shadow-git-inject/version}}
:output-dir "resources/app/js"
:asset-path "/js"
:module-hash-names 4
:modules {:main {:init-fn app.core/init!}}
:dev {:dependencies [#_[day8.re-frame/tracing-stubs "0.5.1"]]
:compiler-options {#_#_:output-feature-set :es6
:closure-defines {app.system.config/version :shadow-git-inject/version
app.system.config/build-time :shadow-git-inject/build-iso-date-time
"re_frame.trace.trace_enabled_QMARK_" true}}}
:release {:output-dir "resources/dist/js"
:compiler-options {#_#_:output-feature-set :es6
:closure-defines {app.system.config/version :shadow-git-inject/version
app.system.config/build-time :shadow-git-inject/build-iso-date-time}
:optimizations :simple
:infer-externs :auto}}
:devtools {;:preloads [day8.re-frame-10x.preload]
:after-load app.core/reload!
:http-port 8050
:http-root "resources/app"
:watch-dir "resources/app"}}}}
I use the :app branch
Do I do anything crazy here?
some unnecessary config but looks ok
{:paths ["src/cljs"]
:deps {org.clojure/clojure {:mvn/version "1.10.3"}
org.clojure/clojurescript {:mvn/version "1.10.866"}
org.clojure/core.async {:mvn/version "1.3.610"}
thheller/shadow-cljs {:mvn/version "2.14.1"}
com.taoensso/timbre {:mvn/version "5.1.0"}
#_#_com.schpaa/schpaa {:mvn/version "0.2.0-SNAPSHOT"}
expound {:mvn/version "0.8.9"}
reagent {:mvn/version "1.0.0"}
re-frame {:mvn/version "1.1.2"}
kee-frame {:mvn/version "1.1.2"}
cljs-bean {:mvn/version "1.6.0"}
fork {:mvn/version "2.4.0"}
vlad {:mvn/version "3.3.2"}
com.andrewmcveigh/cljs-time {:mvn/version "0.5.2"}
thedavidmeister/cljs-i18n {:mvn/version "0.4.0"}
arco {:mvn/version "0.3.4"}
fipp {:mvn/version "0.6.23"}
mvxcvi/puget {:mvn/version "1.3.1"}
markdown-to-hiccup {:mvn/version "0.6.2"}
markdown-clj {:mvn/version "1.10.5"}
medley {:mvn/version "1.3.0"}
nrepl {:mvn/version "0.8.3"}
day8/shadow-git-inject {:mvn/version "0.0.4"}
;for codemirror
#_#_applied-science/js-interop {:mvn/version "0.2.5"}}
:aliases {:carve
{:extra-deps {borkdude/carve {:git/url "<https://github.com/borkdude/carve>"
:sha "$LATEST_CARVE_SHA"}}
:main-opts ["-m" "carve.main"]}
:dev
{:extra-paths ["src/dev"]
:extra-deps {;nubank/workspaces {:mvn/version "1.0.15"}
;day8.re-frame/re-frame-10x {:mvn/version "1.0.2"}
;org.clojure/clojurescript {:mvn/version "1.10.773"}
binaryage/devtools {:mvn/version "1.0.2"}}}}}
I’ve eliminated all codemirror related stuff
{
"dependencies": {
"create-react-class": "^15.7.0",
"firebase": "^8.6.2",
"firebase-auth": "^0.1.2",
"highlight.js": "10.7.1",
"image-conversion": "^2.1.1",
"marked": "^0.7.0",
"process": "^0.11.10",
"react": "^17.0.1",
"react-dom": "^17.0.1",
"react-firebaseui": "^5.0.2",
"react-highlight.js": "1.0.7",
"react-virtualized": "^9.22.2"
},
"devDependencies": {
"highlight.js": "9.18.1",
"react-highlight.js": "1.0.7"
}
}
all looks fine, except the missing npm install shadow-cljs
maybe
hmm
where would that go?
if there is something special
I just invoke it from the cli
in the project, you just npm install shadow-cljs
. so you don't rely on some global install
oh ok
yes
but that likely has nothing to do with whatever your issue is
just recommended and "safer" 😉
There is also the error in the console I cannot really fathom
main.js:1552 TypeError: module$node_modules$firebase$app$dist$index_esm.initializeApp is not a function
at <http://Object.app|Object.app>$system$database$core$init_BANG_ [as init_BANG_] (core.cljs:71)
at <http://Object.app|Object.app>$core$init_BANG_ [as init_BANG_] (core.cljs:33)
at eval (shadow.module.main.append.js:4)
at eval (<anonymous>)
at Object.goog.globalEval (main.js:486)
at Object.env.evalLoad (main.js:1549)
at main.js:2040
depending on which firebase version you use it might require a different import. they seem to change it every other version
erroring while init’ing the fb connection
do they?
so instead of ["firebase/app" :as firebase]
try ["firebase/app$default" :as firebase]
interesting
again .. help if you have JS examples
there are no js I’ve made
https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages there is a translation table
but I assume you are looking at JS docs for this stuff which have examples
the js stuff is rel. easy, just have to establish a stable firebase-var access
which is really tripping me up here
I am also using a react-firebaseui comp
so look at ONE JS example that explains this stuff and then translate it using the table I linked
there is really no point in guessing here. this stuff should be documented somewhere in the docs
for example https://www.npmjs.com/package/react-firebaseui
import firebase from 'firebase';
that would be ["firebase" :default firebase]
OR the new official variant ["firebase$default" :as firebase]
but yeah for firebase it is extremely important to check the versions you use, they change a lot of stuff constantly
so stuff that used to work for older versions may be incorrect today
thank you
no dice at all
Maximum call stack size exceeded when trying to peek at firebase
no idea what you mean by that
env.evalLoad @ main.js:1551
(anonymous) @ main.js:1930
main.js:1552 RangeError: Maximum call stack size exceeded
at Object.eval [as cljs$core$ILookup$_lookup$arity$2] (core.cljs:6851)
at Function.eval [as cljs$core$IFn$_invoke$arity$2] (core.cljs:1959)
at Object.cljs$core$print_meta_QMARK_ [as print_meta_QMARK_] (core.cljs:10236)
at Object.cljs$core$pr_writer_impl [as pr_writer_impl] (core.cljs:10246)
at cljs$core$pr_writer (core.cljs:10339)
at Object.cljs$core$pr_sequential_writer [as pr_sequential_writer] (core.cljs:10191)
at Object.eval [as cljs$core$IPrintWithWriter$_pr_writer$arity$3] (core.cljs:692)
at Object.cljs$core$_pr_writer [as _pr_writer] (core.cljs:778)
at Object.cljs$core$pr_writer_impl [as pr_writer_impl] (core.cljs:10257)
at cljs$core$pr_writer (core.cljs:10339)
that meta_QMARK
ok, that means you can't print it. likely because is has self-referential circular references
oh
but if you don't print it thats not a problem 😛
So i cannot do
(-> firebase .-app)
or (.-app firebase)
sure you can. you just can't print it, so you can't do it in the REPL if thats what you mean
(js/console.log (-> firebase .-app))
should be ok, or tap>
and the Inspect UI (probably rather limited, so use console)
@thheller shadow.lazy/loadable
is used in the function I’m testing that’s why error happens inside :karma while working fine inside :browser-test
I’ll open an issue in GitHub and will try to find some workaround in meanwhile. I think it would be nice to have some recipe to run tests when shadow.lazy
is used inside
nothing shows up in the console
oh yes
ƒ app(name){name=name||“[DEFAULT]“;if(!(0,_util.contains)(apps, name))throw ERROR_FACTORY.create(“no-app”,{appName:name});return apps[name]}
So it seems I can invoke initializeApp via this firebase thing
if you provide a repro I can give you tips. without knowing what you are doing I really can't give other tips.
sure, the JS examples seem to do that. don't see the <http://firebase.app|firebase.app>
anywhere but the initializeApp
I believe is the first thing you are supposed to call
sure, I’ll try to prepare some demo tomorrow
yes
and thats passing fine
I do an init at
(defn ^:export init! []
and put the result in an atom
(defn init! []
(log/info "widd/init!")
(reset! app (if (zero? (count (.-apps firebase)))
(-> firebase
(.initializeApp (->js appinfo-vakt)))
(.-app firebase)))
(when goog.DEBUG
(-> firebase
.database
(.useEmulator "localhost" 10008))
(-> firebase
.firestore
(.useEmulator "localhost" 10009))))
that doesn't seem to have a result. or at least the JS stuff never handles it
Is it possible to access closure-defines, or something simlar, in a clojure macro? I have a side effecting macro, and I’d like to somehow disable the side effecting part in certain builds like in CI.
sure, see https://github.com/binaryage/cljs-devtools/blob/master/src/lib/devtools/prefs.clj#L8-L12 for an example
closure defines are also somewhere in @cljs.env/*compiler*
, I think just [:options :closure-defines]
but not sure
awesome, thanks!
how did you infer that “firebase$default” was needed in the require
require(‘firebase’).default as it is in js
is this a translation that is only applicable to shadow-cljs?
I cannot find anything in the docs related to adding a $default to the name required
Perhaps I’m formulating this somewhat obtuse
I just dont know where to look and I feel I have no threads to follow
@schpaencoder if you look at the translation table https://shadow-cljs.github.io/docs/UsersGuide.html#_using_npm_packages you'll see the use of :default
, more here https://shadow-cljs.github.io/docs/UsersGuide.html#_about_default_exports. that is a shadow-cljs only thing that was rejected from CLJS, instead it added the $default
thing in the recent release. see https://clojurescript.org/news/2021-04-06-release#_library_property_namespaces
oh, never seen that before
so the $
really is just sugar for accessing properties directly, ["firebase" :as firebase]
and firebase/default
is also valid.
which would equate to the require(‘firebase’).default
variant, as does "firebase$default"
@thheller I have a bit of a weird question for you: when I have a shadow-cljs server running for a web app, and the browser has the web app open, if the app is unresponsive I will get a message about shadow-cljs reconnecting. How do you display that message?
I ask because I just saw that message pop up while the web app was blocked on a synchronous 30s transit deserialization call, which surprised me because nothing else should be able to run.
Hi @thheller. I just started an app that I need to use deps.edn
. I just tried to add nextjournal.clojure-mode
and shadow-cljs
on dependencies, configured a simple browser app, but I'm seeing the following error on console:
cljs$core$ExceptionInfo {message: "failed to encode relay msg", data: {…}, cause: null, name: "Error", description: undefined, …}
eval @ shared.cljs:229
eval @ shared.cljs:229
shadow$remote$runtime$api$relay_msg @ api.cljc:4
...
I downgraded to 2.12.7
, the error is gone and the browser can connect to the running instance