shadow-cljs

https://github.com/thheller/shadow-cljs | https://github.com/sponsors/thheller | https://www.patreon.com/thheller
kennytilton 2020-10-20T00:05:49.022100Z

I am getting a harmless error

Parse error. illegal use of unknown JSDoc tag "pd"; ignoring it
doing a release build, when it gets to this line in a library I am using: https://github.com/ptaoussanis/tufte/blob/master/src/taoensso/tufte.cljc#L315 There is a comment with a code snippet ending @pd. ANy way to quiesce that? Not a big deal at all.

thheller 2020-10-20T08:05:25.022700Z

@kenny there is an option but I can't remember the name. I'll try to look it up later.

thheller 2020-10-20T08:06:50.023700Z

@mail024 what are "duplicate require issues"? for now :npm-module should sort of work. :esm is sort of finished except for a "do not bundle X packages" setting I guess

victorb 2020-10-20T10:13:34.025100Z

@thheller I keep trying to shoehorn shadow-cljs into lots of different contexts, and thinking about it, it would be helpful if you could provide new :target 's as plugins/extensions to shadow-cljs, to keep the core smaller and not having to implement everything in shadow-cljs. Something you thought about?

thheller 2020-10-20T10:13:51.025300Z

this is the basic design

thheller 2020-10-20T10:14:32.026Z

:target accepts a symbol. so :target your.lib/my-target would call that function

victorb 2020-10-20T10:14:43.026300Z

ooooh, didn't know that! That's cool, will take a look at that

thheller 2020-10-20T10:15:07.026800Z

all the default targets are implemented this way https://github.com/thheller/shadow-cljs/tree/master/src/main/shadow/build/targets

victorb 2020-10-20T10:15:07.026900Z

guessing it just has to be available on the classpath and it'll pick it up from there?

thheller 2020-10-20T10:15:28.027400Z

and a keyword for :target just expands to shadow.build.targets.<name-of-kw>/process

victorb 2020-10-20T10:16:19.027700Z

cool cool, thanks :thumbsup:

thheller 2020-10-20T10:16:37.028100Z

yes its just a regular function you implement that inspects some keys to know what it is supposed to do

thheller 2020-10-20T10:16:58.028600Z

I recommend looking at simple targets like node-script https://github.com/thheller/shadow-cljs/blob/80b00a6bd61537c3a4dbcaece1f7555234cc2d87/src/main/shadow/build/targets/node_script.clj#L66

thheller 2020-10-20T10:17:35.029400Z

:browser is by far the most complicated so can be hard to understand what is happening

thheller 2020-10-20T10:18:41.029900Z

the API isn't documented at all though but happy to walk you through it

๐Ÿ‘ 1
thheller 2020-10-20T10:18:56.030400Z

basically it gets the entire build state and just does whatever it needs to

thheller 2020-10-20T10:22:11.030800Z

this is one of the custom targets someone else wrote as a lib https://github.com/titonbarua/shadow-cljs-gjs-target

Alexis Vincent 2020-10-20T10:44:38.033100Z

@thheller duplicate require was a bad way to name it. I meant Namespace "xxx" already declared . Happens for both esm and npm-module. I think i remember similar things happening a little while back when I tried to import cljs code from shadow in webpack.

Error: Namespace "cljs.core" already declared.
    at Object.goog.provide (webpack-internal:///./dist/cljs/cljs-runtime/cljs_env.js:102:13)
    at eval (webpack-internal:///./dist/cljs/cljs-runtime/cljs.core.js:4:6)
    at Module../dist/cljs/cljs-runtime/cljs.core.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:199:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./dist/cljs/index.js:41:85)
    at Module../dist/cljs/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2298:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./pages/index.js:2:77)
    at Module../pages/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2310:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)

Alexis Vincent 2020-10-20T10:44:56.033500Z

Super cool about the target thing mentioned above!

thheller 2020-10-20T10:46:10.033900Z

weird. are you including multiple builds this way?

Alexis Vincent 2020-10-20T10:48:43.034600Z

A single one. I can get you a repro project if thats useful.

Alexis Vincent 2020-10-20T10:49:14.034900Z

