cljs-dev

ClojureScript compiler & std lib dev, https://clojurescript.org/community/dev
john 2020-04-25T00:04:17.434Z

So, are you saying that one would use :require instead of :import for the goog libs? Isn't it the case that you'd usually only ever see an inner class $ situation in CLJ when using the :import context? If we want to ride on existing idioms, would it make sense to keep this behavior to the :import context? I love the $ idea!

john 2020-04-25T00:04:59.434500Z

plus, :import is for external stuff anyway

john 2020-04-25T00:07:30.437300Z

As an OG Clojurist, I vote for the $ syntax. Strongly dislike adding : within symbols, since some things like to store keywords concatenated as a string (without a space).

2020-04-25T00:07:49.437800Z

Two things to consider: 1. Would there ever be ambiguity with choosing $? Could JS start using this for other thing? What about Clojure? 2. Is it easy to auto-complete? For example, $ can act as a marker, saying, ok now auto-complete given what's before what can come after

john 2020-04-25T00:09:24.438900Z

Also, how does :refer work, if the referred thing is a data property rather than a fn? Does it just become the value of the property?

john 2020-04-25T00:10:39.439900Z

And my last question would be: What are the possible ways in which a Clojure user's expectations of the $ symbol for inner classes be violated when trying to use this feature in CLJS land? Any?

2020-04-25T00:29:54.441500Z

Man, JS modules are a mess šŸ˜› I don't think I even really understand how things are imported in JS, so I can't contribute too much. But I always thought it was really confusing that I can't just :require x.y.x :as foo for everything. So if this gives me that, I'd say +1. And the whole thing with import I still don't really understand what needs imported and why.

2020-04-25T00:31:02.442700Z

Also, I would find it weird that I need to use ns for requiring/importing. I would always expect that I can choose to use require and import on their own, outside of ns as well.

john 2020-04-25T00:31:34.443400Z

congruence of semantics between clj and cljs for import and require would be sweet

2020-04-25T00:31:55.443900Z

So I think whatever CLJS does with ns, it should be compatible with require and import, or it needs to add new functions, if there was a :default now you need a matching default function, etc.

john 2020-04-25T00:34:08.445600Z

@didibus I think the default would go as a tag in the require or import vector, not as a top level command like require or import, so wouldn't have an associated fn. But yeah, the default stuff is all another language to me too.

2020-04-25T00:36:50.448300Z

I personally like to try and be as consistent with Clojure. But I also think there shouldn't be anything that is not possible to import due to this constraint. And maybe for me, the latter is more important. Like there's nothing more frustrating but to hit a wall and realize there's just no way to require what you need. Which I'm concerned a little bit in case $ can clash. Would there be a way to say escape the one that is for require vs the one that is in the name?

lilactown 2020-04-25T00:37:04.448600Z

dynamic require is just not something thatā€™s easily supported and my guess is probably wonā€™t be in the near future

john 2020-04-25T00:38:59.449700Z

I guess the string version could allow you to escape the $ that happened to be in js name? I never liked the string syntax though.

2020-04-25T00:39:21.450Z

I hate the string syntax (as a mainly Clojure dev)

lilactown 2020-04-25T00:40:31.450600Z

my understanding is that :import would still be there for some google closure interop.

lilactown 2020-04-25T00:43:17.452800Z

the proposal is: :require would be used to access CLJS namespaces, external JS packages, and globals importing a JS property as a namespace would be supported using the new feature, at this time the $ in the middle would delimit the package/global and the property

lilactown 2020-04-25T00:46:09.454400Z

I think it would be better to use :import to add some new semantic, since itā€™s used so infrequently, but the semantics weā€™re talking about (using an object property as a namespace) doesnā€™t match the semantics of Clojureā€™s :import at all

john 2020-04-25T00:46:28.454600Z

How so?

john 2020-04-25T00:47:08.455700Z

Does the inner class thing and the nested object thing really differ so much? And how so?

lilactown 2020-04-25T00:48:14.457Z

import in Clojure brings in a Java class as a value the nested object require weā€™re talking about brings in a JS object as a namespace

john 2020-04-25T00:49:15.458400Z

In code, rather than in namespace declarations, right?

lilactown 2020-04-25T00:49:47.459400Z

example:

(ns <http://corp.app|corp.app>
  (:require
   [window$console :as console]))

(console/log "hi")

john 2020-04-25T00:50:13.460300Z

Right, but (.-log console) wouldn't work, right?

lilactown 2020-04-25T00:50:21.460500Z

ĀÆ\(惄)/ĀÆ

2020-04-25T00:50:25.460800Z

