shadow-cljs

borkdude 2025-08-19T09:16:13.290719Z

For this shadow config, how can I get a node terminal REPL for the :test build?

{:source-paths ["src" "test"]
 :dev-http {8022 "out/test"}
 :nrepl {:cider false}
 :builds
 {:test
  {:target :node-test
   :output-dir "out"
   :output-to "out/node-tests.js"
   :closure-defines {shadow.debug true}
   :js-options {:js-provider :shadow
                :output-feature-set :es8}}

  :browser-test
  {:target :browser-test
   :test-dir "out/test"
   :closure-defines {shadow.debug true}
   :js-options {:output-feature-set :es8}}}}

borkdude 2025-08-19T09:17:02.386589Z

I have tried:

clj -Scp "$(clj -A:shadow -Spath)" -M -m shadow.cljs.devtools.cli node-repl
It works somewhat... but not quite.
cljs.user=> shadow-cljs - #4 ready!

(+ 1 2 3)
6
cljs.user=> (require '[nextjournal.markdown :as md])
------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:125:7
 Cannot infer target type in expression (. token -meta)
--------------------------------------------------------------------------------

------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:127:46
 Cannot infer target type in expression (. token -meta)
--------------------------------------------------------------------------------

------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:133:61
 Cannot infer target type in expression (. token -meta)
--------------------------------------------------------------------------------

------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:146:66
 Cannot infer target type in expression (. token -meta)
--------------------------------------------------------------------------------

------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:272:32
 Cannot infer target type in expression (. x -attrs)
--------------------------------------------------------------------------------

------ WARNING - :infer-warning ------------------------------------------------
 File: /Users/borkdude/dev/markdown/src/nextjournal/markdown/impl.cljs:272:60
 Cannot infer target type in expression (. x -attrs)
--------------------------------------------------------------------------------

cljs.user=> (md/parse "$$x^2$$")

Execution error (ReferenceError) at (<cljs repl>:1).
nextjournal is not defined
:repl/exception!

thheller 2025-08-19T13:51:57.558539Z

I think those warnings might be the issue? I think I configured the REPL to not load code with warnings by default?

borkdude 2025-08-19T13:53:06.746169Z

Ok I’ll give it another shot

thheller 2025-08-19T13:55:05.517289Z

yeah :devtools {:ignore-warnings true} would just load the code regardless, which you can't set because node-repl has no build config

thheller 2025-08-19T13:55:21.573599Z

I suppose :build-defaults {:devtools {:ignore-warnings true}} at the top level would work

thheller 2025-08-19T13:55:48.873679Z

why :js-options {:output-feature-set :es8}? are you working with an ancient node version?

thheller 2025-08-19T13:57:28.351699Z

I suppose this could be smarter and just ignore :infer-warning since they do not matter in the REPL

borkdude 2025-08-19T14:37:33.898259Z

got it working after getting rid of the warnings, thanks!

$  clj -Scp "$(clj -A:shadow -Spath)" -M -m shadow.cljs.devtools.cli node-repl

(require '[nextjournal.markdown :as md])
nil
cljs.user=> (md/parse "# Hello")
{:toc {:type :toc, :children [{:type :toc, :content [{:type :text, :text "Hello"}], :heading-level 1, :attrs {:id "hello"}, :path [:content 0]}]}, :footnotes [], :content [{:type :heading, :content [{:type :text, :text "Hello"}], :heading-level 1, :attrs {:id "hello"}}], :type :doc, :title "Hello"}

borkdude 2025-08-19T14:37:48.368389Z

why js-options, I don't know, it was like that when I got here :-)

borkdude 2025-08-19T14:37:53.075649Z

do you recommend to change it?

thheller 2025-08-19T15:19:04.778259Z

yes, unless you really need to target node versions from like 8 years ago

😆 1
borkdude 2025-08-19T15:22:28.978969Z

this is only for testing so maybe it doesn't matter

itaied 2025-08-19T12:03:04.392809Z

Hi, I have an issue importing dependencies such as dayjs from both node and browser. this works for node but breaks for browser

{:target    :node-test
 :output-to "tests-output/tests.js"}
(ns my-app
  (:require
   [dayjs]
   ["dayjs/plugin/utc" :as utc]
   ["dayjs/plugin/timezone" :as timezone]))
this works for browser but breaks for node
{:target      :browser
 :modules     {:main {:init-fn main/init}} 
 :devtools    {:http-port 8021}
 :js-options  {:js-provider           :external
               :external-index        "target/index.js"
               :ignore-asset-requires true
               :external-index-format          :esm
               :external-index-always-optimize true}}

(ns my-app
  (:require
   ["dayjs$default" :as dayjs$default]
   ["dayjs/plugin/utc$default" :as dayjs-utc]
   ["dayjs/plugin/timezone$default" :as dayjs-timezone]))
the error is a random
Uncaught TypeError: Cannot read properties of undefined (reading 'default')
    at date.cljs:8:18
    at date.cljs:8:25

thheller 2025-08-19T13:50:27.530719Z

I very much doubt that the error is random. dayjs seems to ship two variants of the code. one is commonjs the other esm. esm will have the default export, commonjs will not. so it kinda depends on how you configured the :external build tool, cause it will decide which variant it will take. seems like you configured it to take the esm variant. node and shadow-cljs will take the commonjs by default.