This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-23
Channels
- # bangalore-clj (5)
- # beginners (136)
- # boot (1)
- # bristol-clojurians (6)
- # cider (46)
- # cljs-dev (172)
- # cljsrn (35)
- # clojure (82)
- # clojure-china (2)
- # clojure-dev (9)
- # clojure-dusseldorf (1)
- # clojure-finland (15)
- # clojure-italy (54)
- # clojure-norway (4)
- # clojure-russia (6)
- # clojure-spec (19)
- # clojure-uk (61)
- # clojurebridge (1)
- # clojurescript (55)
- # community-development (23)
- # cursive (7)
- # datomic (19)
- # emacs (10)
- # events (4)
- # fulcro (108)
- # graphql (7)
- # hoplon (1)
- # leiningen (7)
- # lumo (14)
- # off-topic (68)
- # onyx (23)
- # parinfer (8)
- # portkey (40)
- # precept (11)
- # re-frame (5)
- # reagent (40)
- # ring-swagger (5)
- # shadow-cljs (58)
- # specter (5)
- # tools-deps (37)
- # unrepl (13)
- # vim (9)
- # yada (12)
Wow, an exploratory change for ^ shows a 5x speedup, and the amount of extra code to achieve that is not too scary. (I've attached the exploratory patch, just to show this.)
@mfikes you recently did a pass over the :closure-warnings
which now breaks if the user pins a specific closure-compiler version.
I wonder if we can maybe create a solution that either picks these out via reflection or gracefully skips things it can't find
there is a bug in the latest closure release which means some users wanted to pin to a previous release
ideally this shouldn't pretty much breaks with every closure release and always has to be updated manually
There already is a public DiagnosticGroup/forName
, just need to camelCase the input. There is also CompilerOptions/fromString
.
There is also DiagnosticGroup/getRegisteredGroups
which can be used to error out to the user if he/she selects a group that doesn't exists. "Cannot find DiagnosticGroup XYZ, available: ...`
weird
public Map<String, DiagnosticGroup> getRegisteredGroups() {
return ImmutableMap.copyOf(groupsByName);
}
public static final DiagnosticGroup CHECK_USELESS_CODE =
DiagnosticGroups.registerGroup("uselessCode",
CheckSideEffects.USELESS_CODE_ERROR,
CheckUnreachableCode.UNREACHABLE_CODE);
:check-useless-code
is the current keyword for this but its registered under uselessCode
so you'd be ok if users have "invalid keywords" from previous versions and just warn about those not existing?
if the user currently has :check-useless-code
we can't look that up via forName
because its registered under a different name
There could also be changes in the ClojureScript compiler that depend on the latest Closure release, outside of the set of warnings. Some of that stuff could also be conditional / reflective, I suppose. Apart from users wanting to pin to a specific older version, simply being able to flip back to an older version can help isolate regressions that might crop up. (The scenario where you think it is the latest Closure release breaking something, and you want to try an older one to see if it still works with that.)
I guess now we get into this position where ClosureScript strongly depends on the very latest if not careful.
https://dev.clojure.org/jira/browse/CLJS-2694 and https://dev.clojure.org/jira/secure/attachment/17930/CLJS-2694.patch
@mfikes It would be very hard to support multiple Clusure versions, module stuff changed A LOT during last few releases
For some parts, like warnings etc. it is probably easy, but having working module processing with e.g. both v20180204 and v20170910 would require lots of checks
Maybe for next Closure releases we can implement changes in a way that works also with current, the changes are hopefully smaller in next releases
Right. That's the point, really. Addressing the warnings keywords issue is insufficient. It might be prudent to at least have the ability to to back to the previous version that ClojureScript dependent on, but even then, I wonder if that leads to a convoluted set of checks. We do this with Java, for example (see here https://github.com/clojure/clojurescript/blob/8670cc40cf09f90f1d36cb4bf0a2c68713fb1d68/src/main/clojure/cljs/js_deps.cljc#L19-L37), but Java is much more conservative that Closure. Hrm.
If the changes are small in future, we can think about this, but the previous update was so complex that supporting old version wasn't in my opinion sane. And some of the regressions are due to changes in our side.
Yeah, I wonder what other consumers of Closure do? This must be painful. The same sort-of happens with React, right? (But not as badly.)
Are there many other Closure consumers? Besides obviously Google itself.
If I recall correctly, Scala JS projects use Webpack or something.
My guess is that no-one else is integrating with Closure on same level as we do.
Perhaps the teams in Google, themselves don't have other dependencies that have dependencies on Closure. (Perhaps it is only at the "leafs" in Google.)
Otherwise, I would imagine a lot of strife within Google, and complaints about change.
Google has much easier time as they probably only use "simple API", like single build call or something.
Due to our special node module handling, we use quite many Closure classes directly.
Ahh. This raises the idea, if ClosureScript is so heavily dependent, if we had our own fork to act as a buffer.
That would allow getting fixes in quicker also. But it would be more work for someone to keep the fork up-to-date, especially if we try to keep compatibility.
Yeah, perhaps a less aggressive idea is to split off the bits in ClojureScript that touch Closure directly into another lib, and keep the API to that new lib simple. Then if you want to revert to an older version, you just revert both that lib and Closure.
And the previous Closure update affected analyzer/compiler due to changes to how we need to emit Cljs code which will call module-processed JS.
https://github.com/clojure/clojurescript/commit/72e2ab6e63b3341aa26abcbdd72dc291cbd0c462
No API wrapper will help with change where Closure changed how it converts CJS modules.
All problems in computer science are solvable by another level of indirection, unless you are trying to indirect from yourself.
I ran master through 1.10.x Quick Start on Windows Source mapping not working there https://dev.clojure.org/jira/browse/CLJS-2695 And using optimizations can still be flakey https://dev.clojure.org/jira/browse/CLJS-2401
re: Closure Compiler/Library this problem has been true for some time, I donβt think we should spend lots of effort in it. Best way to prevent breakage is to get our own tests in
Yes I have a fix for module processing for node scoped modules. It needs tests though.
Definitely. Arguably we are only using public API, but perhaps exercising subtle corner cases in Closureβs code paths.
Thinking out loud: Iβm wondering if we can construct our own CI that always builds with the latest from the Closure tree. Then we would also have another way to catch things earlier.
I think we could setup clojurescriptβs own tests to run in canary jobs as well (maybe as part of compiler build), and as a next step maybe configure it to use closure master
I don't know the details of how the unshaded JAR gets created (I just tried the latest Closure release, but changing the version numbers was insufficient.)
Yeah, maybe a script/test-closure-latest
or somesuch could do all the needed actions to test things that way.
(Like pulling, building, setting all the version numbers in the deps files.) With that, it would be trivial to add a Travis call to such a script.
I haven't quite been able to consistently generate this error, but I'm fairly sure it has something to do with my use of macros in a node cljs repl:
cljs.repl/repl* repl.cljc: 930
cljs.repl/evaluate-form repl.cljc: 553
boot.user.Delegatingcljs_repl_node_NodeEnv._evaluate NO_SOURCE_FILE: 122
cljs.repl.node.NodeEnv/-evaluate node.clj: 234
cljs.repl.node/node-eval node.clj: 66
java.lang.NullPointerException: {"type":"result","repl":"nREPL-worker-1","status":"success","value":"true"}{"type":"result","repl":"nREPL-worker-2","status":"success","value":"true"}
I'm not familiar enough with the node repl to understand what it's doing here https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl/node.clj#L66
Does anyone have any idea what the issue might me? I'll continue trying to find consistent reproduction steps.It's fairly intermitent, and Cider doesn't catch it at all. I have to kill the repl and restart is when this happens.
Is it possibly an issue with Cider's eval-buffer command? I've noticed that I sometimes have to manually evaluate the ns
declaration before I can evaluate the buffer.
Oh, perhaps we already have a way to test with the latest Closure
lein with-profile +closure-snapshot test
This is great:
actual: java.lang.NoSuchMethodError: com.google.javascript.jscomp.Es6RewriteModules.<init>(Lcom/google/javascript/jscomp/AbstractCompiler;)V
Hmm, maybe I should send patch which fixes this Es6RewriteModules in a way that works with current & next version?
I have already the fix somewhere and it should be possible to implement this in a way that works for both
@juhoteperi Yeah, perhaps that is a good test of straddling two versions
Perhaps tools.deps
doesn't see upstream aliases. A :closure-snapshot
alias works if you are in the ClosureScript tree, but not if you are elsewhere pointing at that tree: https://gist.github.com/mfikes/84a83abec3860ac86a3096a5b8a62a04#file-deps-edn-L16
you have to resolve aliases to build the dependency tree, which you canβt do before you build aliases to build the dependency tree to build aliases to build the dependency tree, well you get the idea
are the sources coming with 1.10.217
encoded somehow? I see cljs/core/specs/alpha.cljs
does not contain any code?
The ClojureScript analog of https://github.com/clojure/core.specs.alpha/blob/master/src/main/clojure/clojure/core/specs/alpha.clj
Oh yeah I noticed that, I misscopied ... ok i might have something strange going on here
https://dev.clojure.org/jira/browse/CLJS-2698 would give us the ability to script/bootstrap
with the latest snapshot of Closure Compiler (akin to lein with-profile +closure-snapshot test
but then letting us run script/test
to really use the entire thing to do the typical :advanced
stuff script/test
does)
script/bootstrap --closure-compiler-snapshot
and then script/test
is another way to repro the Es6RewriteModules
stuffcljs.main
with -t nodejs -r
Exception in thread "main" java.lang.AssertionError: Assert failed: :nodejs target with :none optimizations requires a :main entry
(not (and (= target :nodejs) (= optimizations :none) (not (contains? opts :main))))
Should this work?
@ghopper you need -re node
in addition to the IIRC
Thanks π
the -t
vs -re
difference can be difficult to grasp but I think the latter is always necessary with -r
...
@mfikes It seems to work with just -re
.
the two are effectively decoupled, one defines the Repl Env, the other is a compiler option
maybe because one might want a Nashorn REPL targeting node?
is it even possible?
There is an implication between the two, I just can't recall the direction of the arrow π
I would guess that -re
implies -t
according to what @ghopper just did
It certainly seems to.
Ahh, so if you -re
node then the that REPL environment code will set the target https://github.com/clojure/clojurescript/blob/master/src/main/clojure/cljs/repl/node.clj#L209
we could add a warning, when you have -r
you might want to be notified when you miss -re
ah actually no, that defaults to browser
In this case you can see that it is actually cljs.repl.browser
, and then during the build stage it complains about the node target. https://gist.github.com/mfikes/e8e514d5c67ffb37a83f0cc0b35ea68d
Effectively the same as if you had explicitly done
clj -m cljs.main -t node -re browser -r
This is because even though -re node
implies -t node
, -re browser
doesn't set a target
we could detect it in cli
instead of let it through
right!
Perhaps these issues have always existed. There just so easy to explore now. π
agree, but probably release should have checks, I still make this mistake even now that I know about it π
I mean "official" release
Then there are strange twists like this path AntΓ³nio sent me down with :target :nodejs
but while actually doing React Native π http://blog.fikesfarm.com/posts/2017-07-17-cleaner-clojurescript-react-native-interop.html
The mind bending aspect there is that there is the React Native packager running in Node.js while you are actually targeting JavaScriptCore as the JS engine.
server side rendering is a thing actually
The websocket thing is pretty powerful. I just made a little chrome extension the uses it. I can inject a repl env into any running browser tab. This connects back to my ws repl server which is hanging off of a socket repl. Then, as each new connection connects to the ws repl, I can connect more and more socket repl clients and switch to the different clients connected to the single compiler env.
So socket repl combined with websocket env... you can manage tons of simultaneous connections
Sooooo each connection shares nothing?
Right they target the browser yeah going back to -t
vs -re
π once again cool
yeah, thus far all my experiments are in the browser. I'm not actually sure how I would go about composing heterogeneous targets in the same compiler env...
So what could cljs-dev use the most help with this weekend? Are we still gunning for a monday release?
the patch for https://dev.clojure.org/jira/browse/CLJS-2685 works for me
I'm not able to repro https://dev.clojure.org/jira/browse/CLJS-2679
hey @john , I just saw you commented on this https://dev.clojure.org/jira/browse/CLJS-2679 . under which environment did you try this? browser, os?
ok, thanks. it's really strange. it may be some platform specific problem or either my system is messed up π
from your description (edn/read-string "{\"repl\":\"main\",\"result\":\"{:status :success, :value \\\"true\\\"}\"}")
cd clojurescript
./script/uberjar
cd src/test/cljs_build/hello-modules
java -cp ../../../../target/cljs.jar:src clojure.main repl.clj
I can't figure out why, but apparently the latest node repl times out after a few minutes when running under piggieback, but it works fine when running in a normal terminal. The error is own thrown after waiting a while and then trying to evaluate something.
I've started trying to trace cljs.repl.node
and cemerick.piggieback
, but I haven't been able to make heads or tails of it yet.
Has something changed in the structure of the node repl recently that would cause this?
nREPL server started on port 35919 on host 127.0.0.1 -
REPL-y 0.3.7, nREPL 0.2.13
Clojure 1.9.0
OpenJDK 64-Bit Server VM 1.8.0_152-16
Exit: Control+D or (exit) or (quit)
Commands: (user/help)
Docs: (doc function-name-here)
(find-doc "part-of-name-here")
Find by Name: (find-name "part-of-name-here")
Source: (source function-name-here)
Javadoc: (javadoc java-object-or-class-here)
Examples from : [clojuredocs or cdoc]
(user/clojuredocs name-here)
(user/clojuredocs "ns-here" "name-here")
To quit, type: :cljs/quit
nilcljs.user (+ 1 1)
{"type":"result","repl":"nREPL-worker-1","status":"success","value":"2"}
java.lang.NullPointerException
at cljs.repl.node$node_eval.invokeStatic(node.clj:66)
at cljs.repl.node$node_eval.invoke(node.clj:60)
at cljs.repl.node.NodeEnv._evaluate(node.clj:234)
at boot.user.Delegatingcljs_repl_node_NodeEnv._evaluate(Unknown Source)
at cljs.repl$evaluate_form.invokeStatic(repl.cljc:553)
at cljs.repl$evaluate_form.invoke(repl.cljc:484)
at cljs.repl$evaluate_form.invokeStatic(repl.cljc:491)
at cljs.repl$evaluate_form.invoke(repl.cljc:484)
at cemerick.piggieback$eval_cljs.invokeStatic(piggieback.clj:271)
at cemerick.piggieback$eval_cljs.invoke(piggieback.clj:270)
at cemerick.piggieback$do_eval.invokeStatic(piggieback.clj:297)
at cemerick.piggieback$do_eval.invoke(piggieback.clj:278)
at cemerick.piggieback$evaluate.invokeStatic(piggieback.clj:320)
at cemerick.piggieback$evaluate.invoke(piggieback.clj:318)
at clojure.lang.Var.invoke(Var.java:381)
at cemerick.piggieback$wrap_cljs_repl$fn__6035$fn__6037$fn__6038.invoke(piggieback.clj:351)
at cemerick.piggieback$enqueue$fn__6007.invoke(piggieback.clj:253)
at clojure.tools.nrepl.middleware.interruptible_eval$run_next$fn__5917.invoke(interruptible_eval.clj:190)
at clojure.lang.AFn.run(AFn.java:22)
at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1149)
at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:624)
at java.lang.Thread.run(Thread.java:748)