Hum, Clojure's import is a bit crappy though, it doesn't follow require syntax, so everyone get it mixed up all the time. And it has no features, can't alias, refer is implicit, etc. But hey, I guess in Clojure the ship as sailed. That said, the syntax is the same as for namespaces outside of it. If you imported a.b Foo you can do Foo/ for everything else. And I think one thing confusing in CLJS, is that there's no logic. In Clojure you can say.. require for Clojure stuff, import for java stuff. It be nice if that was true in cljs as well

john 2020-04-25T00:50:35.461200Z

Well, then it's seems like a value

lilactown 2020-04-25T00:50:53.461700Z

I donā€™t know that it would disallow, but it does allow (console/log ,,,) which is typically reserved for namespaces

lilactown 2020-04-25T00:51:19.462300Z

CLJS doesnā€™t actually have namespaces as values, so

lilactown 2020-04-25T00:51:36.462900Z

and a lot of objects masquerade as namespaces already

john 2020-04-25T00:52:33.463500Z

Yeah, I guess there's an argument for not inheriting CLJ's namespace ugly-parts

lilactown 2020-04-25T00:55:42.467100Z

:import alone also doesnā€™t really solve the problem we started with:

(ns <http://corp.app|corp.app>
  (:import
   ["react" default]
   ["@corp/my-lib" default]))
you get two default bindings, need to introduce some way to alias them, you might even want to add :referā€¦.

2020-04-25T00:55:50.467400Z

Can someone explain to me what we mean here between namespace thing and object thing? Like what's wrong with: (import [window console]) and then I can do console/log ?

john 2020-04-25T00:56:13.467900Z

To be honest... If I go back to the first time I saw the $, I think I wished that it could have been a ., just to minimize the noise. But if there's any utility keep it, and it's not an artifact of java-isms, then I'd love to see $ smooth out the interop between CLJS and JS.

2020-04-25T00:56:41.468300Z

In Java you don't actually use $ for inner class, that's only used in ASM, which Clojure compiler uses. So you can say it is more of a Clojure thing then a Java thing in my opinion

john 2020-04-25T00:58:30.469700Z

ah, right... a java-interop-ism, under the covers

lilactown 2020-04-25T00:59:36.470500Z

it's a JVM thing? šŸ™‚

2020-04-25T01:00:14.471200Z

I guess a JVM thing, but Clojure could have chosen whatever symbol it wants, Java for example uses .: outer.inner.

john 2020-04-25T01:01:06.472600Z

Well, there might have been a decision at the time, where maybe using . caused some ambiguity

2020-04-25T01:01:13.472800Z

So in fact, lots of Java folks get tripped up in Clojure, and ask how to access an inner class, because they try . and it doesn't work šŸ˜›

2020-04-25T01:03:12.474600Z

Ya, I think making it $ is equivalent to Clojure's /. So now given any prefix a.b.c$d you know to look up a.b.c for d. Otherwise you'd need some more elaborate logic I think. Like can you find a.b.c.d in the map? No, ok try a.b.c ? No, ok try a.b, ok found it, ok now from it look for c.d, etc.

2020-04-25T01:05:12.475700Z

Anyways, so if I understand the issue, this is about how do you alias and refer JS dependencies? Cause without those features, seems import could work for everything no?

john 2020-04-25T01:07:08.478200Z

Well, after thinking about it some more, the :import syntax is generally disliked, by everybody, in it not having the :as and :refer and friends. And if we're putting this stuff there just to be like CLJ, then would you also disallow :refer? Seems draconian...

2020-04-25T01:09:01.480800Z

I guess I'm just trying to unravel the "issue". In Clojure, you want to use a function from Java, you always need to prefix the classname or even fully qualify it. Like I said before, this seems a bit underwhelming in features, but it also motivates people to wrap Java stuff in Clojure.

john 2020-04-25T01:10:12.481600Z

There's a bunch of weird import/export scenarios in JS that this feature would nicely address - one of which was the default issue

lilactown 2020-04-25T01:12:03.483800Z

I think there are two things to consider for the proposal of using :import for JS libs: ā€¢ import in Clojure land typically imports a class that's used as a value, not a namespace, so it would be a slight semantic diff ā€¢ you would want things like :as , :refer , :rename , etc. to avoid collisions which would be additional syntax inside the :import section dnolen has been pretty explicit that he isn't interested in extending the ns form and adding more differences between Clojure and CLJS, but maybe these differences are more palatable seeing as import has very little direct relation between the two platforms

john 2020-04-25T01:12:03.483900Z

I also personally like how it addresses "the differences between clojure and clojurescript" issue... if only a little

2020-04-25T01:12:28.484500Z

Right, but all of these "weird import/export" seems out of place for Clojure. It seems JS is trying to bring so much "user convenience". Like I'm so lazy, I don't even want to choose what to import, I want the export to define defaults that magically appear in my import and might change at any upgrade because the export controls it

