Configurable reader features
Description
Environment
Activity

Matthew Huebert November 13, 2018 at 12:15 PM
I've run into the same issue trying to share code between server and browser builds. A couple examples –
1. the Firebase API is fairly consistent across browsers and node.js, but you need the `"firebase-admin"` package on the server, and just `"firebase"` for the browser.
2. I have a namespace where I define a series of API endpoints. A subset of the API metadata should be visible to the browser build, while the node.js build should also include references node.js-specific resolver code, via vars to namespaces which do not exist at all in the browser.
I'm currently using a combination of workarounds, like (1) modifying how JS modules are resolved at compile time, eg. redirecting "firebase" to "firebase-admin" for node.js builds using shadow-cljs :js-options, (2) creating extra namespaces that are included/excluded from different builds which "inject" platform-specific functionality into the reusable namespaces by resetting vars / atoms, (3) using macros to read the current :target from the cljs compiler env and conditionally eliding/including code based on that, (4) using `goog-define`'s which are set per-build to conditionally evaluate code based on platform.
I like this proposal because reader conditionals would be a direct, inline expression of my intent, whereas these workarounds tend to add indirection, extraneous code, and more complicated build configurations.

Andrea Richiardi July 6, 2018 at 5:27 PM
I have another use case in my app:
Two different namespaces use the AWS and the Azure JavaScript SDKs for performing tasks. At the moment I have to require both and use a goog-define
for picking the desired one, hoping unused parts gets trimmed away - using :simple
in node I am not even sure it is possible to trim..
The proposal seems cleaner.

Thomas Heller November 17, 2017 at 8:10 PM
I was under the impression that JIRA is the place to have these discussions so they don't get lost in Slack Archives.
The Clojure Reader and tools.reader already support everything we need so no changes to either are necessary.
Only the :features
option would become configurable, nothing more. Clojure itself does not need this feature since it only runs on the JVM, has its :clj option and already ignores every other option. I do think it is useful to have this for CLJS given the wide variety of host platforms.
https://github.com/clojure/clojurescript/blob/245bdee2c35e19a9685b7a0849f26fce8bdaf7ca/src/main/clojure/cljs/analyzer.cljc#L3652 and very few other places would need to change.
David Nolen November 17, 2017 at 7:38 PM
This is serious language level feature request. Such ideas need to be discussed around Clojure first.
Details
Assignee
UnassignedUnassignedReporter
Thomas HellerThomas HellerPriority
Major
Details
Details
Assignee
Reporter

Priority

The reader features for
.cljc
files is currently hard coded to#{:cljs
} and Clojure will use:clj
. With the intent being that host-specific features can be chosen at read-time. Given that there are a variety of different JS host platforms it would be useful to allow setting build-specific reader features so that builds targeting node can use different code than using the browser.We can not always rely on the Closure Compiler eliminating all the code for us and we currently have no other way to get conditional requires.
Kevin Lynagh described his use-case here: https://gist.github.com/lynaghk/0608a43f173558b6fcf30c3be53d77dd
I had a very similar use case in mind for conditional requires related to excluding some code from a node.js targeted build for doing SSR that otherwise should use the same code as the browser uses.
My suggestion would be to add
:reader-features #{:kw1 kw1
} to the compiler options which will be added to the default:cljs
at read-time.