clojurescript

ClojureScript, a dialect of Clojure that compiles to JavaScript http://clojurescript.org | Currently at 1.10.879
West 2021-05-19T05:43:11.023500Z

Ok, I’ve got a problem I’m trying to wrap my head around. This is a clojurescript file, intended as a node script in the end. The purpose of these few lines is just to get a list or sequence of strings from files.

(ns app.parser
  (:require ;[...]
            [cljs-node-io.core :as io]
            [cljs-node-io.fs :as fs]))

(def all-filenames
  (let [path "src/posts"]
    (rest (io/file-seq path))))

(def all-org-docs
  (map #(fs/readFile % "utf8") all-filenames))
When I run map on all my files, it concatenates the strings from the files rather than returning a lazy-seq. Is this a quirk of cljs’ map function, node’s fs, cljs-node-io, or something else? Using cljs-node-io.core/slurp in place of cljs-node-io.fs/readFile gives me the same result.
app.parser=> (map #(fs/readFile % "utf8") all-filenames)
;;actual
("#+title: my blog post... ... ...)
;;expected
(("#+title: my blog post...")("#+title: second blog post..."))

West 2021-05-19T16:43:48.048300Z

Imma check it.

West 2021-05-19T16:46:54.048500Z

count returned 4. I didn’t notice that they were all separate strings.

West 2021-05-19T16:50:17.048700Z

Thank you @smith.adriane. I guess I just didn’t realize that they were in fact surrounded by quotes.

1👍
phronmophobic 2021-05-19T05:51:56.023800Z

I wouldn't expect each file's contents to be wrapped in a list. Does the result include a number of strings that matches the number of files or one big long string? In other words what's the result of:

(count (map #(fs/readFile % "utf8") all-filenames))

phronmophobic 2021-05-19T05:53:15.024Z

If you did want each file's content wrapped, you could try:

(map #(list (fs/readFile % "utf8")) all-filenames)

Joni Hiltunen 2021-05-19T07:00:39.024700Z

I'm trying to use setInterval and clearInterval but for some reason the clearInterval isn't working... any tips? https://gist.github.com/Sose/c20a64b64b64b47fde7183e4932b9885

Joni Hiltunen 2021-05-19T07:00:48.024900Z

state/app-state is a reagent atom

Joni Hiltunen 2021-05-19T07:01:23.025100Z

oh lol, there's a misplaced ]

Pepijn de Vos 2021-05-19T09:45:56.025700Z

What do you mean with a subscription of a subscription?

Oliver George 2021-05-19T11:44:57.026800Z

Quick poll: Are you using "https://clojurescript.org/guides/webpack" as per the website guide?

Oliver George 2021-05-19T11:46:52.028500Z

(I ask because I hit super slow compilation times after converting a large project over from the old :foreign-libs approach. Wondering if it's proven itself a best practice now.)

thheller 2021-05-19T11:47:52.029500Z

can't comment on how many people use it but compile times will be whatever you had before + however long webpack takes (which can be quite long, depending on how much you use)

Oliver George 2021-05-19T11:48:43.030200Z

Thanks. I think my issue was webpack trying to optimise the advanced compiled output from cljs (from memory).

thheller 2021-05-19T11:50:02.031Z

yeah, thats a problem with :target :bundle.

Oliver George 2021-05-19T11:54:46.031500Z

Any chance you know a webpack alternative I could switch in for this use case?

thheller 2021-05-19T11:55:13.032400Z

well shadow-cljs doesn't have this problem 😉

Oliver George 2021-05-19T11:55:16.032700Z

🙂

thheller 2021-05-19T11:55:26.033Z

its really a problem with :target :bundle not so much webpack. the output of the CLJS build is just passed to whatever other tool you are using. that tool should run some optimzations for the "other" JS code it gets. I'm not aware of any options that let you skip re-optimizing the CLJS output but still optimize the rest.

Oliver George 2021-05-19T11:55:39.033200Z

Thanks anway. Seems like a fight I should walk away from really.

Oliver George 2021-05-19T11:56:23.033900Z

No doubt shadow-cljs is good but I haven't stopped long enough to get familiar with it.

Oliver George 2021-05-19T11:57:49.035100Z

I'd be interested to hear if others have struggled with crazy slow build times using :target :bundle. If so I'll petition for some warnings to be added to the webpack guide on the CLJS website.

thheller 2021-05-19T11:58:33.035700Z

how crazy slow are you seeing? shouldn't be that extreme?

danieroux 2021-05-19T12:03:31.035800Z

I am. The initial bundler is slow, and then the development cycle stays fast.

Oliver George 2021-05-19T12:04:29.036600Z

It was madness, like 10 mins. I https://ask.clojure.org/index.php/9602/recommended-webpack-config-for-clojurescript-bundle-target?show=9602#q9602 but didn't get much help.

thheller 2021-05-19T12:20:42.038200Z

hmm yeah no clue about that. seems a little excessive

danieroux 2021-05-19T12:28:44.038700Z

@olivergeorge the dev-cycle is very acceptable to me. Obviously, no TerserPlugin there. prod-cycle takes a few minutes, not in a way that blocks me

1👍
dnolen 2021-05-19T13:39:24.040300Z

@olivergeorge I think you probably need to dig into this more - like is this a memory issue?

dnolen 2021-05-19T13:39:53.041Z

far as I can know other people using webpack plus bundle on large projects who haven't reported extravagant build times

dnolen 2021-05-19T13:42:02.041500Z

@olivergeorge also based on your report this doesn't really have anything to do w/ Webpack, but perhaps the Terser plugin

dnolen 2021-05-19T13:43:28.042500Z

certainly haven't seen this Metro & bundle target which is a different flavor of the same thing - build times are not extravagant at all

dnolen 2021-05-19T13:48:07.043100Z

in any case since this is the first report I've seen, not really interested in changing anything on the website at this time - need a lot more information first

dnolen 2021-05-19T13:49:30.044100Z

also Terser does allow exclusions - https://stackoverflow.com/questions/56557986/webpack-terserplugin-exclude-node-module

Pepijn de Vos 2021-05-19T13:52:53.047200Z

I'm proper confused. I've created a shadow-cljs project and added reagent, and when I run the watcher and make changes to my reagent example, it recompiles, I see a brief spinning logo at the bottom left in the browser, but the react component is not updated unless I manually reload the whole browser. This worked last week when I first experimented with shadow-cljs and reagent 😞

Pepijn de Vos 2021-05-19T13:58:03.047300Z

derp ^:dev/after-load apparently

2021-05-19T14:51:12.047900Z

I could be wrong but I think this is what deftime (from Macrovich) is for

1👍
West 2021-05-19T16:43:48.048300Z

Imma check it.

West 2021-05-19T16:46:54.048500Z

count returned 4. I didn’t notice that they were all separate strings.

West 2021-05-19T16:50:17.048700Z

Thank you @smith.adriane. I guess I just didn’t realize that they were in fact surrounded by quotes.

1👍
Nate Hunzaker 2021-05-19T17:20:28.050400Z

I have a shadow-cljs question regarding polyfills - I'm struggling to figure out if :output-feature-set :es5 is doing anything, and if so, what polyfills it is including. Is there a good way to get this information?

thheller 2021-05-19T17:25:51.051700Z

polyfills depend on the code you use, I guess there is no easy way to tell which are included. the data exists but it isn't printed anywhere or so.

Nate Hunzaker 2021-05-19T17:36:15.051900Z

Okay cool. Maybe we simply don't use these 😧 . I'll keep digging. Thank you! Right now we have a static list of polyfills we include, but I'd like to drop them if we can. It just gives me a little bit of anxiety. Do these polyfills come from closure compiler?

thheller 2021-05-19T17:37:29.052100Z

yes. which static list are you refering to?

Nate Hunzaker 2021-05-19T17:40:30.052300Z

We just have a javascript module that requires a bunch of ES6 polyfills, roughly:

require("core-js/es6");

require("core-js/fn/array/includes");
require("core-js/fn/string/pad-start");
require("core-js/fn/string/pad-end");
// ... etc

thheller 2021-05-19T17:42:24.052500Z

why? that will at the very least lead to duplicated polyfills for most cases

Nate Hunzaker 2021-05-19T17:45:57.052700Z

I'm concerned about that too 🙂. Some of this is carry over from our old figwheel build process. I can't actually see if these functions are being polyfilled in our production output though. Which means either: 1. Our shadow-cljs config needs to be corrected 2. We aren't using these at all, and so the shadow-cljs release build isn't including them.

thheller 2021-05-19T17:48:01.053Z

yeah its kinda tough sometimes since :advanced can inline some polyfills if only used once and that sort of stuff

thheller 2021-05-19T17:50:04.053200Z

the closure compiler will analyze the code and only end injecting what is actually used

thheller 2021-05-19T17:50:20.053400Z

but it won't account for core-js already providing some

Nate Hunzaker 2021-05-19T17:50:36.053600Z

Right. I guess part of me is a little anxious about it picking up stuff in some of our NPM dependencies. I suppose we have externs.

Nate Hunzaker 2021-05-19T17:52:21.053800Z

The compromise I've come to right now anyway is to load this script with <script nomodule> , which dovetails nicely with our browser support situation.

Nate Hunzaker 2021-05-19T17:58:33.054Z

Anyway, thanks! This was super helpful

grounded_sage 2021-05-19T19:40:57.054600Z

Is there a good way to detect the browser environment in Clojurescript?

dnolen 2021-05-19T19:41:40.054900Z

google closure has some agent detection stuff

1👍
Oliver George 2021-05-19T22:58:23.056200Z

Thanks for the tips/thoughts. I'll give it another go and aim for a minimal repro if it pops up again.

Felipe 2021-05-19T23:25:27.058900Z

hello! I'm using Weasel [1] instead of the browser REPL. is there any way to avoid adding the XPC iframe besides manually removing the following line from the JS output? document.write('<script>goog.require("clojure.browser.repl.preload");</script>'); [1] https://github.com/nrepl/weasel