Fork me on GitHub
#clojurescript
<
2019-12-12
>
cfleming04:12:05

I’m building some scripts for node.js using simple optimisations. I can’t figure out under which conditions my node_modules deps are included in the output js file. How do I control this? Is it expected that they are included, or should I be bundling node_modules with my js file when deploying?

cfleming04:12:50

I’m using lein-cljsbuild, but it looks like I should probably switch to a build.clj file.

Roman Liutikov07:12:35

hmmm, if you use js/require to require node modules, they shouldn’t go into the bundle then

Roman Liutikov07:12:06

not sure about normal :require with :target :nodejs

thheller08:12:26

@cfleming they are never included. you should use a separate tool like https://github.com/zeit/ncc for that.

cfleming08:12:20

That was my impression from all the doc I could find, but somehow it’s definitely working for me sometimes at the moment. I’m only deploying a single script which requires node files, and they’re in there.

cfleming08:12:32

ncc looks good though, thanks. I’ll try that, or just zip things up.

thheller08:12:33

if you include only the built-in node packages (eg. fs, http, etc) then there is nothing to include from node_modules

thheller08:12:20

maybe you somehow ended up uising :npm-deps which would run the code through the closure-compiler and most likely break it?

cfleming08:12:01

No, I’m using lein-cljsbuild and lein npm, but nothing like that. It definitely somehow includes nodemailer, rollbar etc.

cfleming08:12:31

Anyway, as part of modernising my project all that has broken, so at least now I know it should never have worked 🙂

thheller08:12:37

you just might have those included globally or somehow accessible via the normal resolve rules when running the code

thheller08:12:11

node will check your global installs and /a/b/c/node_modules /a/b/node_modules /a/node_modules /node_modules wherever you run the generated script

thheller08:12:40

so if you run the code in /a/b/c/script.js there are a bunch of location it'll check

cfleming08:12:05

This is running in AWS Lambda, so I assume the env is clean.

cfleming08:12:26

Would you recommend ncc over just zipping?

cfleming08:12:40

Are there advantages to it being more node-aware?

thheller08:12:01

startup time is better with ncc I think

thheller08:12:34

and likely smaller

thheller08:12:51

zipping node_modules usually contains a bunch of stuff you won't actually use

cfleming08:12:58

Ok, thanks - I’ll do that.

cfleming08:12:02

I just tried ncc, and that also didn’t pick up my nodemailer dep. Is package.json required for that? For some reason lein npm never creates one.

thheller08:12:22

I think it only processes your require, but those need to be actual require calls, so only js/require. if you use cljs.nodejs/require then they won't be picked up.

cfleming08:12:06

Hmm. So will it pick up deps using (:require ["foo"]) in ns?

cfleming08:12:18

Does that desugar to js/require?

thheller08:12:30

sorry no clue what standard CLJS emits for that

thheller08:12:42

I'd think it would use js/require but I'm not sure

cfleming08:12:06

I think I’m just going to move this project to shadow-cljs.

thheller08:12:33

that definitely uses require yes 🙂

dabrazhe12:12:44

Hi. How can I create a valid json from a map? I'd expect the keywords to be come strings, but the stay keywords:

(clj->js  {:title "Miss", :first "Freya", :last "Taylor"}))
=>#js {:title "Miss", :first "Freya", :last "Taylor"}

Roman Liutikov12:12:40

that’s just how it’s printed

dabrazhe13:12:34

Not really, it return this #js map as the result and http response parser promptly fails on the keywords: )

#js {"title" "Miss", "first" "Freya", "last" "Taylor"}

aisamu13:12:25

Are you sure that's not expected?

(. js/console log 
(clj->js {:title "Miss", :first "Freya", :last "Taylor"}))
Then, on the browser's console
> ({title: "Miss", first: "Freya", last: "Taylor"}).title
< "Miss"
> ({title: "Miss", first: "Freya", last: "Taylor"})["title"]
< "Miss"

p-himik14:12:13

JS != JSON.

p-himik14:12:18

If something expects a proper JSON string (like an HTTP response parser probably would) and you give it a JS object, that won't work.

Filipe Silva14:12:35

if you want to be super duper sure of what the data structure is on js, print it using JSON.stringuify on the console.log

Filipe Silva14:12:32

(js/console.log (js/JSON.stringify (clj->js {:title "Miss", :first "Freya", :last "Taylor"}))))

Filipe Silva15:12:46

this is what chrome shows

dabrazhe15:12:53

thanks for the replies. on node.js this js/JSON.stringify code results in

{\"title\":\"Miss\",\"first\":\"Freya\",\"last\":\"Taylor\"}"
which makes it promptly fail : )

p-himik15:12:57

This is a perfectly valid JSON, which means that the failure is some place else.

👍 4
dabrazhe15:12:49

:)) will give it another go )

Hi15:12:20

Hello! is there any way to catch global browser exceptions in Clojescript?

Filipe Silva15:12:16

I guess the same way you do in js

Filipe Silva15:12:25

that suggests doing

<script type="text/javascript">
window.onerror = function() {
    alert("Error caught");
};
</script>

Filipe Silva15:12:40

(set! (.-property foo) 5)

Filipe Silva15:12:46

so putting those two together I suppose