john 2020-04-25T01:13:25.485500Z

@didibus but we need some way to map the lib in... and js/ or "..@blah." is a wild west

john 2020-04-25T01:14:32.486900Z

@lilactown what do you mean by "`import` in Clojure land typically imports a class that's used as a value, not a namespace, so it would be a slight semantic diff"

2020-04-25T01:14:48.487700Z

So maybe this is where I'm not familiar with the complexities. But why can't you just: (import whatever) and then do (whatever/some-fn) and (.- some-field whatever) ?

john 2020-04-25T01:16:13.489400Z

When used in an ns declaration, isn't it [Some$Foo bar]? Where that's more-so an ns than a value. Or are you talking about using Some$Foo/bar in code?

2020-04-25T01:17:47.491700Z

You asking me? In Clojure it would be (import some.package OuterClass$InnerClass] and then in code you do: (OuterClass$InnerClass/some-fn)

john 2020-04-25T01:18:09.492200Z

@didibus because if the lib exported as, for instance, default, then neither of those existing ways get at the export correctly. I can't remember the details, but I've been bit by the complexity of it.

john 2020-04-25T01:18:32.492500Z

ah, right

lilactown 2020-04-25T01:18:53.493Z

I thought that foo/bar was reserved for namespaces. clearly I'm mistaken

john 2020-04-25T01:19:41.494Z

well, you can access a static method off the class using foo/bar as well, right?

lilactown 2020-04-25T01:19:57.494500Z

TIL

john 2020-04-25T01:20:27.495Z

Well, more like Foo/bar

2020-04-25T01:20:35.495300Z

Same access syntax for both

2020-04-25T01:21:26.496100Z

The only difference is you would never do: (.-field some-ns) but you might do: (.-field SomeClass)

2020-04-25T01:22:10.496600Z

Well... hum, actually I'm a bit fuzzy here, might still be (SomeClass/field) actually.

2020-04-25T01:22:43.497300Z

But that field access is syntax sugar for the . special form, which would be: (. SomeClass -someField)

2020-04-25T01:24:34.498600Z

It be nice if someone could describe such an edge case that makes it you can't do things exactly how they are in Clojure to me šŸ˜„

john 2020-04-25T01:25:20.499Z

Another question: what would this whole solution look like if . was used instead of $? Would that introduce any ambiguity?

john 2020-04-25T01:25:57.499400Z

If not, is there any point in adding $ at all?

2020-04-25T01:27:23.000300Z

It still all seems to me like all the challenge here are due to having used require for JS stuff as well, and not just cljs stuff.

john 2020-04-25T01:27:32.000500Z

Wasn't it mentioned somewhere above that . was also a possibility?

lilactown 2020-04-25T01:28:31.001600Z

. is used in JS package names so can be ambiguous

2020-04-25T01:28:34.001700Z

I think I understand the intent at first, like, hey JS modules are closer to Clojure ones, so why not pretend like they are Cljs libs, but clearly, they were different enough that now we have a weird state of affair

john 2020-04-25T01:28:42.001900Z

ah

john 2020-04-25T01:28:45.002100Z

So that's out

john 2020-04-25T01:29:29.002600Z

Well, that wouldn't work for us anyway? :thinking_face:

john 2020-04-25T01:30:37.004300Z

I don't think cljs's require has gotten weird yet. Except for the string requires

2020-04-25T01:30:52.004600Z

Which I think is where dnolen is coming from. Like saying, ok we don't want a js-require. So either we want to use import, but that's not convenient because people seem to really want to be able to alias, or refer things from JS lib as well. If so, then we must find a way to make them work as if they are ClojureScript lib with standard require. And now the question is.. can we?

john 2020-04-25T01:31:03.004900Z

I guess that's a necessary escape hatch though

john 2020-04-25T01:33:33.005800Z

@didibus Yeah, sounds like david and team got most of the way there over the last few years and a kind of solution is finally coming together.

john 2020-04-25T01:34:34.006500Z

Might not solve all edge cases, but it doesn't sound like the string require escape hatch is going away.

2020-04-25T02:24:32.007200Z

Speaking of which, it is also inconssitent with Clojure for enums to be EventType.value and not EventType/value. Don't know what the rational was for that

2020-04-25T03:09:54.007300Z

I think the string require is a good reason for needing some form of aliasing

2020-04-25T03:10:15.007500Z

Since you wouldn't even be able to type the fully qualified version in code

2020-04-25T03:10:38.007700Z

unless you allowed "lib"/some-fn

2020-04-25T03:10:47.007900Z

which seems a worse compromise

2020-04-25T03:13:33.008400Z

Also, would ClojureScript be able to handle dynamic imports?

