Hey, I understand what you want to achieve and I definitely want to make the whole thing easier but some issues don't have an easy solution.
TL;DR: It's complicated. First we need to split compilation and bundling. CLJS->JS compilation just takes one .cljs file and compiles it to .js. To do that it needs analyzer data of all CLJS dependencies. If you were to publish compiled CLJS to npm you'd need to also ship the analyzer data somehow. The other problem is that certain compiler options affect the generated JS which means that for every .cljs file there are many possible .js results. Another thing is that you also need to account for the compiler version since that may also affect the output or the analyzer data which then may affect other files. The second part is bundling things together, which means reducing the number of individual files down to a more reasonable number. shadow-cljs enables JS tools to do that for us (eg. webpack, create-react-app or any other), since those tools use "require" to discover dependencies. The best option for this however is to use the Closure Compiler but to get the whole benefit of it you need to optimize your whole program, which includes EVERY .js file. There is promising progress in Closure to support optimizing common js and ES6 code but it is not quite there yet and can't compile everything. It will be coming to shadow-cljs soon though, it is already in CLJS but I didn't hook it up yet since I wanted to solve some issues first. :npm-module tries to bridge the gap a little but as soon as you don't optimize your whole program you need externs to teach Closure about the things it can't see. Which means you can still use :advanced compilation for the CLJS/Closure parts but the rest of the code remains untouched. It also means that you need a second bundler (eg. webpack) to then combine the Closure output with the remaining unoptimized parts. Given all these constraints I don't think it is feasible to publish compiled (but unbundled) CLJS code as a library to NPM. It would be relatively easy to consume uncompiled .cljs code from NPM packages but unless everybody agrees to do that it would just make things a whole lot more complicated for everyone. Maven is also a whole lot better than NPM IMHO, npm or yarn just have better UX (until something breaks). :npm-deps is a feature in CLJS that lets you declare which npm packages your CLJS code requires to work. Technically this would need a complement in package.json to allow declaring which CLJS packages the JS code needs. I don't have a solution for that and I was and still am opposed to whole idea of :npm-deps. It does however solve the issue from the CLJS perspective, just not from the "Play as a Team" JS perspective. I do want integration to be painless and I do think shadow-cljs already makes life easier for some. I am very interested to hear about any other pain points people may have with CLJS<->JS interop. I tested webpack, create-react-app and create-react-native-app. They are all work reasonably well but I haven't gone beyond basic examples. I really don't have a good solution for the problem since part of the solution must come from the JS world and I have basically no idea what people are doing over there. The whole problem basically boils down to which bundler you want to use. I'm personally only considering the Closure Compiler for that and shadow-cljs is trying to make that as easy as possible with support for common JS / ES6 coming soon. If you want to use webpack or so that also works reasonably well already but CLJS really is built with the Closure Compiler in mind so the end result of this won't be optimal. If you want both that is always going to require more manual work for :externs and come with certain caveats. I hope that made some sort of sense, I have been thinking about this a lot but haven't gotten very far. /thomas On Sunday, July 9, 2017 at 3:29:15 AM UTC+2, Kurt Harriger wrote: > > Thomas, > > First thank you for starting this project! > > I recently joined a team at Atlassian that uses ClojureScript to support > collaborative editing. I don't think I need to sell the community here on > the advantages of ClojureScript, but I think packaging still needs work. > > If you use ClojureScript for your entire UI you probably don't have any > issues, but in larger organizations we need to "Play as a Team." It does > not seem feasible or reasonable to expect that other teams switch to using > the ClosureScript compiler and make their js libraries play nice with > closure because the end result will be marginally better, especially given > the work involved in ensuring they still work with advanced optimizations > may be non-trivial. > > The only practical alternative I'm currently aware of is to precompile the > ClojureScript with optimizations and have them include this as a script tag > in their page. The disadvantages of this are many: > > * separate download - not bundled with other js libraries > * not commonjs / cannot require / pollutes global namespace > * install/upgrade/versioning process is different / change script tag > rather than npm/yarn > * each precompiled ClosureScript library will include closure and cljs > again > > As we add support for multiple editors I want to split the library into > multiple artifacts that can be released separately, however that last > bullet point is undesirable. I have had some success in adding a cljsbuild > along side a webpack build, but CommonJS has solved a lot of pain points > for JS devs and most modern js devs now expect an npm artifact. > > Although shadow-cljs doesn't solve having different install/version > process it does appear to solve the other issues and is better than using a > script tag. > > I did have a general question though. I understand that if you compile > multiple ClosureScript libraries independently each will end up with > duplicate bits of closure and cljs core. Shadow-cljs, as I understand it, > appears to solve this by first compiling all the ClosureScript code > together and exposing it as a commonjs module. But thinking out-loud > here...isn't sharing dependencies the problem npm is trying to solve? could > we leverage that instead of reinvent it? > > What if google closure libraries and cljs.core were published as their own > commonjs npm libraries - precompiled but not minified yet? Couldn't cljs > libraries then just 'require' them without resulting in another copy or > requiring the closurescirpt compiler (and jvm)? In my ideal world, I think > I would be able to specify :npm-module as the clojurescript compiler target > and it would generate js that can be packaged in npm that 'requires' rather > than bundles cljs and closure. Minification can be done downstream with > *all* the javascript, not just the cljs code. I also found a closure plugin > for webpack https://www.npmjs.com/package/webpack-closure-compiler (I > never used it though), so maybe we can still get just as good if not better > results doing it later? > > I'm not sure what would be involved in rewriting cljs output to require > "require" closure and cljs.core as their own libraries, but maybe the > partially solved already with > https://github.com/clojure/clojurescript/wiki/JavaScript-Module-Support-(Alpha) > ? > > Thanks! > -- Note that posts from new members are moderated - please be patient with your first post. --- You received this message because you are subscribed to the Google Groups "ClojureScript" group. To unsubscribe from this group and stop receiving emails from it, send an email to clojurescript+unsubscr...@googlegroups.com. To post to this group, send email to clojurescript@googlegroups.com. Visit this group at https://groups.google.com/group/clojurescript.