This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2022-01-22
Channels
- # announcements (1)
- # aws (2)
- # babashka (52)
- # beginners (35)
- # calva (20)
- # clj-kondo (13)
- # cljdoc (8)
- # clojure (14)
- # clojure-uk (6)
- # clojurescript (5)
- # conjure (13)
- # crypto (1)
- # data-oriented-programming (1)
- # datalevin (7)
- # emacs (2)
- # fulcro (21)
- # graalvm (14)
- # introduce-yourself (1)
- # lsp (6)
- # malli (17)
- # off-topic (15)
- # re-frame (10)
- # releases (1)
- # sci (2)
- # shadow-cljs (17)
- # tools-build (9)
- # tools-deps (6)
Is there a way to get a REPL for a build with target :esm
and runtime :node
?
The build configuration:
{:target :esm
:js-options {:js-provider :import}
:runtime :node
:output-dir "out/esm"
:modules
{:script {:entries [my.script.core]
:exports {init my.script.core/init}}}}
The output produced by npx shadow-cljs watch ...
for this build seems to not connect to the server and node out/esm/script.js
exists immediately.
I have tried to make it connect to the server by requiring the namespace shadow.cljs.devtools.client.node
in my.script.core
.
But then running the output with node ...
reports the following error:
var socket = (new shadow.esm.esm_import$ws(ws_url,({"rejectUnauthorized": false})));
^
TypeError: shadow.esm.esm_import$ws is not a constructor
at shadow$cljs$devtools$client$node$start (file:///.../out/esm/cljs-runtime/shadow.cljs.devtools.client.node.js:122:15)
at Object.attempt_connect_BANG_ (file:///.../out/esm/cljs-runtime/shadow.cljs.devtools.client.shared.js:482:128)
at Object.shadow$cljs$devtools$client$shared$init_runtime_BANG_ [as init_runtime_BANG_] (file:///.../out/esm/cljs-runtime/shadow.cljs.devtools.client.shared.js:970:16)
at file:///.../out/esm/cljs-runtime/shadow.cljs.devtools.client.node.js:431:36
I also tried to use node-script
as a target but that doesn't seem to be an option with some npm packages that are ESM only (e.g., the latest version of chalk).
@davidst I didn't try to get the node repl running with :esm
yet. you can try setting :runtime :custom :devtools {:client-ns some.ns}
where some.ns
is just a copy of https://github.com/thheller/shadow-cljs/blob/master/src/main/shadow/cljs/devtools/client/node.cljs with the ["ws" :as ws]
changed to ["ws$default" :as ws]
. maybe thats enough?
Thank you. Following your suggestion I was able to connect to the repl. Unfortunately, when evaluating anything, I was getting errors about undefined SHADOW_IMPORTED
and SHADOW_IMPORT
. It looks like these are defined in node_bootstrap.txt
for node
targets. It seems shadow/boot/esm.js
is supposed to replace (some of) that. I have tried to fix these errors. It seems to work alright so far but it is clearly a nasty hack:
;; these implementations replace the first three functions in shadow.cljs.devtools.client.node
(defn node-eval [{:keys [js source-map-json] :as msg}]
(let [result (js* "(0,eval)(~{});" js)]
result))
(defn is-loaded? [src]
(true? (js/SHADOW_ENV.setLoaded src)))
(defn closure-import [src]
{:pre [(string? src)]}
(js/console.log src)
(when-not (= src "goog.base.js")
;; goog base doesn't work with this kind of import?
(js/globalThis.shadow_esm_import (str "./cljs-runtime/" src)))
(js/SHADOW_ENV.setLoaded src))
;; this interface implementation replaces the current one for the type cljs-shared/Runtime
api/IEvalJS
(-js-eval [this code]
(js* "(0,eval)(~{});" code))
this probably needs many more adjustments. the regular node
impl assumes it can do sync imports but the shadow_esm_import
is async so all of the code needs to be adjusted to not assume sync
might need to go with loading the file from disk using fs/readFileSync
and then eval'ing
haven't spend much time on node with esm so not sure what kind of restrictions exist. might even require modifying the source get get rid of import
statements. I opened https://github.com/thheller/shadow-cljs/issues/979
The hack to prepend "./cljs-runtime"
to src
seems especially fragile. Is there a better way to do that?
Complete newbie using the default shadow-cljs setup in luminus. App loads fine but test throws a fit. Is this a 'need to be using :broswer-test instead of :node-test' type issue? I'm struggling to figure out where to even look to troubleshoot what wrong beyond an import expects the browser 'window' object to exist. Its one test file for a re-frame subscription if that helps at all
ReferenceError: window is not defined
at [path]/.shadow-cljs/builds/test/dev/out/cljs-runtime/accountant/core.cljs:21:35
at [path]/.shadow-cljs/builds/test/dev/out/cljs-runtime/accountant.core.js:16:3
at global.SHADOW_IMPORT ([path]/target/test/test.js:64:44)
at [path]/target/test/test.js:1701:1
at Object.<anonymous> ([path]/target/test/test.js:1781:3)
at Module._compile (node:internal/modules/cjs/loader:1097:14)
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1149:10)
at Module.load (node:internal/modules/cjs/loader:975:32)
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
===============================================
I'm not calling window anywhere but I suppose one of the libraries I'm using must be. I swapped to :browser and am at least past ^ error message. I was hoping to avoid having to set up Karma and a browser-driven test suite for now by just testing my re-frame logic with :node-test but its been more of a hassle to troubleshoot than it is to just launch Karma. Anyways, thanks for taking a look!
this library is using js/window
. so it just isn't compatible with anything that doesn't have that. from the looks of it there are many other things that expect a full browser