2020-04-25T03:42:40.009400Z

@didibus Thereā€™s no such thing as a class in JS. Itā€™s all objects. You always access objects with ..

2020-04-25T12:11:52.036300Z

. is the interop special form.

2020-04-25T03:43:07.009600Z

/ is used exclusively for namespaces in cljs

2020-04-25T03:59:25.010500Z

But that's a decision made within the ClojureScript project

2020-04-25T04:00:42.012500Z

And it appears to me here we are suggesting that we want to lift Objects in JS which act as namespaces as if they were namespaces and treat them so.

frozar 2020-04-25T04:01:04.012700Z

What an animated (and overwhelming) debate, I wish a good rest to the CLJS team during this week-end. Event if I arrived after the battle, I thought maybe I can add something. I was wondering if is was possible to get the name of all npm package. The answer is "yes", and guess what: there's a npm package for it "all-the-package-names". It just output every package on stdout.

npx all-the-package-names | grep "coffee.*maker" | wc -l
4

npx all-the-package-names | grep get-or-set | wc -l
1
You can find anything there. Yeah, coffee maker packages exist (you can check it yourself). These JS funny guys have a package for everything! I you do get how huge is this ecosystem, I highly recommend you to take a look at the generated galaxy regarding npm: https://anvaka.github.io/pm/#/galaxy/npm (you should take a seat before using this link). So from there, I check if there's any package with the $ character: no package involved the character, good news! But:
npx all-the-package-names | grep "dollar" | wc -l
123
We're just one step away from it. One day, a JS dev will find to long to use dollar in a package name and will prefer $ instead: concise, explicit, straightforward, only benefits => profits! And who knows, if emoji are allow, why not use them in package name? More seriously, I wonder if they were forbidden characters in package name. I found a npm package which answer this question, "validate-npm-package-name" (https://github.com/npm/validate-npm-package-name): package every where. In its README, you can find the Naming Rules (https://github.com/npm/validate-npm-package-name#naming-rules) of package name. It says explicitly that package name cannot contain these characters: ~)('!* Any character for this list can be used as a delimiter IMHO, and my favorite one is !.

2020-04-25T04:02:09.013600Z

To me, a prototype acts as both a Class and its instance, so I would have found it natural to treat them as a Class as well

2020-04-25T04:04:08.013800Z

@fabien.rozar Good investigation! The other issue is you need it to also not clash with possible ClojureScript namespace names. And the rules for that is it may include: . * + ! - _ ? $ % &amp; = &lt; &gt; : #. Though I guess it already allows $ so if something were to happen, we'd be breaking compatibility if there are any existing namespace with a $ in it

2020-04-25T04:07:52.014Z

I'm not sure what you mean by always access objects with . ?

2020-04-25T11:24:03.015100Z

Hi guys. I ran into some problems with the latest version of CLJS. I reported about it here https://ask.clojure.org/index.php/9260/some-problems-with-latest-cljs-1-10-741

dnolen 2020-04-25T11:29:22.016400Z

@fabien.rozar that's useful info thanks, it's been 10+ years of Node and you haven't seen $ in package name, I'm not too concerned at this point, again it aligns with some Clojure-isms so that's a plus

dnolen 2020-04-25T11:30:32.017400Z

@didibus no dynamic imports, we're never going to work on that outside of what's needed for REPLs and all the various restrictions that apply for even that case

dnolen 2020-04-25T11:33:38.019300Z

@john . just not under consideration - Foo/bar thing from Clojure can't work because Clojure knows that Foo is a class and not a namespace, we don't have this information in ClojureScript generally, including foreign libraries coming from node_modules - there's no type information to figure this out

dnolen 2020-04-25T11:37:18.020900Z

@didibus Not really interested in :import it really only serves one purpose - a way to get a certains kind of GCL libraries, it's not relevant outside that use case. The other problem is that :import has a very restrictive syntax, again not interested in any changes - so not useful in this context.

dnolen 2020-04-25T11:44:05.022900Z

all the feedback is appreciated. Just want to reiterate not interested in any change to the ns form wrt syntax, if your idea is based on that let it rest šŸ™‚

dnolen 2020-04-25T11:45:02.024Z

$ is still a primary contender given it exists in Clojure in a similar context, it's been used before in CLJS bootstrap, and it's unlikely to clash for cases that matter to most ClojureScript users

dnolen 2020-04-25T11:47:09.026Z

what we're proposing now is about reconciling 2 different but related problems: A) global stuff that's loaded outside of ClojureScript B) being able to treat some property, not nested, of a JS value as a namespace

dnolen 2020-04-25T11:47:53.026700Z

(:require [goog.global.Math :as math]) (:require [goog.global$Math :as math])

