Fork me on GitHub
#shadow-cljs
<
2018-12-05
>
richiardiandrea00:12:45

so before going all the way in depth on this I would like to get an opinion. I was a shadow-cljs.edn with:

:release {:compiler-options {:optimizations :simple
                                              :variable-renaming :off
                                              :property-renaming :off
                                              :pretty-print true
                                              :elide-asserts false
                                              :source-map true}
                           :autorun false}

richiardiandrea00:12:55

it used to test some spec

richiardiandrea00:12:05

(= {:problems
            [{:path []
              :pred 'cljs.core/keyword?
              :val {:foo :bar}
              :via []
              :in []}]
            :value {:foo :bar}
            ::error2/id :this-is-an-error-id}
           (ex-data (error2/spec-ex-info :this-is-an-error-id spec body)))

richiardiandrea13:12:15

So this is basically the original spec, sorry if messy. keyword? is the spec (predicate only) and {:foo :bar} the value. I will try to repro in core as well

richiardiandrea00:12:22

the problem is, witch shadow-cljs watch the above passes

richiardiandrea00:12:40

with the :release config above it does not

richiardiandrea00:12:48

(not
 (= {:problems
     [{:path [], :pred cljs.core/keyword?, :val {:foo :bar}, :via [], :in []}],
     :value {:foo :bar},
     :laputa.tools.error2/id :this-is-an-error-id}
    {:laputa.tools.error2/id :this-is-an-error-id,
     :value {:foo :bar},
     :problems [{:path [],
                 :pred :cljs.spec.alpha/unknown,
                 :val {:foo :bar},
                 :via [],
                 :in []}]}))

richiardiandrea00:12:09

the problem above is in the :pred, which is :cljs.spec.alpha/unknown in :release

richiardiandrea00:12:41

does it sound a thing worth an issue in shadow? or core?

thheller09:12:20

@richiardiandrea spec + body is missing from the code above so I can't say.

thheller09:12:43

given that I don't do anything to specs its probably in core?

thheller09:12:04

but the above doesn't show enough to reproduce anything

richiardiandrea13:12:22

Sorry if messy. keyword? is the spec (predicate only) and {:foo :bar} the value. I will try to repro in core as well then

escherize17:12:12

Would shadow be a good choice for writing a wrapper for a react based component framework?

thheller17:12:02

@escherize I assume you mean writing a CLJS wrapper? for that you don't need a compiler at all since CLJS libraries are just uncompiled .cljs files

thheller17:12:27

so you can use whatever. that being said shadow-cljs does not currently support publishing libs so you'd need lein or something else anyways 😉

thheller17:12:05

the challenge you'll face however is writing the library in a way that CLJS can access it

thheller17:12:17

