shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
Jeremy 2020-09-29T03:45:21.108Z

Hi everyone. May I please get some advice on how to debug an AssertionError Assert failed: (rc/valid-resource-id? src-id) shadow.cljs.devtools.server.worker.impl/eval17300/fn--17303/fn--17306 (impl.clj:808) error? :shadow.cljs.devtools.server.util/handle-ex reports {:msg {:op :cljs-load-sources, :sources [[:shadow.build.classpath/resource "common/lists.cljc"]... and :sources seems to include a nil which I presume is causing the problem. Unfortunately I can't quite work out what's causing the nil.

Jeremy 2020-09-29T03:45:53.108500Z

(The error happens when I try to evaluate anything once connected to the browser cljs repl)

shivekkhurana 2020-09-29T04:57:28.108600Z

Thank you Thomas! I was able to get lazy loading work with shadow/lazy

thheller 2020-09-29T06:56:07.109700Z

@clojure475 what are you trying to eval? and please do not shorten errors. I need the full stacktrace to make sense of it

Jeremy 2020-09-29T10:05:05.118700Z

Thanks for reply Thomas. It seems to happen when I try to eval anything, even a plain keyword.

Jeremy 2020-09-29T10:05:45.118900Z

The setup is a bit complicated (`shadow-cljs.edn` pointing at deps.edn aliases etc) but has been working brilliantly until I made too many changes without testing stepwise.

Jeremy 2020-09-29T10:05:54.119100Z

Output

:a
[2020-09-29 20:04:36.176 - WARNING] :shadow.cljs.devtools.server.util/handle-ex - {:msg {:op :cljs-load-sources, :sources [[:shadow.build.classpath/resource "common/lists.cljc"] [:shadow.build.classpath/resource "common/allocations.cljc"] [:shadow.build.classpath/resource "test/tools.cljc"] [:shadow.build.classpath/resource "test/examples.cljc"] [:shadow.build.classpath/resource "test/common/allocations.cljc"] [:shadow.build.classpath/resource "test/common/api.cljc"] [:shadow.build.classpath/resource "test/common/appointments.cljc"] [:shadow.build.classpath/resource "test/common/dates.cljc"] [:shadow.build.classpath/resource "test/common/fsm.cljc"] [:shadow.build.classpath/resource "test/common/lists.cljc"] [:shadow.build.classpath/resource "test/common/message.cljc"] nil [:shadow.build.classpath/resource "test/common/core.cljc"] [:shadow.build.npm/resource "node_modules/react/cjs/react.production.min.js"] [:shadow.build.classpath/resource "test/client/events/requests.cljs"] [:shadow.build.classpath/resource "test/client/core.cljs"] [:shadow.build.npm/resource "node_modules/scheduler/cjs/scheduler.production.min.js"] [:shadow.build.npm/resource "node_modules/react-dom/cjs/react-dom.production.min.js"] [:shadow.build.npm/resource "node_modules/scheduler/cjs/scheduler-tracing.production.min.js"] [:shadow.build.npm/resource "node_modules/react-is/cjs/react-is.production.min.js"] [:shadow.build.npm/resource "node_modules/prop-types/factoryWithThrowingShims.js"] [:shadow.build.classpath/resource "cljs/user.cljs"]], :call-id 5, :from 57}}
ExceptionInfo no output for id: [:shadow.build.classpath/resource "test/examples.cljc"] {:resource-id [:shadow.build.classpath/resource "test/examples.cljc"]}
	shadow.build.data/get-output! (data.clj:197)
	shadow.build.data/get-output! (data.clj:193)
	shadow.cljs.devtools.server.worker.impl/eval17300/fn--17303/fn--17306 (impl.clj:813)
	clojure.core/map/fn--5866 (core.clj:2753)
	clojure.lang.LazySeq.sval (LazySeq.java:42)
	clojure.lang.LazySeq.seq (LazySeq.java:51)
	clojure.lang.RT.seq (RT.java:535)
	clojure.core/seq--5402 (core.clj:137)
	clojure.core.protocols/seq-reduce (protocols.clj:24)
	clojure.core.protocols/fn--8146 (protocols.clj:75)
	clojure.core.protocols/fn--8146 (protocols.clj:75)
	clojure.core.protocols/fn--8088/G--8083--8101 (protocols.clj:13)
Timeout while waiting for result.

thheller 2020-09-29T10:06:42.119300Z

which version in deps.edn?

Jeremy 2020-09-29T10:07:35.119600Z

2.11.2, running from clj not the command line

thheller 2020-09-29T10:08:21.119800Z

try 2.11.4 just in case

thheller 2020-09-29T10:09:57.120Z

there was a bug related to this a while ago but no clue why you are still seeing it

thheller 2020-09-29T10:12:19.120200Z

what REPL is this? assuming nrepl?

Jeremy 2020-09-29T10:13:05.120400Z

yep nrepl and yep thank you the version bump (as well as restarting repl, which I do fairly frequently) seems to have resolved the problem!👍

👍 1
Jeremy 2020-09-29T10:19:25.120700Z

brilliant

2020-09-29T07:44:09.110700Z

In my project, I'm doing a normal + bootstrap build, and when I first launch shadow-cljs, I get a bunch of warnings about a provide conflict between the normal and bootstrap builds, like this:

[2020-09-29 09:40:52.675 - WARNING] provide conflict for #{goog.structs.Set} provided by web/js/bootstrap/js/goog.structs.set.js and {"/goog/structs/set.js" #{goog.structs.Set}}

2020-09-29T07:44:25.111200Z

Does this represent an error on my part, that can be avoided?

thheller 2020-09-29T07:46:08.111500Z

don't have the output of a build on the classpath 😛

thheller 2020-09-29T07:46:44.111900Z

although I thought I had fixed the filtering that should take care of this

thheller 2020-09-29T07:46:59.112200Z

guess it doesn't account for bootstrap builds

2020-09-29T07:47:56.112900Z

So that's inferred or generated based on what, exactly? outdir-dir ? or asset-path ? I see no explicit classpath in my shadow-cljs.edn.

2020-09-29T07:48:04.113200Z

What I am doing seems to follow more or less the tutorials that exist.

2020-09-29T07:48:21.113600Z

So I don't find that advice of "don't do that" very easy to follow, unfortunately.

thheller 2020-09-29T07:52:54.114700Z

by classpath I'm referring to your :source-paths and the :output-dir being on said source path

2020-09-29T07:54:25.115300Z

My :source-paths have my output dir on them - but if I remove it from source-paths and restart shadow-cljs, I get the same error.

2020-09-29T07:54:48.115500Z

Let's see ...

2020-09-29T07:57:22.115700Z

Ok, perfect.

2020-09-29T07:57:47.116400Z

So I ended up having that same issue in a project I was importing, which maybe seems to have been the source of the error.

2020-09-29T07:57:58.116800Z

Thanks for that - I'm not sure why my output dir was in the source paths to begin with.

2020-09-29T07:58:05.117100Z

Probably an artifact of something dumb I was doing long ago!

thheller 2020-09-29T07:58:51.117700Z

well it is supposed to be filtered and ignored but it looks like it just doesn't filter bootstrap builds

thheller 2020-09-29T07:59:03.118100Z

since the filtering is based on the cljs-runtime dir which bootstrap doesn't have

2020-09-29T08:01:30.118600Z

Ok, well, thank you for the insight in any case. I prefer having no warnings coming from the build if I can!

ullrich 2020-09-29T10:26:13.125300Z

Intro and context: We are reusing some code between our web app and our react-native app and for that we need to do some runtime checks. Unfortunately we also need to convince the compiler to play along. For web it’s easy to stub out dependencies by using :js-options :resolve with :target :global. So here comes the question: If we want to use :target :global on react-native what is the best way to populate global? In our web app we can execute JS before the app runs, but on mobile I didn’t find a way to do so.

thheller 2020-09-29T10:27:51.125900Z

@ullrich.schaefer do you have an example of what you are stubbing out this way?

thheller 2020-09-29T10:28:17.126300Z

I made this example a while ago https://gist.github.com/thheller/fa044450a6470fdd1afdbcf3f37a65e3

thheller 2020-09-29T10:28:29.126700Z

it isn't fully explained but I hope the idea is somewhat understandable

thheller 2020-09-29T10:28:43.127300Z

point is that you don't do any "replacements" of the requires this way

ullrich 2020-09-29T10:40:38.132300Z

A good example is Quill-js which is used in the main app to edit text. The mobile app is not concerned with editing text, but is including some namespaces that eventually end up importing quill. Also our main app is still build without shadow in production so we’re restricted in how we can import namespaces. There we use :global-exports in deps.edn. We use shadow for dev though so we can just do :js-options {:resolve {"quill" {:target :global :global "quill"}}} . Quill is just one of many examples and it would be great not to have to restructure all code around those dependencies, but find a solution at build tool level.

thheller 2020-09-29T10:58:00.133100Z

I don't get it. where does quill come from?

thheller 2020-09-29T11:00:25.133700Z

you might want to look into :js-provider :external if thats coming from webpack or so? only desribed here currently https://code.thheller.com/blog/shadow-cljs/2020/05/08/how-about-webpack-now.html#option-2-js-provider-external

👍 1
thheller 2020-09-29T11:03:16.134400Z

as far as I understand for the react-native issue though you can probably just set :js-options {:resolve {"quill" false}}

👀 1
thheller 2020-09-29T11:03:51.135200Z

that will make it just ignore that dependency entirely? not sure if you need the actual global?

thheller 2020-09-29T11:05:51.136400Z

I'm assuming that the code using the result isn't called at all?

thheller 2020-09-29T11:06:14.137100Z

otherwise (:require ["quill" :as q]) the q will be false

ullrich 2020-09-29T11:09:50.140100Z

Yes, that’s actually what we’re looking for. We’ll try that and I’ll report back to you. Sorry, but our setup is a bit complicated and grew a bit over the years 😄 Our dependencies on web are loaded using an outdated approach called doublebundle, described https://presumably.de/double-bundle-integrating-npm-dependencis-into-clojurescript-projects.html. Certainly something we need to transition away from at some point. A lot of good things happened to the CLJS ecosystem over the last years. Shadow being one of them 🙏 :thanks3: 🙇

thheller 2020-09-29T11:10:19.140800Z

look into the :external stuff maybe

thheller 2020-09-29T11:10:46.141500Z

thats basically a half-automated double-bundle

ullrich 2020-09-29T11:12:15.141600Z

in which context? Do you have a link where I can learn more?

thheller 2020-09-29T11:12:29.141800Z

see the link a few lines up

👍 1
thheller 2020-09-29T11:13:06.142Z

for the web parts I mean

2020-09-29T11:35:47.142500Z

Having some problems with my project after installing some npm dependencies Uncaught TypeError: Cannot read property 'hydrate' of undefined

2020-09-29T11:36:10.143100Z

(ns pwa.core
  (:require [react-dom :as react-dom]
            [reagent.core :as r]))

2020-09-29T11:36:18.143300Z

Why would react-dom be undefined here?

2020-09-29T11:36:52.143900Z

Is the reagent dependency somehow conflicting with the react/react-dom in package.json?

thheller 2020-09-29T11:39:40.144900Z

@danielstockton there is no use of hydrate in the code you pasted so no clue how you are using it?

2020-09-29T11:40:13.145200Z

Sorry, just using it like this

(ns ^:figwheel-hooks pwa.core
  (:require [pwa.shared :as shared]
            [react-dom :as react-dom]
            [reagent.core :as r]))

(defn mount [el]
  (react-dom/hydrate (r/as-element [shared/root]) el))

thheller 2020-09-29T11:40:33.145400Z

looks fine

thheller 2020-09-29T11:40:46.145900Z

check if your node_modules/react-dom is empty for some reason

thheller 2020-09-29T11:40:59.146400Z

sometimes that can happen with npm

2020-09-29T11:41:46.147300Z

Yeah, these problems started after i installed html-react-parser for the server side part, which meant i also had to install react and react-dom with npm. Have tried clearing node_modules completely and reinstalling multiple times, npm installing the same version as reagent (16.13.0)

2020-09-29T11:42:06.147600Z

ls node_modules/react-dom/
build-info.json  index.js  package.json  README.md          server.js       test-utils.js  unstable-fizz.browser.js  unstable-fizz.node.js
cjs              LICENSE   profiling.js  server.browser.js  server.node.js  umd            unstable-fizz.js          unstable-native-dependencies.js

2020-09-29T11:42:17.148Z

react-dom folder not empty

thheller 2020-09-29T11:43:25.148500Z

if you haven't restarted shadow-cljs after running npm install or so maybe try doing that

👍 1
ullrich 2020-09-29T12:01:04.149400Z

@thheller Turned out it didn’t work because we’re not using shadow-style/double-quote imports (we have another app that is build using cljs with :target :bundle

2020-09-29T21:26:55.150700Z

I've been banging my head against Calva and VSCode with shadow all day and I'm spent... anyone know why when I eval a namespace nothing seems to get loaded?

2020-09-29T21:29:17.151200Z

here's my shadow-cljs.edn:

{:source-paths ["src"]
 :dependencies [[cljs-ajax "0.8.0"]
                [org.clojure/core.async "1.3.610"] ; ignored by shadow-cljs (embedded)
                [funcool/cuerdas "2.2.0"]
                [clojusc/defun "0.4.0"]
                [frankiesardo/linked "1.3.0"]
                [jamesmacaulay/cljs-promises "0.1.0"] ; FIXME: When batching cartography files: uncomment and `shadow-cljs pom`
                ;;[cider/cider-nrepl "0.23.0"] ; for Calva + Shadow-cljs 
                [net.cgrand/xforms "0.19.2"]]
 :nrepl        {:port 3333}
 :builds       {:lib {:target           :node-library
                      :output-dir       "public/census"
                      :output-to        "public/census/census.js"
                      :compiler-options {:optimizations :advanced
                                         :source-map-include-sources-content false}
                      :exports-var      census.core/census}
                :geo {:target           :node-library
                      :output-dir       "public/geo"
                      :output-to        "public/geo/batch_convert.js"
                      :compiler-options {:optimizations :simple}
                      :exports-var      configs.geojson.core/batch_convert}}}

2020-09-29T21:29:45.151700Z

... here's what I'm trying to load:

(ns configs.geojson.core
  (:require
   [cljs.core.async           :refer [>! <! chan promise-chan close! take! put! pipeline-async]
    :refer-macros [go go-loop]]
   [cuerdas.core              :refer [join]
    :as s]
   [clojure.set               :refer [map-invert]]
   [defun.core                :refer-macros [defun]]
   [cljs-promises.async       :refer [value-port]] ;; Fixme: Need this dependecy -< move configs to separate project
   [census.utils.core         :refer [map-target error err-type]]
   [configs.utils.core        :refer [read-edn FileSaver]]
   [configs.geojson.filepaths2018 :refer [paths]]
   [clojure.reader :refer [read-string]]
   ["fs" :as fs]
   ["shpjs" :as shpjs]
   ["mkdirp" :as mkdirp]))

(def geoKeyMap (read-edn "./src/configs/geojson/index.edn"))

2020-09-29T21:30:09.152200Z

and here's what's eval'd:

clj::shadow.user=> 
; Creating cljs repl session...
; Connecting cljs repl: shadow-cljs...
;   The Calva Connection Log might have more connection progress information.
; Connected session: cljs, repl: node-repl
; TIPS: You can choose which REPL to use (clj or cljs):
;    *Calva: Toggle REPL connection*
;    (There is a button in the status bar for this)
cljs::cljs.user=> 
; Evaluating file: core.cljs
; ------ WARNING - :redef --------------------------------------------------------
;  Resource: <eval>:16:1
 resolve already refers to: cljs.core/resolve being replaced by: cljs-promises.core/resolve
--------------------------------------------------------------------------------

nil
cljs::configs.geojson.core=> 
#object[TypeError TypeError: Cannot read property 'core' of undefined]
cljs::configs.geojson.core=> 

2020-09-29T21:31:50.153400Z

I've tried using a remote session and a straight "jack-in" workflow both using a build id as well as just a node-repl I get the same no matter

thheller 2020-09-29T22:06:18.154500Z

@loganpowell the problem might be the warning

thheller 2020-09-29T22:06:43.154900Z

I can't see what the REPL is actually doing (like what was eval'd) so I can't tell

thheller 2020-09-29T22:06:59.155200Z

might be that the warning skips loading the code

2020-09-29T22:08:51.155500Z

let me try without defun

thheller 2020-09-29T22:09:19.155900Z

defun? the warning is from cljs-promises? no clue what defun is?

2020-09-29T22:09:30.156100Z

sorry, that's what I meant

steveb8n 2020-09-29T22:55:46.157400Z

Q: has anyone ever done aws interop to implement x-ray tracing for the entire SDK as documented here https://docs.aws.amazon.com/xray/latest/devguide/xray-sdk-nodejs-awssdkclients.html ? I can’t figure out the incantation for Shadow style interop

thheller 2020-09-29T22:57:03.157800Z

what incantation?

thheller 2020-09-29T22:57:44.158300Z

can't tell from the page since either example is missing code to understand what any of it means

steveb8n 2020-09-29T23:05:16.159200Z

I agree. That’s part of my problem. I’m experimenting with it now, looking at the generated js to try and match it up. I’ll report back if/when I get it working

steveb8n 2020-09-29T23:05:52.159900Z

(sorry, by “incantation”, I meant “interop form”. that’s me being too clever)

thheller 2020-09-29T23:09:10.160100Z

yes but which form do you mean?

thheller 2020-09-29T23:09:35.160600Z

var AWS = AWSXRay.captureAWS(require('aws-sdk')); that example doesn't explain where AWSXRay is coming from

thheller 2020-09-29T23:10:10.161100Z

var ddb = AWSXRay.captureAWSClient(new AWS.DynamoDB()); that doesn't explain where AWS is coming from

thheller 2020-09-29T23:10:24.161500Z

so I can't tell how this is supposed to be used

thheller 2020-09-29T23:11:22.161800Z

unless its supposed to be used together

var AWSXRay = require('aws-xray-sdk');
    var AWS = AWSXRay.captureAWS(require('aws-sdk'));
    var ddb = AWSXRay.captureAWSClient(new AWS.DynamoDB());

thheller 2020-09-29T23:11:31.162300Z

in which case the documentation is just plain weird

thheller 2020-09-29T23:11:51.162700Z

but which part do you have an issue with?

thheller 2020-09-29T23:13:36.162900Z

(ns foo.bar
  (:require
    ["aws-xray-sdk" :as aws-xray]
    ["aws-sdk" :as aws-sdk]))

(def aws (aws-xray/captureAWS aws-sdk))
(def ddb (aws-xray/captureAWSClient (aws.DynamoDB.)))

thheller 2020-09-29T23:13:50.163300Z

maybe that helps. no clue what any of it does but that would be the translation

2020-09-29T23:28:33.164200Z

yep, resolve already refers to: cljs.core/resolve being replaced by: cljs-promises.core/resolve is the issue, when I remove that, smooth sailing. Is there a way to alias a function within a dependency like this?

steveb8n 2020-09-29T23:31:54.165500Z

thanks @thheller I figured it out. the confusing part was around calling the “new” which is not very lispy. And yes, the AWS doc is not clear at all

steveb8n 2020-09-29T23:35:17.167300Z

the solution is…. use these 2 requires

["aws-sdk" :as aws-sdk-clean]                   ; clean means without x-ray
          ["aws-xray-sdk" :as aws-xray-sdk]
          
then use this form to wrap the sdk with xray
(let [capture-full-sdk (j/get aws-xray-sdk :captureAWS)]
  (capture-full-sdk aws-sdk-clean))
then you can use this let form to construct a service client where aws-sdk is the wrapped sdk
[s3-client (j/get aws-sdk :S3)
      s3 (new s3-client)]

steveb8n 2020-09-29T23:35:27.167600Z

was not obvious but this works