dnolen 2020-04-25T11:48:09.027100Z

is the essence of this proposal, very little else

dnolen 2020-04-25T11:55:03.027900Z

it's utility for ES6 default just falls out, not an essential thing

dnolen 2020-04-25T11:56:39.028900Z

secondary benefits, for goog.global.Math where GCL has externs we can do the same arity, existence, validation as is done for GCL namespaces

dnolen 2020-04-25T11:56:48.029100Z

(doc string too)

dnolen 2020-04-25T11:56:55.029300Z

anything that's in the extern

frozar 2020-04-25T12:00:33.031100Z

Ok, just to say, concerning cljdoc, its trajectory is clear thanks to the above discussion, thank you šŸ˜ø (I just follow the discuss for other issue you're talking, that's it)

2020-04-25T12:05:19.033200Z

@dnolen after looking more into https://clojure.atlassian.net/browse/CLJS-3159 I now think that perhaps we could have reify* special instead of fiddling with anonymous deftype, this would also align with Clojure, wdyt?

dnolen 2020-04-25T12:07:36.033700Z

@roman01la for that why can't you just mark the var as private?

dnolen 2020-04-25T12:08:04.034100Z

I don't know why deftype needs to do anything here except preserver the private var meta if it doesn't

2020-04-25T12:08:31.034500Z

hmm, good point. Would that solve https://clojure.atlassian.net/browse/CLJS-3160 though?

dnolen 2020-04-25T12:08:40.034700Z

I left that comment on that one

2020-04-25T12:09:40.035Z

I guess it should, will give it a try, thanks

dnolen 2020-04-25T12:10:43.035700Z

3160 seems a bit contrived to me - I don't know how these vars would every appear in numeric forms

2020-04-25T12:11:30.036Z

I think it went out of https://clojure.atlassian.net/browse/CLJS-2875

2020-04-25T12:11:49.036200Z

> The ns-publics issue is related to the use of reify inside cljs.core/nil-iter's definition and incorrect type information being established: A Var is created, which is tagged as being of function type, when in fact the Var's value is nil. Then when the var special is applied to the Var's symbol, there is a bit of code that would normally conditionally include test meta in the generated Var:

dnolen 2020-04-25T12:13:47.037200Z

yeah going to have to look all that later - that's a bit too much for me to load - the public problem is easy and obviously should be fixed

2020-04-25T12:15:27.037700Z

I can work on that, just need more input

dnolen 2020-04-25T12:24:06.038100Z

in the symbol passed to deftype just (vary-meta x assoc :private true)

šŸ‘ 1
john 2020-04-25T12:45:04.041100Z

@dnolen okay, understood. Is it true that $ would only be used in ns declarations? Or could I go (ns (:require [X.Y])) (Y$someFn))?

2020-04-25T12:46:33.041200Z

@dnolen any thoughts on it?

dnolen 2020-04-25T12:47:54.041700Z

I tried to be pretty clear about what I proposed

dnolen 2020-04-25T12:48:08.042Z

if I haven't mentioned then it's not something under consideration

dnolen 2020-04-25T12:48:31.042500Z

so just rule out anything not in mentioned in the two forms above

dnolen 2020-04-25T12:49:49.042600Z

no will have to look at that later

šŸ‘Œ 1
thheller 2020-04-25T12:51:35.044100Z

using this example (:require [goog.global$Math :as math]). How do you know at compile time what can be used before $? I mean even goog.global does not exist as a namespace and is itself a property of the goog "global"?

dnolen 2020-04-25T12:52:25.044700Z

I said there are two parts

dnolen 2020-04-25T12:52:41.045100Z

A) global stuff B) one level $ property access

dnolen 2020-04-25T12:52:52.045400Z

both need implementation support

dnolen 2020-04-25T12:54:10.046600Z

but how it's going to work isn't really important

thheller 2020-04-25T12:59:41.048100Z

so I guess its too early to ask about implementation details? I'll come back in a couple days then.

dnolen 2020-04-25T13:00:13.049300Z

implementation details are not a discussion point, and not going to be looking for feedback about that

thheller 2020-04-25T13:00:14.049400Z

my concern is about figuring out what can be valid as a "prefix" (ie. prefix$Thing)?

dnolen 2020-04-25T13:00:29.049700Z

semantics sure

dnolen 2020-04-25T13:00:58.050500Z

@john I would drop this line of thinking šŸ™‚ don't worry about how it's going to work, we're past that part now

john 2020-04-25T13:01:32.051400Z

I'm not advocating one way or another. Just trying to better understand what's under consideration

dnolen 2020-04-25T13:01:59.052300Z

sure, but the answer is if I didn't mention it above, not under consideration - what's above is it

