Now I am fighting with nodejs built-in modules, keep running into these errors when loading the compiled nodejs script:
shadow-cljs - failed to load module$node_modules$$google_cloud$firestore$build$src$index
Module not provided: shadow.esm.esm_import$process
node:internal/modules/esm/module_job:387
const namespace = this.module.evaluateSync();
^
Module not provided: shadow.esm.esm_import$process
This is with :target :esm :runtime :node with :js-provider :import or :keep-as-import #{"process"}?
:js-options {:keep-native-imports true
:keep-as-import
#{"trace_events"
"async_hooks"
"wasi"
"perf_hooks"
"request"
"inspector"
"diagnostics_channel"
"fs"
"os"
"path"
"http"
"http2"
"https"
"zlib"
"stream"
"crypto"
"tty"
"net"
"tls"
"querystring"
"child_process"
"dns"
"worker_threads"
"module"
"constants"
;; Weird and annoying libraries
"re2"
"canvas"
"jsdom"
"firebase-admin/app"
"firebase-admin/auth"
"firebase-admin/storage"
"firebase-admin/functions"
"@google-cloud/firestore"
"@elastic/elasticsearch"
}
:ignore-asset-requires true}But yeah with :keep-as-import
I might be blind but "process" is not in that set?
:keep-native-imports is not an option that exists
Oh my bad I added this into shadow.build.resolve
(or
(str/starts-with? require "esm:")
(str/starts-with? require "https://")
(str/starts-with? require "http://")
(and
(:keep-native-imports js-options)
(or (contains? native-node-modules require) (str/starts-with? require "node:")))
(contains? (:keep-as-import js-options) require)) ah
I can remove it and fix the :keep-as-import list
For some reason it broke with all of these libs:
"firebase-admin/app"
"firebase-admin/auth"
"firebase-admin/storage"
"firebase-admin/functions"
"@google-cloud/firestore"
"@elastic/elasticsearch"That is why I was adding them
"broke"?
I assume you are not using :js-provider :import because of this css stuff?
I got the same error for all of the libs about shadow.esm.esm_import$process
And yes you are correct because of the css stuff
what confuses me is failed to load module$node_modules$$google_cloud$firestore$build$src$index
that is not a file it should be loading if you have excluded it
so it should just import "@google-cloud/firestore" directly from node
Oh yeah sorry I added that later
currently it is:
shadow-cljs - failed to load module$node_modules$agentkeepalive$lib$agent
Module not provided: shadow.esm.esm_import$process
shadow-cljs - failed to load module$node_modules$agentkeepalive$index
Module not provided: shadow.esm.esm_import$process
node:internal/modules/esm/module_job:387
const namespace = this.module.evaluateSync();
^
Module not provided: shadow.esm.esm_import$processSo sorry about that
did you restart the build sometime inbetween changing all those exludes?
Yes and als did a clean of the .shadow-cljs folder and the target folder
I do have multiple builds running so I could try to only run the one build
nah builds don't share anything, so should not matter
unless of course they use the same :output-dir?
No they don't
But I am now only running the one build to be sure
ok, then they can't affect each other
Still running into exactly the same error
maybe I need to add an inverse like :only-bundle #{"that-css-thing"} 😛
Yeah I was just thinking the same thing
only bundle the @atlaskit crap
its always a bit sketchy to only bundle partially because some of the included things may end up using the same things and end up with the unbundled stuff
two versions of the same thing is never good
yeah that is never a good idea
And that is a very easy trap to fall into
I don't really get why a shadow.esm.esm_import$process is created I thought it would keep those import calls as is
you could do a quick test and try :js-provider :import but then run the final result through something like ncc
I did the same with rsbuild
And then the project works
hmm ok
would help to have a reproducible example so I can check what exactly is wrong
Sure I'll work on that
I reproduced it:
shadow-cljs - failed to load module$node_modules$agentkeepalive$lib$agent
Module not provided: shadow.esm.esm_import$process
shadow-cljs - failed to load module$node_modules$agentkeepalive$index
Module not provided: shadow.esm.esm_import$process
node:internal/modules/run_main:129
triggerUncaughtException(
^
Module not provided: shadow.esm.esm_import$process
(Use `node --trace-uncaught ...` to show where the exception was thrown)
I'll create a repoBtw I got the same error for other built-in stuff if it tried to require that
fixing this is unfortunately a bit involved. not quite sure how to go about it. currently for esm shadow-cljs will leave esm_import$... references in the code. as part of :advanced optimizations there is an extra closure pass that'll collect these and add the actual required JS import. problem is the sources for the :keep-as-import stuff are :shadow-js, so like any other npm source only runs through :simple and not this path
It currently breaks without advanced optimizations though? Or is it more related to the pass that get's added regardless of the optimizations?
making dev builds work is trivial
Ah ok I did not get that far
problem is making this work without breaking the reasons I did this compiler pass in the first place
I think I have a plan though
try 3.1.3. Module not provided: shadow.esm.esm_import$process should be gone
Damn that was fast
its not the cleanest solution, but should be fine
I will test it out today and report back, if it all works I can remove a lot of crap from our projects
I want to port node class. It works in repl, but release build is crashing. (btw. in my setup in calva no longer works async print from node)
const { TeamsActivityHandler } = require("botbuilder");
class TeamsBot extends TeamsActivityHandler {
constructor() {
super();
this.onMessage(async (context, next) => {
await context.sendActivity("robotox!");
await next();
});))
with defclass
(ns teams-bot
(:require
["botbuilder" :refer [^js TeamsActivityHandler TurnContext]]
[promesa.core :as p]
[shadow.cljs.modern :refer [defclass]]))
(defclass TeamsBot
(extends TeamsActivityHandler)
(constructor [this]
(super)
(.onMessage this (fn [^ĵs context next]
(on-message context)
(p/then (next) identity)))))
It works in repl (btw in calva no longer works async print).
but in release build with debug there is crash. I tried ^js, js/*, and :simple
/app/bot.js:11843
this.$onMessage$(function($context$jscomp$15$$, $next$jscomp$6$$) {
^
TypeError: this.$onMessage$ is not a function
at new $teams_bot_cljs$classdecl$var6$$ (/app/bot.js:11843:10)
at Function. (/app/bot.js:11995:3)
at $cljs$core$apply$cljs$0core$0IFn$0_invoke$0arity$02$$ (/app/bot.js:3586:179)
at /app/bot.js:11991:2
at Object. (/app/bot.js:11999:3)
at Module._compile (node:internal/modules/cjs/loader:1364:14)
I aslo don't know how to do await next(); this is my best guess (p/then (next) identity)you should be getting an extern inference warning?
onMessage is getting renamed
the ^js needs to be on the this in this case
so (.onMessage ^js this ...)
(defclass TeamsBot
(extends TeamsActivityHandler)
(constructor [this]
(super)
(.onMessage ^js this
(fn [^js context next]
(js-await [_ (.sendActivity context "robotox!")]
(js-await [_ (next)]
nil))))))maybe
dunno exactly that the next is doing there or why its waiting for it, probably can just by (next) without await
or (-> (.sendActivity context ...) (.then next))
thanks I tried (constructor [^ĵs this] and it got renamed, thanks,
hmm that should be fine too
this await chaining is very strange to me. i am guessing that this is so confusing to me, because clojure return last eval as function result, but js hacks something with await
So I am getting "router deprecated handlers that are Promise-like are deprecated, use a native Promise instead at node_modules/router/lib/route.js:157:13"
that might be complaining about promesa. that has its own weird promise type
yes it is something in p/let because without p/let and just returning (p/promise nil) there are no warns
so probably need to remove promesa
FWIW async functions in JS just implicitly always return a promise
I read somewhere that yours js-await is just for repl?
so without an actual return that just returns a promise that resolves to undefined
no?
https://clojureverse.org/t/promise-handling-in-cljs-using-js-await/8998
doesn't make much sense to use the in the REPL. there was talk about a specific "primitive" in the REPL to make dealing with async code a bit easier
but that doesn't exist yet
i don't see async output in calva, no logss, and prints, so it is quite painfull to do repl dev.
We do
(p/handle promise-thing (fn [res err] (def _res [res err]))
This kinda works for repl devGreat, But all log statements are not printed when they are invoked in express handlers.
Yeah I just have a console open for that
I am investigating if this is just my problem, because i am running shadow-cljs watch ;bot, and I am connected from calva to nrepl, and there is no output. And I tried different output destinations. but just for node.
It is interesting that (TeamsBot.) is not marked as JS,. and .run is renamed.
(defn run-teams-bot [^js context]
(let [^js b (TeamsBot.)]
(.run b context)))hmm that is very clearly marked?
which shadow-cljs version do you use? could be that the js tag is removed because the type is inferred by other code? could just be a bug
or do you mean that it gets renamed if the ^js tag is not there. that would be expected than and should produce an inference warning
3.1.1
in case (.run (TeamsBot.)) .run was renamed, even (.run ^ĵs (TeamsBot.)) got renamed
wo warnings
but now i have bigger problem:
/app/node_modules/botbuilder-core/src/turnContext.ts:557
this.responded = true;
^
TypeError: Cannot perform 'set' on a proxy that has been revoked
at Proxy.<anonymous> (/app/node_modules/botbuilder-core/src/turnContext.ts:557:35)
at Generator.next (<anonymous>)
at fulfilled (/app/node_modules/botbuilder-core/src/turnContext.ts:4:4)
at process.processTicksAndRejections (node:internal/process/task_queues:95:5)
I tried some other unusual ^js annotations .run is recognised in this case
(defn async-run-teams-bot
[^js context]
(let [b (TeamsBot.)]
(p/let [_ (.run ^js b context)])))
this case is also ok:
(let [b (TeamsBot.)]
(js-await [_ (.run ^js b context)]))
but not
(js-await [_ (.run (TeamsBot.) context)])
(js-await [_ (.run ^js (TeamsBot.) context)])
(let [b (TeamsBot.)]
(js-await [_ (.run ^js (TeamsBot.) context)])
(let [b (TeamsBot.)]
(p/let [_ (.run ^js b context)])))
(p/let [_ (.run (new TeamsBot) context)]))
(p/let [_ (.run (TeamsBot.) context)])
(p/let [_ (.run ĵs (TeamsBot.) context)])
(p/let [_ (.run (new TeamsBot) context)])
And this is also strange
(:require ["botbuilder" :refer [TurnContext]])
ok
(.getConversationReference ^js *TurnContext* (.-activity context))
not ok:
(*TurnContext*.getConversationReference (.-activity context))(TurnContext.getConversationReference (.-activity context)) this not working is sort of expected since this is syntax that only accidentally works
(.getConversationReference TurnContext (.-activity context)) this should be fine and not require ^js hints?
It is a must