In Clojure due to JVM munging, static inner classes in package use the `$` delimiter. ClojureScript itself adopted this convention for `foo$macros`. We could adopt a similar convention here.
This also gives us an idiomatic way to deal with `default` exports:
We don’t need to be too concerned about clashes - we can first check that the original thing exists. If not remove the suffix and check for the prefix.
There are common cases where nested access is necessary. For example React Native native modules. After the first $ we can return to . (suggested by Thomas Heller).
FWIW I implemented this in shadow-cljs. Unfortunately I can’t easily turn this into a patch given how different shadow-cljs handles ns forms. What I’m doing is pretty straightforward though, so it may apply to CLJS in some way.
A [react-native$NativeModules.SomeBridge :as woz] require will be turned into 2 virtual sources. One will become (and shared with any other react-native requires)
and the other will use that one
The sources will be treated as regular closure-js/goog sources and :advanced will make everything nice and short.
I made no changes to cljs.analyzer/resolve-var of any kind since the ns form setup all the necessary stuff so the consumer will have ns alias from woz to some.helper.module$react_native$NativeModules$SomeBridge and happily use the virtual sources this created. Nothing is done at the indivual ns level, everything is handled in the “resolve” stage which I believe has no distinct stage in CLJS but the parse-ns might be close enough.
is not handled yet. Waiting for the decision which prefix to use for that.
The non-global part is addressed in master as of . For the global bit I think we should just avoid picking new names for now.