dnolen 2020-04-25T13:02:23.052900Z

@thheller re: semantics

dnolen 2020-04-25T13:02:40.053700Z

goog.global - you can't know what's there anyway, that's the whole point

thheller 2020-04-25T13:03:05.054500Z

you used (:require [goog.global$Math :as math]) as an example. I'm trying to figure out how you get to the point of knowing that goog.global is valid and correct? is it just a hardcoded default?

dnolen 2020-04-25T13:03:08.054700Z

what we can do is validate against known globals via externs, and warn if foreign entry w/o file isn't provided

dnolen 2020-04-25T13:03:41.055Z

does that answer your question?

thheller 2020-04-25T13:04:13.055300Z

I guess

thheller 2020-04-25T13:06:17.056800Z

sort of don't like the ambiguities that creates though. goog.string.format would also be valid as goog.string$format by that logic. given that it exists as a goog.provide and a runtime "var"

dnolen 2020-04-25T13:07:25.057600Z

the ambiguity doesn't seem meaningful though, I don't see how this could lead to any real correctness issues

dnolen 2020-04-25T13:07:57.058300Z

the whole point of this idea is that it perfectly aligns w/ object as namespace convention

dominicm 2020-04-25T13:39:35.059800Z

Would it be usable for things that are renamed? Eg in the case of goog string? I think I've not well followed what the impact of externs is

dnolen 2020-04-25T13:45:57.060300Z

the proposal doesn't change anything about the ns form - all features work

dnolen 2020-04-25T13:46:17.060500Z

no limitations

dnolen 2020-04-25T13:47:50.061100Z

if you think about the proposal is really just allowing something which already true right now

dnolen 2020-04-25T13:48:19.061600Z

in regular JS libraries - objects are used to represent nested namespaces

dnolen 2020-04-25T13:48:35.062100Z

in global objects loaded by something else - objects are used to represent nested namespaces

dnolen 2020-04-25T13:49:01.062600Z

the proposal just lets you get them even if there is no goog.provide

dnolen 2020-04-25T13:49:23.063100Z

which there never will be for global things nor node_modules

dnolen 2020-04-25T13:50:33.064Z

if you squint - this is an incredible minimal change, with significant repercussions that allow to cover all use cases of external JS

dnolen 2020-04-25T13:50:42.064300Z

everything can be required normally

2020-04-25T13:54:28.066700Z

Feedback on :bundle target - Setting :output-to to a different dir than :output-dir breaks import {npmDeps} from "./npm_deps.js";, since the path should be different - :bundle-cmd doesn't output stdout/err of whatever command it executes, which makes it less obvious to find out if something is broken or not

dnolen 2020-04-25T13:56:54.068400Z

@roman01la minor ticket + patch welcome for more flexible path, and another one for printing out stderr on failure

šŸ‘ 1
2020-04-25T14:04:42.068600Z

just added one more issue related to node target

2020-04-25T14:38:40.069500Z

I guess there already was a discussion regarding generating JS exports for ^:export vars with :bundle target?

dnolen 2020-04-25T14:39:47.069700Z

@roman01la what do you mean?

2020-04-25T14:41:15.070800Z

To turn (def ^:export x 1) into module.exports.x = cljs.user.x when :bundle target is set

dnolen 2020-04-25T14:42:39.071600Z

this seems a bit esoteric for most users

dnolen 2020-04-25T14:43:21.072200Z

it's also trivial to do this downstream

2020-04-25T14:43:38.072600Z

sure, btw who are those most users in your opinion?

dnolen 2020-04-25T14:43:51.073Z

what I mean is I don't really care if you need it

dnolen 2020-04-25T14:43:57.073200Z

if it can be solved downstream

dnolen 2020-04-25T14:44:11.073700Z

if there's some use case you believe everyone is going to hit then something to talk about

dnolen 2020-04-25T14:44:13.073900Z

which is what?

dnolen 2020-04-25T14:46:07.075600Z

I also want to point out something which I haven't had time to elaborate is there's a ton of change to make downstream tooling trivial

dnolen 2020-04-25T14:46:13.075900Z

w/o a ton of ceremony

dnolen 2020-04-25T14:46:46.076300Z

what I'm really tired of is tools that do everything

2020-04-25T14:46:57.076600Z

yes, I agree

dnolen 2020-04-25T14:47:25.077100Z

this is literally what krell does

dnolen 2020-04-25T14:47:34.077400Z

just call cljs.main

dnolen 2020-04-25T14:47:40.077600Z

to rewrite requires for assets

dnolen 2020-04-25T14:48:34.078500Z

instead a morass of plugins and plugin architectures or giant balls of mud

šŸ‘ 2
dnolen 2020-04-25T14:48:51.079Z

write some functions, make a deps.edn alias