(given that you'll probably be using some npm dependencies?)

escherize17:12:55

Yeah, there are a couple npm dependencies.

thheller17:12:36

yeah thats a problem for people not on shadow-cljs

thheller17:12:49

so you probably need to create some cljsjs packages or so

escherize17:12:00

one of which is react - Not sure how to do the bundling / packaging of the libraries.

thheller17:12:13

react is solved already so thats not a problem

escherize17:12:16

I'd prefer to avoid making cljsjs stuff 🚒

escherize17:12:25

if possible, at least.

thheller17:12:37

its probably fine to write it with shadow-cljs in mind first

thheller17:12:49

and then add the cljsjs parts later (if needed)

escherize17:12:06

Yeah, I think that's what I want to do.

thheller17:12:29

but it is probably going to require some tweaks for the other build tools since npm access is limited

pez20:12:24

@thheller is there some way I can run my npm module library such that the cljs repl can be used? I now tried starting a the simple demo http server code from the user guide (the node hot-reload section). I can start the server and browse to it, but shadow-cljs still doesn’t count that as an app has connected.

pez20:12:47

I guess my question is: how would you do to be able to use the REPL with the npm module code, while developing it?

2
aisamu21:12:28

I asked that a couple days back, but haven't got the chance to test the proposed workaround

pez21:12:47

What was the proposed workaround?

pez21:12:18

I found it. However I am targeting node.

ClashTheBunny21:12:48

Like, you want shadow to rebuild every time node_modules changes?

ClashTheBunny21:12:09

Is it for running in node or the browser?

pez21:12:35

@clashthebunny Assuming you are asking me. 😄 I have some code I’d like to share between some VS Code extensions and am repackaging that code as an NPM module. VS Code is built on Electron, so it is node.

pez21:12:47

Today that code is built using target :node-library and connects to the REPL when the extension starts. But this repackaging is really totally independent on VS Code or anything but node. And I can’t figure out how to get it connected to the REPL.

mauricio.szabo13:12:10

I'm doing the same with Chlorine, my package for Atom, with Shadow-CLJS too

ClashTheBunny21:12:29

They are developing an atom plugin with shadow-cljs.

pez21:12:51

Cool project! They are using the same approach as I do today.

thheller22:12:12

@pez in your build config try :runtime :node and then loading require("./path-to-output/shadow.cljs.devtools.client.node")

thheller22:12:37

it is probably not going to be very reliable but it might work

pez22:12:06

I just tried that, actually. Ran into the problems I had last time I tried to build with the :npm-module target.

pez22:12:10

Lots of complaints when requiring the client. Then no eval. Which I tried to fix using this:

global["SHADOW_NODE_EVAL"] = function (js, smJson) {
        if (smJson) {
            js += "\n//# sourceMappingURL=data:application/json;charset=utf-8;base64,";
            js += Buffer.from(smJson).toString('base64');
        }
        //console.log(js);
        return eval(js);
    };

thheller22:12:33

> Lots of complaints

pez22:12:38

(Which you once gave me, last time I went down this path. 😄)

thheller22:12:39

show me one? two?

thheller22:12:31

REPL is always tricky since we are not in charge of loading the final code

thheller22:12:05

as always you could just use node-repl outside all of this to work on the CLJS side of things

pez22:12:38

The complaints: It starts here:

var shadow = require('./calva_lib/shadow.cljs.devtools.client.node')
undefined
> failed to parse websocket message {:type :repl/init, :repl-state ...

thheller22:12:09

... please ... stop ... removing the most important parts from the errors ...

pez22:12:41

Sorry, I can post it all in a snippet. Just a sec.

thheller22:12:08

post the "end" of the message .. there should be a stacktrace?

thheller22:12:21

or some reason WHY it failed to parse?

thheller22:12:37

the first part is just the message it failed to parse

thheller22:12:46

should maybe drop/re-order that part

pez22:12:11

There was, I was about to paste that too.

ReferenceError: SHADOW_IMPORTED is not defined
    at Object.shadow$cljs$devtools$client$node$is_loaded_QMARK_ [as is_loaded_QMARK_] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:64:24)
    at Object.shadow$cljs$devtools$client$node$repl_init [as repl_init] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:137:40)
    at shadow$cljs$devtools$client$node$process_message (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:478:41)
    at Object.shadow$cljs$devtools$client$env$process_ws_msg [as process_ws_msg] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.env.js:274:102)
    at WebSocket.<anonymous> (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:535:44)
    at WebSocket.emit (events.js:182:13)
    at WebSocket.EventEmitter.emit (domain.js:460:23)
    at Receiver._receiver.onmessage (/Users/pez/Projects/calva-lib/node_modules/ws/lib/WebSocket.js:141:47)
    at Receiver.dataMessage (/Users/pez/Projects/calva-lib/node_modules/ws/lib/Receiver.js:389:14)
    at Receiver.getData (/Users/pez/Projects/calva-lib/node_modules/ws/lib/Receiver.js:330:12)

pez22:12:07

(The message it failed to parse was huge, that’s why I choose to do it in two steps.)

thheller22:12:37

so please take this file and put it into your source path

thheller22:12:18

let me know if that fixes the problem?

pez22:12:31

Doin’ it!

pez22:12:19

Should I remove the :runtime :node thing?

thheller22:12:41

no other changes no

pez22:12:53

OK. I get the same errors.

pez22:12:39

But am unsure which node client I am using, since that runtime directive.

thheller22:12:24

it is connected to the shadow-cljs server using the node ws module. so you are in node.

thheller22:12:46

try

(defn is-loaded? [src]
  (js/$CLJS.SHADOW_ENV.isLoaded src))

thheller22:12:28

it'll probably still fail but I'm gonna need some way to reproduce the problem

pez22:12:24

I restarted the node process after having replaced the is-loaded? function and then I could require the client w/o complaints.

thheller22:12:28

so does the rest work?

pez22:12:33

Getting the SHADOW_NODE_EVAL reference error still. “Installing” it per that code I pasted earlier gives some eval power back.

pez22:12:26

But trying to eval any of my code I get:

ReferenceError: calva is not defined
    at eval (eval at global.SHADOW_NODE_EVAL (repl:7:16), <anonymous>:1:22)
    at eval (eval at global.SHADOW_NODE_EVAL (repl:7:16), <anonymous>:4:3)
    at global.SHADOW_NODE_EVAL (repl:7:16)
    at Object.shadow$cljs$devtools$client$node$node_eval [as node_eval] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:60:14)
    at /Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:177:41
    at Object.shadow$cljs$devtools$client$env$repl_call [as repl_call] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.env.js:154:108)
    at Object.shadow$cljs$devtools$client$node$repl_invoke [as repl_invoke] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:175:92)
    at shadow$cljs$devtools$client$node$process_message (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:482:41)
    at Object.shadow$cljs$devtools$client$env$process_ws_msg [as process_ws_msg] (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.env.js:274:102)
    at WebSocket.<anonymous> (/Users/pez/Projects/calva-lib/packages/calva_lib/shadow.cljs.devtools.client.node.js:535:44)

thheller22:12:53

yeah this is probably not going to work

thheller22:12:59

scopes are weird in electron

pez22:12:20

There’s no electron involved here.

thheller22:12:43

I thought you were loading the code in electron?

pez22:12:58

Yes, I probably am… Let me think about what is going on. I am really just executing node inside the packages folder and then requiring the node client like so: require('./calva_lib/shadow.cljs.devtools.client.node')

thheller22:12:52

well .. that simplifies things a lot ...

pez22:12:01

So I don’t think electron is there in any way.

thheller22:12:05

I thought you were loading electron extensions and stuff

pez22:12:37

No, I have choosen to keep all that vscode stuff in TS. And building a library that only deals with data in CLJS. That is what I am trying to package as a npm module.

thheller22:12:29

well say so next time 😉

pez22:12:53

Haha, I have tried to say it so many times. I probably suck at communication.

thheller22:12:07

ok I have no reproduced. looking into it.

pez22:12:14

Cool. I’ll push this experiment to github so it is easier to look at what the heck it is I am doing.

pez22:12:08

Everything about this is new to me. Electron, VS Code. Node. CLJS. The list goes on. 😄

thheller22:12:34

yeah this is not going to work. especially not in electron.

pez22:12:56

What is not going to work?

thheller22:12:50

node REPL via npm-module

pez22:12:13

I’m not sure where electron enters the picture, but you seem to have doubts regardless?

thheller22:12:40

well that is the ultimate goal no?

pez22:12:09

I want to consume the module in an electron app, yes.

thheller22:12:22

there is no point in getting the node-repl to work in npm-module when you can just use shadow-cljs node-repl instead?

pez23:12:02

I haven’t tried that. First time I hear of it.

thheller23:12:00

if you just want a repl to work on the CLJS side of things just use node-repl

thheller23:12:19

getting the REPL to work inside electron via npm-module is not going to work

pez23:12:34

Today I start the repl using npx shadow-cljs cljs-repl :calva-lib

thheller23:12:00

npx shadow-cljs node-repl

pez23:12:49

I get the same errors as before.

pez23:12:55

But I can eval stuff at the prompt after a while.

thheller23:12:58

doing what?

thheller23:12:23

oh yeah if you have the changed node.cljs still in your sources thats now gonna break stuff

thheller23:12:27

so you need to remove that first

pez23:12:04

But will I be able to connect to the nREPL server too this way?

thheller23:12:43

you can also start the node-repl via nrepl

pez23:12:17

How would I do that?

thheller23:12:34

if you are connected to the CLJ nrepl part you simply call (shadow.cljs.devtools.api/node-repl)

thheller23:12:49

that'll start the node REPL and switch the session to CLJS

pez23:12:54

Awesome. I’ll have to hack Calva to support this, then can continue to hack on Calva using it. 😄

pez23:12:11

I checked the user guide and it says there are no builds involved using this repl. There are big chunks of shadow-cljs knowledge missing for me. I don’t really understand what is different with this repl and the other one.

thheller23:12:42

other REPLs runs as part of your build while your build is doing its thing, eg. rendering something using react when the page loads

thheller23:12:58

node-repl is just a simple node-repl that doesn't do anything on its own until you tell it to do something

pez23:12:07

OK. But I think that should work pretty good for my particular setup.

thheller09:12:46

@pez forgot to mention that there also is a npx shadow-cljs browser-repl in addition to node-repl. same deal, configless but runs in the browser.

pez23:12:14

I’ll make Calva support this mode and continue with the npm-module idea of sharing code between the extensions. It really seems like it should work well. Huge thanks for all this patience with me. I truly appreciate.