;; shadow-cljs configuration
{:source-paths
 ["src/dev"
  "src/main"
  "src/test"]

 :dependencies
 [[reagent "0.8.1"]]

 :builds
 {:site {:target :npm-module
         :output-dir "site/src/cljs"
         :build-hooks [(shadow.next-js/create-pages)]
         :entries [<http://demo.site|demo.site>]}
  :esm {:target :esm
        :output-dir "dist/cljs"
        :build-hooks [(shadow.next-js/create-pages)]
        :modules {:index {:exports {page_index <http://demo.site/page-index|demo.site/page-index>}}}}}}

Alexis Vincent 2020-10-20T10:50:03.035400Z

Let me push a repro project

Alexis Vincent 2020-10-20T10:53:18.035600Z

https://github.com/alexisvincent/shadow-cljs-next-repro

Alexis Vincent 2020-10-20T10:54:07.036Z

repro is for esm

Alexis Vincent 2020-10-20T10:54:43.036700Z

npm run dev shadow-cljs watch esm

Alexis Vincent 2020-10-20T10:55:24.037100Z

actually. Sorry, should remove the build hook for esm. Will fix

Alexis Vincent 2020-10-20T10:58:21.039200Z

Also to note, on latest shadow last night I ran into an issue where I changed the shadow-cljs output-dir for either the npm-module or esm and even after restarting shadow watch, it was still outputting to the old dir. Deleting .shadow-cljs fixed it. Possible i had a shadow server running somewhere in emacs while this happened but i dont think i did

Alexis Vincent 2020-10-20T11:01:36.039600Z

scratch that, I think i did have a shadow-cljs server running

Alexis Vincent 2020-10-20T11:09:06.041500Z

ok. Iโ€™ve pushed a clean repro case for issues with next-js (although i think this is webpack reproducible as well) and esm. Super simple import. From fresh next and shadow cache. Terminal history is as follows:

Alexis Vincent 2020-10-20T11:09:06.041600Z

&gt; next-cljs@0.0.1 dev /Users/alexisvincent/Code/next-cljs
&gt; next dev

ready - started server on <http://localhost:3000>
event - compiled successfully
event - build page: /
wait  - compiling...
[BABEL] Note: The code generator has deoptimised the styling of /Users/alexisvincent/Code/next-cljs/dist/esm/cljs-runtime/cljs.pprint.js as it exceeds the max of 500KB.
[BABEL] Note: The code generator has deoptimised the styling of /Users/alexisvincent/Code/next-cljs/dist/esm/cljs-runtime/cljs.pprint.js as it exceeds the max of 500KB.
[BABEL] Note: The code generator has deoptimised the styling of /Users/alexisvincent/Code/next-cljs/dist/esm/cljs-runtime/cljs.core.js as it exceeds the max of 500KB.
[BABEL] Note: The code generator has deoptimised the styling of /Users/alexisvincent/Code/next-cljs/dist/esm/cljs-runtime/cljs.core.js as it exceeds the max of 500KB.
warn  - ./dist/esm/cljs-runtime/cljs_env.js
Critical dependency: the request of a dependency is an expression
info  - ready on <http://localhost:3000>
ReferenceError: WebSocket is not defined
    at shadow$cljs$devtools$client$websocket$start (webpack-internal:///./dist/esm/cljs-runtime/shadow.cljs.devtools.client.websocket.js:9:16)
    at shadow.cljs.devtools.client.shared.Runtime.attempt_connect_BANG_ (webpack-internal:///./dist/esm/cljs-runtime/shadow.cljs.devtools.client.shared.js:507:131)
    at Object.shadow$cljs$devtools$client$shared$init_runtime_BANG_ [as init_runtime_BANG_] (webpack-internal:///./dist/esm/cljs-runtime/shadow.cljs.devtools.client.shared.js:978:18)
    at eval (webpack-internal:///./dist/esm/cljs-runtime/shadow.cljs.devtools.client.browser.js:989:38)
    at Module../dist/esm/cljs-runtime/shadow.cljs.devtools.client.browser.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2046:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./dist/esm/index.js:130:112)
    at Module../dist/esm/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2286:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./pages/index.js:2:76)
Error: Namespace "shadow.cljs.devtools.client.browser" already declared.
    at Object.goog.provide (webpack-internal:///./dist/esm/cljs-runtime/cljs_env.js:102:13)
    at eval (webpack-internal:///./dist/esm/cljs-runtime/shadow.cljs.devtools.client.browser.js:5:6)
    at Module../dist/esm/cljs-runtime/shadow.cljs.devtools.client.browser.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2046:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./dist/esm/index.js:130:112)
    at Module../dist/esm/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2286:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./pages/index.js:2:76)
    at Module../pages/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2298:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
event - build page: /next/dist/pages/_error
wait  - compiling...
event - build page: /next/dist/pages/_error
warn  - ./dist/esm/cljs-runtime/cljs_env.js
Critical dependency: the request of a dependency is an expression
info  - ready on <http://localhost:3000>
warn  - ./dist/esm/cljs-runtime/cljs_env.js
Critical dependency: the request of a dependency is an expression
info  - ready on <http://localhost:3000>
Error: Namespace "cljs.core" already declared.
    at Object.goog.provide (webpack-internal:///./dist/esm/cljs-runtime/cljs_env.js:102:13)
    at eval (webpack-internal:///./dist/esm/cljs-runtime/cljs.core.js:4:6)
    at Module../dist/esm/cljs-runtime/cljs.core.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:199:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./dist/esm/index.js:41:85)
    at Module../dist/esm/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2286:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)
    at eval (webpack-internal:///./pages/index.js:2:76)
    at Module../pages/index.js (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:2298:1)
    at __webpack_require__ (/Users/alexisvincent/Code/next-cljs/.next/server/pages/index.js:23:31)

thheller 2020-10-20T11:20:17.042800Z

uhm yeah watch won't work

thheller 2020-10-20T11:20:20.043Z

try compile

Alexis Vincent 2020-10-20T11:21:45.044600Z

Have now added an npm-module case. Which works! I must have had bad caches yesterday? What doesnโ€™t work however is interplay between hmr from webpack and shadow. I expect here that I could leave hmr up to shadow by using compile. But then i still want to have a shadow server for repl and hmr, how do I do this? Im assuming some combination of compile and server?

Alexis Vincent 2020-10-20T11:25:51.046300Z

esm compile works, but fails for other reasons I dont think are related to shadow. Thanks! Having a way for shadow to do hmr but bypassing the flush step to avoid next attemping to hmr cljs code would be great. Do you know how i might achieve this?

thheller 2020-10-20T11:41:18.046500Z

sorry don't have time for this today

thheller 2020-10-20T11:41:31.046800Z

you cannot have both webpack hmr and shadow

thheller 2020-10-20T11:41:35.047Z

it is either or

thheller 2020-10-20T11:41:50.047400Z

if you want REPL and stuff you need to use the shadow reloading only

Alexis Vincent 2020-10-20T12:30:37.048400Z

Ok, thanks for the input. Iโ€™ll get some time to look closer into this tomorrow. Goal is to get reliable interplay between shadow and nextcljs

thheller 2020-10-20T12:33:04.049100Z

I believe I said it is not a good match for CLJS and it still isn't and never will be great

thheller 2020-10-20T12:33:35.049400Z

too many presumed JS-isms that don't translate well

victorb 2020-10-20T12:50:01.050400Z

yeah, I got the same impression last time I looked at next.js, doesn't seem to fit with clojurescript development really. Question for people who used next.js more though, what exactly are you missing in cljs devlopment that next.js gives you? Might be something better in the ecosystem to give you the same or greater benefits

mauricio.szabo 2020-10-20T19:14:59.053400Z

Hi, @thheller, I just found a really strange issue ๐Ÿ˜„. On Chlorine, I evaluate all shadow-cljs commands by treating the result - so they all go inside a let. So, if I do something like this:

(let [res (ns some.namespace (:require ["js-dependency" :as dependency]))] res)
And then try do define a function: (defn a-fn [] (.useThis dependency) It breaks with:
AssertionError Assert failed: (symbol? module)
        shadow.build.cljs-hacks/js-module-exists? (cljs_hacks.cljc:71)
        shadow.build.cljs-hacks/js-module-exists? (cljs_hacks.cljc:71)
        shadow.build.cljs-hacks/invokeable-ns? (cljs_hacks.cljc:109)
        shadow.build.cljs-hacks/invokeable-ns? (cljs_hacks.cljc:104)

mauricio.szabo 2020-10-20T19:16:10.054700Z

If I don't wrap the ns form in a let, it works fine. It's not a big deal, really - Shadow's hot-reload makes evaluating ns forms unnecessary, but I thought I would explain the issue anyway ๐Ÿ˜„

thheller 2020-10-20T19:24:09.055500Z

@mauricio.szabo ns is a special form which you cannot put into a let in CLJS

thheller 2020-10-20T19:25:52.056500Z

that alone should already fail. dunno how you get to the second error

mauricio.szabo 2020-10-20T19:26:36.056700Z

Yes, the simple fact that it works sometimes is something that amazes me ๐Ÿ˜„. For example, load-file simply do not work if you wrap on let

mauricio.szabo 2020-10-20T19:27:19.057400Z

The result of the first command is nil, so it does run... to some extend

thheller 2020-10-20T19:32:35.057600Z

all special forms can't possibly work