dnolen 2020-04-25T14:48:53.079300Z

sleep soundly

dnolen 2020-04-25T14:50:39.080200Z

i think the only way to avoid the cluster that is JS is to not publish this stuff

2020-04-25T14:50:42.080500Z

ho, that's a nice example of using compiler passes

dnolen 2020-04-25T14:50:53.080800Z

not try to compose this transformation stuff, if you need it just write 20-30 lines of code

dnolen 2020-04-25T14:51:50.081200Z

@roman01la yes so again I haven't had a ton of time to document this

dnolen 2020-04-25T14:52:06.081700Z

but I made a lot of things public in the api nses

dnolen 2020-04-25T14:52:19.082300Z

there's more work to do here, but I would I like to see people hit that stuff hard

dnolen 2020-04-25T14:52:24.082500Z

to do typical custom stuff

dnolen 2020-04-25T14:52:38.083Z

some namespaces like cljs.build.api is krufty

dnolen 2020-04-25T14:52:54.083500Z

so it maybe that we need cljs.build.api2

dnolen 2020-04-25T14:53:24.084Z

also later not now I would like to do some of the things that shadow-cljs wrt to the pipeline

dnolen 2020-04-25T14:54:03.084900Z

shadow-cljs IMO does too much, has too many options, but the general idea of keeping everything in data and only a final flush to disk is sound and easier to reason about

dnolen 2020-04-25T14:55:05.085500Z

and I would like see to public apis for that when we get there

2020-04-25T14:57:44.086800Z

sounds good, I could help with code or docs/guides, but that would still require some of your time, to put thoughts on paper

dnolen 2020-04-25T14:59:04.088100Z

@roman01la I believe you have enough right now to handle the export stuff, just binding a pass around build that collects ^:export vars and then generate the :target-fn

dnolen 2020-04-25T14:59:23.088500Z

doing that will probably help us see what's missing to make this cleaner easier

dnolen 2020-04-25T14:59:59.089300Z

so the next person can go solve their own problems and not bother me šŸ˜‰

2020-04-25T15:00:15.089600Z

sounds like a plan šŸ™‚

dnolen 2020-04-25T15:08:11.089700Z

reproduced and fixed, cutting a release just for the Quick Start - it seems like a pretty old bug

šŸŽ‰ 1
dnolen 2020-04-25T15:37:40.090200Z

https://clojure.atlassian.net/browse/CLJS-3233

šŸ‘ 1
dnolen 2020-04-25T15:39:38.090400Z

https://clojure.atlassian.net/browse/CLJS-3235

dominicm 2020-04-25T15:55:33.090900Z

cljs-3233: what does "disciplined" mean here?

dnolen 2020-04-25T16:05:17.092Z

a proper require vs. interacting with global libraries will-nilly

dnolen 2020-04-25T16:20:05.092900Z

@dazld https://clojure.atlassian.net/browse/CLJS-3236 working on this now

šŸ‘ 1
2020-04-25T17:34:16.094700Z

My confusion here from a mostly Clojure dev is what you mean by "as a namespace"? As opposed to what? You referring to the use of js/ instead?

dazld 2020-04-25T18:18:11.094900Z

thumbs up! tried out the git url and no more warnings!

dazld 2020-04-25T18:18:43.095100Z

updated my original repo with a link to that commit

dazld 2020-04-25T18:18:53.095300Z

think itā€™ll get into the next release?

dnolen 2020-04-25T19:01:25.095600Z

yes

dnolen 2020-04-25T19:01:39.095800Z

there'll probably be one later in the week to address straggling issues

2020-04-25T19:57:06.098500Z

This one is interesting. Depending on ClojureScript code from JS with optimizations set to :none doesn't work, because ClojureScript output is loaded asynchronously. First browser loads Webpack output, which includes deps loader which only then loads ClojureScript output.

2020-04-25T19:59:03.100Z

Also running Webpack in watch mode from :bundle-cmd blocks REPL, which means Webpack process should start in background and then it's a bit more tricky to manage this

dnolen 2020-04-25T19:59:34.100500Z

I don't know what you mean at all about the first thing

dnolen 2020-04-25T20:00:08.101Z

running watch form :bundle-cmd is gratuitous

dnolen 2020-04-25T20:00:42.101500Z

in the case of Metro the expectation si something else is going to run the bundler

dnolen 2020-04-25T20:02:02.102600Z

I don't see why it should be different for any other watching scenario

dnolen 2020-04-25T20:02:06.102800Z

there will be zero changes to :bundle-cmd

dnolen 2020-04-25T20:02:11.103Z

except for more error reporting

2020-04-25T20:02:34.103400Z

yeah I'm just providing feedback from my observations

