cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
slipset 2019-11-11T15:17:53.260100Z

My colleague is maintaining clj-refactor, and has this issue going on:

slipset 2019-11-11T15:18:18.261Z

Somewhere near the bottom it is stated (with reference to the docs) that require in cljs is only to be used from the repl: https://cljs.github.io/api/cljs.core/require

slipset 2019-11-11T15:18:55.261600Z

My question is that correct, and if so, why?

bronsa 2019-11-11T15:40:07.263Z

cljs doesn't have a resident compiler (self hosted cljs does) like clojure, which is required to provide eval and thus require

borkdude 2019-11-11T15:41:11.263800Z

I also expect "dynamic" or "conditional" require to give problems with google advanced compilation?

borkdude 2019-11-11T15:44:18.265100Z

Wasn't there something that the compiler tries to work with top-level requires at the start of the namespace? but that's pretty limited

dnolen 2019-11-11T15:51:40.265700Z

@slipset the simplest answer is that ClojureScript is meant to be whole program optimized by Closure

dnolen 2019-11-11T15:51:57.266200Z

that means no dynamic loads - because then that strategy falls apart

dominicm 2019-11-11T15:56:10.268100Z

Kinda related: is it okay to do dynamic loads for development? I was thinking of writing a user.cljs which made conditional calls to load-file.

dnolen 2019-11-11T17:35:17.268800Z

Google Closure support dynamic loads during dev to avoid the compile step yes

dnolen 2019-11-11T17:35:29.269200Z

but you should not embed require into arbitrary locations

dnolen 2019-11-11T17:35:38.269500Z

we don't test this nor care if it doesn't work

dnolen 2019-11-11T17:36:23.270200Z

the only thing that we support is top level require before any other statements

dnolen 2019-11-11T17:37:24.270700Z

@dominicm load-file is not supported

dnolen 2019-11-11T17:37:29.271Z

except at the REPL

dominicm 2019-11-11T17:42:24.271800Z

Hmm. Frustrating. I suppose multiple ns generated by a macro wouldn't be supported either?

dnolen 2019-11-11T17:43:23.272600Z

nope

dominicm 2019-11-11T17:43:23.272700Z

The goal is to combine colliding namespaces into one.

dnolen 2019-11-11T17:44:20.273600Z

one namespace per file - and load-file could never work

dnolen 2019-11-11T17:44:54.274600Z

@dominicm I don't understand what problem you're trying to solve - "colliding namespaces"

dominicm 2019-11-11T17:47:43.279700Z

@dnolen I want a way to load code for my development (without modifying the project I'm on). It followed to me that user.cljs is for the user, not for projects, but projects override it anyway. So the idea was to have my user.cljs load the project user.cljs. One constraint is that it should work with a large number of projects you'd find in the wild. Consistently no matter if they're using cljsbuild, deps, etc.

dnolen 2019-11-11T17:49:56.281300Z

user.cljs works already

dnolen 2019-11-11T17:50:06.281700Z

just require whatever you want there

lilactown 2019-11-11T17:51:46.283500Z

I think there are two ways you can do what you want dominicm (only load some code when in development): The first and easiest way is to use (when goog/DEBUG ...) to define the stuff you want to happen only at DEV time. this should get DCE’d when a release build is run. This works across lein-cljsbuild/deps+figwheel/shadow-cljs

dnolen 2019-11-11T17:53:07.285300Z

@dominicm you cannot "override" user.cljs by the way - we'll load them all - if it doesn't work for some reason you should report a bug with some kind of minimal reproduction

lilactown 2019-11-11T17:55:49.287700Z

this doesn’t work when you want to optionally load a dependency (e.g. an external JS lib), so in that case you have to do something grosser,,,: - set up points in your code that should interact with the code you want to optionally load. something like:

(when (and goog/DEBUG (.-someFn js/someCoolThing))
  (.someFn js/someCoolThing))
- instruct the user to add a my-lib.some-cool-thing that sets up js/someCoolThing into their preloads or user.cljs at DEV time

lilactown 2019-11-11T17:58:03.289Z

it’s a PITA from a lib maintainer POV, but from a user POV they just need to make sure they include the side-effecting ns before any code that uses it (which is why preloads is preferred)

dnolen 2019-11-11T17:58:15.289200Z

@dominicm clojure loads them all

dnolen 2019-11-11T17:58:40.289600Z

or that was my understanding anyway

dominicm 2019-11-11T17:59:50.290300Z

I don't think so. Not when I was playing with it. First in the path won.

dnolen 2019-11-11T18:04:21.290700Z

oh sorry you're right I was thinking about a different problem that we solved

dnolen 2019-11-11T18:04:46.291200Z

which is that you can have N files which don't declare a ns

dnolen 2019-11-11T18:05:02.291600Z

so we do some magic to make sure that these get defined in cljs.user

dnolen 2019-11-11T18:05:58.292100Z

@dominicm but note user.clj is just a convenience

dnolen 2019-11-11T18:06:22.292600Z

nothing is stopping you from starting a REPL that loads your thing as well

dnolen 2019-11-11T18:06:26.292900Z

so I'd say stop messing around with user.clj

😈 1
dnolen 2019-11-11T18:06:48.293400Z

make a file called my_dev.clj and load that into your REPL

dnolen 2019-11-11T18:06:53.293600Z

this should also work for ClojureScript

dnolen 2019-11-11T18:07:29.294200Z

you can use an alias if you want to avoid repeating yourself of course

lilactown 2019-11-11T18:24:07.295Z

determining conditional ns at macro-time is something that comes up semi-often for frameworky stuff that I wish there was better support. I can work around it, but it’s onerous as the lib maintainer.

1
dominicm 2019-11-11T18:35:04.296Z

You're right of course. That's a small cost to pay for the functionality. I perhaps got too tied up in the fully automatic aspect.