Fork me on GitHub

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?


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


@cfleming they are never included. you should use a separate tool like for that.


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.


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


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


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


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


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


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


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


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


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


Would you recommend ncc over just zipping?


Are there advantages to it being more node-aware?


startup time is better with ncc I think


and likely smaller


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


Ok, thanks - I’ll do that.


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.


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.


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


Does that desugar to js/require?


sorry no clue what standard CLJS emits for that


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


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


that definitely uses require yes 🙂


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


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"}


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"




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


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

which makes it promptly fail : )


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

👍 4

:)) will give it another go )


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");

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 which lends some extra confidence

Filipe Silva15:12:59

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


What is the best HTTP client for clojurescript?

Roman Liutikov16:12:08

normal js/fetch + cljs-bean library

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

Also, you can take a look at this;


@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?


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: 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; 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.


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 🙂


Thanks for the idea… but I seems I'm out of luck here… hiccups 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


looks like hiccups only offers a one-way street


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


that’s assuming you’ve installed the xmldom library


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.


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


hang on, let me check something real quick…


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)


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)


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.


Try putting it in a namespace that goes in your preloads


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


Ah, but that will only work in development


Ugh this is a mess lol


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…


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…


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


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


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


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:

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?


source maps work OK for advanced


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


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