dnolen 2020-04-25T20:03:01.104200Z

yes that's useful - what needed here is just docs about the limitations

dnolen 2020-04-25T20:03:19.104500Z

modifying the :bundle-cmd docs now

dnolen 2020-04-25T20:05:14.106400Z

Updated. I still don't understand your first comment about :none

2020-04-25T20:06:02.106600Z

> running watch formĀ :bundle-cmdĀ is gratuitous I have JS module that consumes ClojureScript and renders Reagent component in existing JS code. Here it makes sense to run Webpack in watch mode because JS code is being changed. But maybe that's not where target :bundle should be used.

dnolen 2020-04-25T20:07:08.107Z

sure but you don't need :bundle-cmd

dnolen 2020-04-25T20:07:15.107300Z

just run the watcher separately - it's not a big deal

dnolen 2020-04-25T20:07:31.107700Z

there's just too many cases where :bundle-cmd isn't going to be sufficient - which is fine

2020-04-25T20:08:10.108200Z

good point, a not on that in the docstring could be useful

dnolen 2020-04-25T20:08:26.108500Z

yes will be there when the site updates

dnolen 2020-04-25T20:08:35.108900Z

it explicitly states now you should run commands that exit

2020-04-25T20:09:18.109Z

I still don't understand your first comment aboutĀ :noneHere's network trace. bundle.js is produced by Webpack, the code in this file depends on ClojureScript code which is loaded later.

dnolen 2020-04-25T20:09:49.109500Z

oh you have circular deps

dnolen 2020-04-25T20:09:58.109800Z

not going to fix that for you

2020-04-25T20:10:35.110700Z

circular deps? the only thing that I have here is that both cljs and js sources depend on React from node_modules

dnolen 2020-04-25T20:10:37.110800Z

or do you just have bidirectional stuff?

dnolen 2020-04-25T20:11:02.111100Z

yeah mutual requires

dnolen 2020-04-25T20:11:16.111500Z

yeah no good answer here, and probably not going to spend any time on that one

dnolen 2020-04-25T20:11:36.112100Z

well

dnolen 2020-04-25T20:11:44.112400Z

actually ... maybe

dnolen 2020-04-25T20:12:04.113Z

ClosureBundler is a thing - like prep work to get rid of the debug loader

dnolen 2020-04-25T20:12:20.113600Z

not sure when/if they're going to kill it

dnolen 2020-04-25T20:13:08.114700Z

@roman01la you could try :whitespace which is REPL compatible

dnolen 2020-04-25T20:13:53.115300Z

@roman01la the other option is to have your JS sources go through Closure instead of Webpack

dnolen 2020-04-25T20:14:29.115700Z

but I guess you probably want JSX

dnolen 2020-04-25T20:14:43.116Z

then :whitespace is probably best

2020-04-25T20:15:22.116700Z

not sure about mutual deps, it's just JS code that depends on cljs, but yes, bundling all cljs output into a single file will solve this

2020-04-25T20:16:44.117700Z

but again, can probably write a custom target-fn to handle this somehow

dnolen 2020-04-25T20:16:52.118Z

You have two different build outputs that depend on each other

2020-04-25T20:17:38.118700Z

mm, no, just this

import "./out/index.js"
console.log(window.hello_bundler.core);

dnolen 2020-04-25T20:18:20.119700Z

Right canā€™t work

dnolen 2020-04-25T20:20:26.120400Z

You can wait for that stuff though

dnolen 2020-04-25T20:20:31.120600Z

Thatā€™s what Krell does

dnolen 2020-04-25T20:26:50.121400Z

in dev Krell waits for the entry point, in prod it just invokes the entrypoint

2020-04-25T20:33:39.122Z

Looks like it hooks into closure's debug loader?

dnolen 2020-04-25T20:44:41.122200Z

ha not even

dnolen 2020-04-25T20:44:46.122600Z

though that would be better

dnolen 2020-04-25T20:44:54.122900Z

it just waits for cljs.core to appear then starts

dnolen 2020-04-25T20:45:38.123500Z

in dev it's easy, it either exists or it doesn't

dnolen 2020-04-25T20:46:01.124Z

once it exists then you know that goog and all the other stuff is available

dnolen 2020-04-25T20:47:03.124800Z

@roman01la the problem with waiting for anything is that goog.base has to be there, but even goog.base is written as a script tag

souenzzo 2020-04-25T21:51:24.128100Z

Should I expect some kind of requiring-resolve *function* in cljs in the future? Something using JS import function and GCC code splinting? PS. I know that right now I can use code splitting and dynamic load "directly" from GCC, asking about requiring-resolve in particular

dnolen 2020-04-25T22:02:56.128600Z

@souenzzo unlikely to ever have a requiring-resolve