Fork me on GitHub

xposting so more devy folks see it. I'm trying to build a module framework similar to MDC: But I'm getting undefined errors for ModuleLoader when using cljs.main in the attached repro.


This is an interesting resource, btw, if y'all haven't seen it yet:


talks about some of the conventions they use to make sure that closure keeps working like it is supposed to, wrt code splits


And is passing a co.edn to -co the best way to pass in the module info to the compiler? EdnReader doesn't like the '#{blah.core} forms found in the documentation's :entries vals, complaining that "maps require an even number of keys." The examples use a build.cljs file to pass the module info to the compiler, but I'd think this'd be doable from the edn file. Not sure if that has anything to do with the EvaluateCodeEvent and RequestSuccessEvent errors I'm getting.


Also, it seems non-deterministic... do a fresh compile, it'll get to module one. Do a second, it'll get to module two. Hasn't got to module three though.


Also, there seems to have been some churn in the code-splitting-modules space in the last half year, and some of the docs don't seem to match. Some are declaring (loader/set-loaded! :this-module) at the bottom of the file, others aren't. Some have the :entries vals formatted differently. If I can get a MDC-like module framework working on a sizable project, I'd like to update the docs with the latest and greatest.


I think the current ModuleLoader is getting disposed of accidentally, or overwritten for some reason


So, according to this, the bulkLoader is always disposed of after handleSuccess_ and handleError_


perhaps successive calls to the same loader won't work if the calls aren't issued within the same 5 ms goog.Timer window?


@john loading is async. I don't think you are allowed to kick off multiple loads at the same time


hmm, bulkLoader is only a temporary loader created in downloadModules_


and especially starting loads before set-loaded! is called is not a good idea


since that will start the download of the already partially loaded module again


Indeed, calling set-loaded! is causing double loads sometimes


in general calling load at the top level is not a good idea. no point in splitting in the first place if you immediately load things


I guess its for the examples sake but still


Yeah, it was just for the example


also why are you messing with cljs.loader when building a component lib? libraries should basically never use cljs.loader.


To provide smaller, piece-meal consumable libs, similar to MDC


that is not what modules do


closure already takes care of that for us


just use separate namespaces if you must but its totally fine to put everything into one fat namespace


closure will remove the things we don't use when everything is done "correctly"


this MDC piece-meal is done for the JS world ... absolutely not required for CLJS/Closure


right, I also want to make the libs consumable via npm, if possible


aren't there already plenty of those? CLJS is really not a good fit for writing those kind of libs when consumed from JS


I'm writing a special kind of analytics platform that mostly doesn't exist


everything in CLJS is built around the Closure whole-program optimization. writing libraries means it can't optimize the whole program.


so writing this piece-meal type style of lib is really not going to work well


this is what I have done in shadow-cljs to make this sort of work. its not a great fit but it does work.


WRT that, I was also wondering if downstream users could reuse the moduleIds I declare in my set-loaded! statements, so that they can construct their own module deps (for building their own modules downstream) using my moduleIds


I haven't gotten that far yet, with testing, but I don't see why not


I don't see a way how cljs.loader could ever work in a library kind of way for npm


What's the issue?


assuming that your code is going to get processed by webpack or something. those are never going to understand which files they need to move and stuff


hmm, yeah I'm not sure about the webpack stuff. With respect to doing the loading downstream, I was thinking of just exposing functions for each module that did the autoloading of the module lazily, when one of its exposed functions is called.


Of course, if you don't happen to need to load components lazily, you could consume the entire thing as one large library and let DCE get rid of whatever you don't use. But I'd like to provide both options.


but webpack already provides that option for example? are you assuming that your JS folks won't use a build tool at all?


cljs.loader only makes sense if you assume that your JS users will only use YOUR generated JS directly without any other code


I'm supposing that if a user is capable of exploiting modules and codemotion, either via cljs or closure directly (in js land), then they'll be able to leverage my lib in such a way.


But if not, then they'll just be able to use it normally


But, it sounds like you're saying that, unless they're using goog closure specifically, all of this is a wash anyway? I wonder if this module stuff is providing any benefit to users of MDC, outside of google?


I'm saying that cljs.loader is meant for the final app, because only at that point is code-splitting useful. It is never useful for a library.


I think you are mixing your understanding of ES6 Modules with Closure Modules


they are completely different things and not related at all


Can't downstream users reuse my moduleIds?


why not?


because it does not make sense


Not yet 😉


just kidding, it's still pie in the sky idea... But I don't see why this shouldn't work.


suppose you package one component per module. but a user of your lib wants to use 3 components on the same page. why force them to download 3 different modules via cljs.loader?


maybe I just don't understand your vision. I remember a while ago I didn't understand a different vision of yours. 😉


Yeah, I'm going to bang on it more tonight. The leads you gave me will probably resolve my issues. Then I'll put together an example of what I'm talking about


start two when one finishes, three when two finishes


Perfect explanation. Thanks!


don't know if cljs.loader exposes a loadMany but the ModuleLoader from goog has methods for loading multiple mods an continue when all are loaded


Awesome. I'll ping you back with my progress. It may end up being a useful experiment.