This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
- # beginners (118)
- # boot (3)
- # cider (11)
- # clara (1)
- # cljs-dev (139)
- # cljsrn (5)
- # clojure (52)
- # clojure-italy (5)
- # clojure-uk (41)
- # clojured (11)
- # clojurescript (66)
- # community-development (1)
- # component (2)
- # core-async (7)
- # cursive (3)
- # datomic (4)
- # defnpodcast (2)
- # fulcro (23)
- # graphql (1)
- # jobs (2)
- # leiningen (4)
- # off-topic (32)
- # portkey (14)
- # protorepl (5)
- # re-frame (13)
- # reagent (5)
- # reitit (23)
- # ring (12)
- # shadow-cljs (29)
- # slack-help (1)
- # spacemacs (1)
- # tools-deps (21)
- # unrepl (18)
Is this where the cljs.core's aot existence is detected? https://github.com/clojure/clojurescript/blob/c9cf1a76b05b762fe0150b30e4230d56136035ff/src/main/clojure/cljs/closure.clj#L3056
I’m beginning to wonder if https://dev.clojure.org/jira/browse/CLJS-2646 is a valid ticket.
I’ve closed https://dev.clojure.org/jira/browse/CLJS-2646 with a note as to why I concluded I was wrong when I wrote it. I’m still curious about https://dev.clojure.org/jira/browse/CLJS-2671 which is likely unrelated.
Wow, since this ^ change eliminates double compilation of JAR code for a completely fresh build (including no
~/.cljs), it drops my initial build from 35.6 s to 28.7 s for a React Native project that uses Om and other JAR deps.
Tested 1.10.191 with a project that uses code splitting and cljs.loader without success. Running into CLJS-2650 again. https://dev.clojure.org/jira/browse/CLJS-2650
Compilation fails here: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/closure.clj#L611
It looks like the loaded.cljs doesn't get moved from the JAR to disk because
requires-compilation? returns false here: https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/closure.clj#L593
Where you’re pointing doesn’t make sense or do you mean requires-compilation is wrong generally?
I can repro, and get passed that by hacking the call to look like
(comp/requires-compilation? jar-file out-file (update opts :cache-key (fn [x] (or x :bogus))))
what I'm trying at the moment is to copy the cljs.loader from jar to disk just before the last
compile-from-jar returns whatever
compile-file returns, but skips the cache. but not sure if that is even right?
(If you look at
compile-from-jar in 1.9.946 and now, you can see that the conditions have changed a little, but the
:cache-key :bogus hack makes it behave more like 1.9.946
@dnolen Isn't compile-from-jar responsible for moving files from jar to disk? this also seems only to happen when you actually use clojurescript from a JAR.
My hunch ws that, without the
jar-file-to-disk never gets called, and it jumps the gun, calling
requires-compilation? has hard-coded logic to return
false for this namespace unless you use the hack
Yep, I'm just comparing the old and new behavior. Perhaps it was compiling it prematurely in 1.9.946? Dunno.
requires-compileation? retuns false in
compile-from-jar. then the code to copy it from jar to disk doesn't get evaluated. but the last line ,`compile-file`, in
Here is the 1.9.946 logic, for reference: https://github.com/clojure/clojurescript/blob/r1.9.946/src/main/clojure/cljs/closure.clj#L579-L597
The special case for cljs.loader in
requires-compilation? is to prevent cljs.loader from beeing cached, right?
:cache-key :bogus hack is not the right solution, but if useful, here is what happens with it in place: https://gist.github.com/mfikes/969939e06e830bcd2504fb58aa285101
@mfikes ah the guide is wrong. I run in to this previously as well, but thought I made a typo
(Even though I said, I got it running with the hack. I don't want to complain it is really successful. It brings up the browser, and it has a "Load Bar!" button, but I am unfamiliar with what is really supposed to happen at runtime at that point.)
any ideas for testing this? the current tests won't catch this, because loader.cljs is on the classpath/src path I think?
FWIW, this fixes the site https://github.com/clojure/clojurescript-site/pull/197
@mfikes ok, I thought about just checking the output files. and that it "jsut" compiles. :slightly_smiling_face:
Yeah, there is a way to check output files in the
script/test-cli setup and make it fail if some arbitrary post-condition doesn't hold. A trick will be that it will block waiting for the browser to connect...
Here is an example of a disk-based post-condition https://github.com/clojure/clojurescript/blob/master/src/test/cljs_cli/cljs_cli/test.clj#L49
@r0man One idea to consider: The
cljs-cli.test namespace is really testing
cljs.main's core functionality.
But it seems that the ability to run some end-to-end tests using
script/test-cli might be useful going forward.
Thinking that perhaps for this one, there could be a
code-splitting.test namespace or somesuch that has a test or tests for this feature, and
cljs-cli.test-runner could be revised to require and run that namespace's tests as well.
(I'm just thinking that we might find the tests being run here will grow over time, as it is an easy way to exercise the system in an end-to-end way, and if that happens, perhaps separation of test namespaces might be useful.)
Also, @r0man if you look at the way the tests are run, the REPL environment is specified as an optional command line argument when the tests are run. Not sure if that framework needs to be revised to accommodate skipping certain tests if they don't apply to a given target or REPL environment. (So far, all tests are applicable to all environments.)
@dnolen @mfikes I just removed the cljs.loader check in requires-compilation? and it seems to work with my project as well.
now, I tried to test this with :aot-cache. I'm using :aot-cache true in my compiler options but
~/.cljs stays empty. did the direcory change?
:closure-warnings refresh now in the comprehensive 1.10.x doc list: https://gist.github.com/mfikes/bdbe214f03abac88ae384adb1ac26490
@dnolen @mfikes I added a patch to https://dev.clojure.org/jira/browse/CLJS-2650 It uses cljs.main to compile the code splitting guide in :none and :advanced. At the moment this test is in cljs-cli.test. Should I move it somewhere else?
@r0man I think it is fine... if we find that this namespace is getting crowded, we can spit it apart later.
@r0man Your patch tests the ability to pass two
--compile main opts simultaneously? I wasn't aware you can do that.
If I had to guess, the last one wins. (This is what happens if you pass two or more
@mfikes That's the first time I'm using cljs.main. I tried it with only foo.core or only bar.core but I think only one of them ended up in the module info of cljs.loader.
No, I think you are probably right. I tried a couple of things to get this working and ended here. I'll remove the second one.
@dnolen So while trying to get a minimal test using only cljs.jar I realized that even the included test (https://github.com/clojure/clojurescript/blob/78b2395960767ea44b68ddd632d1dfe9a4957853/src/test/cljs_build/code-split/repl.clj) doesn't run with the latest versions. (Anything after r1.9.946 from what I can tell.)
Caused by: java.io.FileNotFoundException: The file out/cljs/loader.cljs does not exist. at cljs.compiler$compile_file$fn__4145.invoke(compiler.cljc:1558) at cljs.compiler$compile_file.invokeStatic(compiler.cljc:1523) at cljs.closure$compile_file.invokeStatic(closure.clj:556) at cljs.closure$compile_from_jar.invokeStatic(closure.clj:626) at cljs.closure$fn__5648.invokeStatic(closure.clj:647) at cljs.closure$fn__5648.invoke(closure.clj:632) at cljs.closure$fn__5571$G__5564__5578.invoke(closure.clj:511) at cljs.closure$compile_sources$iter__5758__5762$fn__5763.invoke(closure.clj:983) at clojure.lang.LazySeq.sval(LazySeq.java:40) at clojure.lang.LazySeq.seq(LazySeq.java:49) at clojure.lang.Cons.next(Cons.java:39) at clojure.lang.RT.next(RT.java:706) at clojure.core$next__5186.invokeStatic(core.clj:64) at clojure.core$dorun.invokeStatic(core.clj:3134) at clojure.core$doall.invokeStatic(core.clj:3140) at cljs.closure$compile_sources.invokeStatic(closure.clj:980) at cljs.closure$build.invokeStatic(closure.clj:2776) at cljs.build.api$build.invokeStatic(api.clj:204) at cljs.build.api$build.invoke(api.clj:189) at cljs.build.api$build.invokeStatic(api.clj:192) at cljs.build.api$build.invoke(api.clj:189) at user$eval38.invokeStatic(repl.clj:25) at user$eval38.invoke(repl.clj:25) at clojure.lang.Compiler.eval(Compiler.java:7062) at clojure.lang.Compiler.load(Compiler.java:7514) ... 9 more
@mfikes Sorry, I didn't see that. Though I did just now compile an uberjar from master. I'll try again—making sure I definitely have the latest.
@mfikes Works like a charm. I guess I didn't actually have the latest master. Thanks! :slightly_smiling_face:
Has anyone had issues with
goog.module.ModuleLoader being undefined in
goog.module.ModuleLoader.prototype.evaluateCode_? It's unable to dispatch an
EvaluateCodeEvent event, because
ModuleLoader is undefined.
I think it's because it's loading
:cljs-base which is redefining
Is it normal for
cljs.loader/load to also load
While loading, there's an error on
Error: Namespace "goog.string" already declared. at Object.goog.provide (eval at goog.globalEval (
So why is the loader trying to load
:cljs-base if that is already loaded by the script tag?
You could mix aribtrary clojure and clojurescript code together, I guess, in the same context?
But does this make all nashorn threads reentrant? So js's run to completion semantics go away?
Not that I was going to be able to build a slab allocator / garbage collector over SAB :slightly_smiling_face:
you use a service worker. intercept synchronous xhr calls and hang the client webworker until some result is finished, then pass the result back in the response
Then you can build futures where you can do things like
(await (anything-asynchronous blah
The wait is not reentrant though... run to completion for the worker context still holds
interestingly, in a cluster of web workers, I think Clojure's three main concurrency primitives can be mostly implemented in cljs
and with run to completion semantics, you can be sure that cljs threads can't be interrupted, so you get some concurrency protections that Clojure provides for free. Makes implementation a bit easier I believe
Also interesting, one could make the wesocket and webworker postMessage interface line up fairly squarely and have local and remote workers look the same to each other, allowing for networks of distributed cljs worker clusters pushing data across a WebRTC mesh