(set! (.-onerror window) (fn [] (js/alert "Error caught"))

Filipe Silva15:12:57

I haven't tested it but that sounds reasonable enough

Filipe Silva15:12:46

this is mostly stack overflow driven but the second google search also showed https://cljs.github.io/api/cljs.core/setBANG which lends some extra confidence

Filipe Silva15:12:59

Sets js-var to val using the JavaScript = operator.

Hi16:12:28

What is the best HTTP client for clojurescript?

Roman Liutikov16:12:08

normal js/fetch + cljs-bean library

8
Filipe Silva18:12:57

is the benefit of cljs-bean mostly performance?

Roman Liutikov18:12:38

Yes, but also correctness I think (don't remember the details)

👍 4
scknkkrer13:12:42

Also, you can take a look at this;

dabrazhe18:12:48

@feikas cljs-http.client is quite popular and is a cljs lib. you can use node-fetch and request

Drew Verlee18:12:00

Do any of the Google Closure optimizations rely on how you structure your modules?

oliver18:12:53

Hi everyone, I need a way to parse HTML markup to hiccup on a node.js app. On the client side I used hickory for the job, which unfortunately doesn't play nice on Node because it depends on the DOM API (see here: https://github.com/davidsantiago/hickory/issues/17). I get code completion for the various hickory functions, but they end up undefined at run time. I tried (set! js/DOMParser (.-DOMParser (nodejs/require "xmldom"))) as suggested at https://github.com/davidsantiago/hickory/pull/33; however, the nodejs namespace is undefined and I do not know how to access it. Has anyone gotten hickory to work on Node.js? Any other suggestions as to how I may convert HTML to hiccup? Many thanks!

Drew Verlee19:12:46

I have seen a couple libs and intelliji can try to do this as well. Probably with cursive. Not sure anything is flawless. If its not your app then re-writting it might not be a bad idea anyway as its a time to review everything.

oliver19:12:27

IntelliJi doing it would allow me to past HTMl as hiccup straight into the code, not aactually have my app do the conversion, right? Not 100% sure I understand what you mean by rewriting… rewrite my app? What need to do is fetch some HTML-strings from a DB and operate on them before rendering… I could of course operate on them as mere strings but it would be much easier to convert them to hiccup first… Or do you mean rewriting hickory? In that case I don't feel qualified for that (yet)… Thanks anyway!

Drew Verlee19:12:17

ignore the rewrite comment.

Drew Verlee19:12:25

i didn't understand what you were asking.

Drew Verlee19:12:00

i think hiccup has a html->hiccup string converter.

Drew Verlee19:12:22

i mean, it can go the other way for sure 🙂

oliver19:12:33

Thanks for the idea… but I seems I'm out of luck here… hiccups readme.md says nothing about such a function and the only completions offered by Emacs are : Possible completions are: hiccups.core/defelem hiccups.core/defhtml hiccups.core/html hiccups.core/html4 hiccups.core/html5 hiccups.core/xhtml

oliver19:12:18

looks like hiccups only offers a one-way street

lilactown19:12:19

@UMWM02TED try (js/require "xmldom") instead of nodejs/require

lilactown19:12:26

that’s assuming you’ve installed the xmldom library

oliver20:12:58

Thanks! Yes I have [xmldom "0.1.27"] in my npm dependencies. Also I have already thought here might be a typo as you suggested… (set! js/DOMParser (.-DOMParser (js/require "xmldom"))) does indeed evaluate.

oliver20:12:04

But maybe I've put it in the wrong place… the weird thing is that evaluating (not calling) hickory.core/as-hiccup gives an object whereas hickory.core/parse-fragment gives me nil

oliver20:12:32

hang on, let me check something real quick…

oliver20:12:26

Hi again… so the problem surfaces in two ways: If there's any namespace requiring hickory, node will refuse to run my app, because of

ReferenceError: Node is not defined
    at hickory$core$node_type (/media/lapdaten/ARBEITSSD/dev/violinas_macchiato/target/out/hickory/core.cljs:37:3)

oliver20:12:03

If I strip hickory from my sources (albeit not the from the project. clj) before starting running the app in node everything is fine until I try to use it. With figwheel running I can put hickory back into a nes form and thus require it. But then only certain functions like as-hiccup are available whereas others are not (such as parse-fragment)

oliver20:12:40

Is there any place I can put the changing of the DOM-Parser to alleviate this? Evaluating it at the REPL or putting it into the script prior to any hickory-calls doesn't seem to change anything.

lilactown20:12:45

Try putting it in a namespace that goes in your preloads

lilactown20:12:00

That way the code will run before any of the other code in your app

lilactown20:12:09

Ah, but that will only work in development

lilactown20:12:35

Ugh this is a mess lol

oliver20:12:36

Even more thanks for looking at it then. I'm still rather new to ClojureScript (and Web Development in general) so maybe this is just too much for me now… I was trying to port somehting I had written for the client side to the server and stumbled across this problem… It is a bit surprising that albeit hiccup beinf so central for ClojureScript there should be no way of parsing HTML to it on node…

oliver20:12:03

Anyway, for my problem at hand I should be able to handle it by working on the the string directly with regexes… so be it for now…

oliver20:12:39

I guess I'll take this question to SO, maybe in the long term there will be a solution

lilactown20:12:06

A lot of old libs don't assume node. Many CLJS devs come from Clojure, and don't really consider server side CLJS usage

oliver21:12:34

I see… does make sense of course… unfortunately the JVM is unavailable on my deployment space so I have no choice

oliver21:12:21

I have put this as a questio on SO now since it seems to be non-trivial and relevant to other people… any further suggestions should better go there: https://stackoverflow.com/questions/59312825/clojurescript-hickory-on-nodejs-parse-html-to-hiccup

Drew Verlee19:12:33

What are the debugging options for code thats been advanced Google Closure Compiled?

Drew Verlee19:12:24

Or maybe just as relevent, is there a way to get more information or warnings on your cljs->js compiled code?

dnolen19:12:02

source maps work OK for advanced

dnolen19:12:30

generally speaking there's not much value to debugging advanced complied code - the only time you might need to do that is if something went wrong w/ advanced

dnolen19:12:47

:pseudo-names true :pretty-print true is often enough to see what went wrong in this case too