Open alex-dixon opened 6 years ago
@alex-dixon shadow-cljs
itself can be used via lein
or clojure
or pretty much anything else that is able to run clojure and build a classpath. I wrote about this some time ago.
What the shadow-cljs
"binary" provides is a convenient way to install it via npm
and an optimized experience to run it from the CLI (this started before tools.deps
was even announced). I still recommend running it standalone because your CLJS really doesn't gain anything by being embedded into your Clojure REPL. Neither the other way around. You just now have to deal with conflicts between your CLJS and CLJ libs. That being said it works perfectly fine embedded.
Tool support for Standalone currently is not great because most tools pretty much only support project.clj
. This should get better once deps.edn
gets adopted more or tools support shadow-cljs.edn
directly.
At this point shadow-cljs provides many different ways for integrating JS and could in theory also build entirely JS-only projects which I have done here. You of course would never do this but taking a project from create-react-app
and start adding .cljs
files is pretty darn simple. It is also possible to just use webpack
to do the final "bundle".
The whole issue is that ClojureScript is built with the Closure Compiler in mind. This means that is assumes that you will run whole-program optimizations. This makes it a terrible fit if you want to write libaries in it and compile those to JS. If you however are able to feed it the entire code the results are enormously better than any other JS tool out there. The entire JS ecosystem is not built with whole-program optimizations in mind and this is sort of a mismatch between Closure and npm
. JS tools like prepack
or rollup
are years behind Closure but a step in the right direction. ES6 also makes things much easier to integrate since its less dynamic than CommonJS.
:npm-deps
will not work properly with the current state of npm
unless you are very careful to only pick dependencies that provide pure ES6, which is only a tiny fraction of packages at the moment.
If you have a concrete question/example of what you are trying to do I'm fairly certain that shadow-cljs
already has a working solution. If not I'll happily add it.
I've been investigating using JS from CLJS, in particular using React components that have already been written in JS that are not part of a library or npm module.
Observations:
I write this against the background of the State of Clojure 2018 survey, which shows most devs are coming from Javascript. Even if JS devs are sold on the language, they may still walk away without a path to using it. Using JS from CLJS mitigates risk for developers and stakeholders alike. We should show how that migration 1. never really has to take place, 2. how to migrate JS code to CLJS code if or when that's desired.