This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2016-04-11
Channels
- # admin-announcements (2)
- # beginners (53)
- # boot (151)
- # cider (11)
- # cljs-dev (60)
- # cljsrn (36)
- # clojure (71)
- # clojure-austin (13)
- # clojure-berlin (2)
- # clojure-czech (11)
- # clojure-dev (35)
- # clojure-dusseldorf (2)
- # clojure-france (6)
- # clojure-japan (9)
- # clojure-russia (183)
- # clojure-uk (18)
- # clojurescript (155)
- # cursive (6)
- # datomic (25)
- # euroclojure (6)
- # funcool (6)
- # hoplon (229)
- # instaparse (10)
- # jobs (9)
- # leiningen (5)
- # off-topic (70)
- # om (29)
- # onyx (18)
- # planck (1)
- # proton (5)
- # re-frame (8)
- # reagent (32)
- # untangled (4)
@danielcompton: I didn't know about its existence. I'm looking into it and it looks promising. Thanks!
Quick question: I want to include translations in my code, based on the goog.LOCALE compiler setting. However, when I use an if-expression in my code to select the right translation file, both language files get compiled in the output (despite :optimizations :advanced).
So is there a compile-time flag I can use in my ClojureScript code to exclude code branches?
@vincentdm: I think you need to use ^boolean
on your if expression to hint to allow the compiler to get enough information to only compile one branch
http://blog.fikesfarm.com/posts/2015-12-04-boolean-type-hints-in-clojurescript.html
e.g. (when ^boolean js/goog.DEBUG (do a thing))
You can see how ^boolean
works live here (with KLIPSE): http://blog.klipse.tech/clojure/2016/04/02/truth-in-cljs.html
I am building a node.js/cljs thing on the command line. I am having trouble running node /path/to/my.cljs
when my CWD is not the dir where my.cljs is stored. I'm getting the error, Error: Cannot find module /some/dir/im/working/in/out/goog/bootstrap/nodejs.js
I suspect the problem is this line in the generated my.js
require(path.join(path.resolve("."),"out","goog","bootstrap","nodejs.js"));
I think the dot in that line probably tells the node binary to resolve the “out” dir relative to the CWD, but I have no idea how I might change that behaviour
any ideas?
@clumsyjedi: I’m not too familiar with node on cljs, but is https://github.com/clojure/clojurescript/wiki/Compiler-Options#asset-path helpful?
looks promising, thanks danielcompton
Thanks @danielcompton. It's not ideal for a locale setting but it provides a workaround where I could set a boolean for each language in each build profile.
a case
statement might work too? Not sure which ones closure can optimise away?
probably worth looking to see how Google do it, I imagine they probably do per language builds too
not AFAIK, but there’s probably some example code around
Hey, I got a problem with a checkbox in reagent-forms. For old version it works fine [reagent-forms "0.5.21"] but for new version [reagent-forms "0.5.22"] it doesn't work well. The problem is the checkbox is not turned into unchecked when I click on the checkbox. But my atom is changed. This is my code (defn home-page [] (let [doc (atom {:name true})] (fn [] [:div [:p (str @doc)] [bind-fields [:input {:field :checkbox :id :name}] doc] [:button.btn.btn-default {:on-click #(reset! doc nil)} "clear"]])))
@danielcompton: type hinting with ^string didn't work, so I opted for this workaround:
(def messages (cond ^boolean (= js/goog.LOCALE "fr") http://i18n.fr/messages ^boolean (= js/goog.LOCALE "nl") http://i18n.nl/messages))
yeah, but it is only in 1 point in my code, so I'm willing to live with it. I tried using a macro to do the conditional before compilation to JS, but didn't manage to get the goog.LOCALE working there. But thanks for your help anyway
np nasty hacks are sometimes ok
@vincentdm: The ^boolean
hints in the cond
form above shouldn't be necessary—this is because =
has a hinted return value.
@vincentdm: using case
may be a more succinct way to write that - case
compiles down to switch
@mfikes @dnolen Unfortunately my approach didn't work after all. I was checking a stale build and it turned out that the closure compiler always includes the code in both branches. I have tried a lot of approaches to exclude it (including a macro which I tried to run before closure compilation) but nothing worked, so I accepted defeat and am now taking an approach of loading translations in a separate http request during runtime.
To be clear: executing the right branch works, but the other code is also present in my :advanced build, which needlessly increases the size
@vincentdm: from a high level, it looks like you want to statically optimize for a given fixed locale … but the locale is dynamic, right?
users switching language is such a rare event that I am willing to let them re-download the entire app bundle when they do it
Ahh. Understand… hmm. So, I wonder if there is an analog if the goog DEBUG stuff for this situation.
So what I expected was that branching according to the goog.LOCALE from profile's :closure-defines would also eliminate the code in the other brancges
One heavy-handed approach is to introduce an additional source path that varies per locale.
By te way, I also discovered the same problem with boolean branching according to the goog.DEBUG :closure-define: even when debug is set to false, the code inside the dev branches is included in the compiled file. It is not executed, but it is present.
I suspect i18n is one of those mundane things which, once solved, people don’t feel compelled to write about it—leading to a dearth of info on it. 😞
@vincentdm: which is why I suggested case
I'm having trouble using Figwheel on a non-root URL, because it's injecting <script> tags with relative urls. Is there any way around this?
e.g. on
it's creating a <script src="js/compiled/out/goog/base.js"></script>
, which resolves to /foo/js/compiled/...
instead of /js/compiled/...
Does anyone have Secretary + the goog.history API experience? Things route correctly if I go to, say, localhost:3449/#/page/subpage, but links on that page won't change the URL bar. They follow and load correctly, but they don't seem to be editing the URL/location bar at all. Insights or things to look for much appreciated! I'm following @yogthos 's guide http://yogthos.net/posts/2014-08-14-Routing-With-Secretary.html pretty closely but no dice.
you would have to manually do it, or add a function that is triggered everytime by the route that does that
@slester: Pushy is a cljs lib for html5 pushstate: I’ve used it successfully with secretary: https://github.com/kibu-australia/pushy
Ah, OK. That seems strange to me, but it explains a lot! Thanks @roberto + @jonathandale -- I'll check that out
I’m having a really weird problem with the compiler’s foreign-libs
, can someone point out what I’m doing wrong here?
(using boot, but it shouldnt matter because it does nothing with the foreign-libs
option)
1) in build.boot declare :compiler-options {:foreign-libs [entry]
where an entry looks like
{:file “main/index.js” :provides [“theThing”] :module-type :commonjs }
2) place /main/index.js
underneather src/js/
3) index.js
looks like a simple module.exports = function theThing(args) { console.log(arg) }
4) from another cljs module (ns main.core (:require [theThing])
I’ve tried not using :module-type
and getting rid of module.exports
(doesnt work). I’ve also tried moving the js source around to different places (resources vs src) and updating the env :source-paths
and :resource-paths
, but just nothing works.
The error is always No such namespace: theThing, could not locate theThing.cljs, theThing.cljc, or Closure namespace "theThing" in file
I checked with the boot guys over in #C053K90BR, but it’s not specific to their tool
@dnolen: thanks for the tip, but the switch statement doesn't solve it. It results in a JS switch statement with obvious dead trees, but still they are included.
(def message (case js/goog.LOCALE "nl" http://tools.nl/message "fr" http://tools.fr/message "nl"))
function(){switch("nl"){case "nl":return"Dutch";case "fr":return"French";default:return"Dutch"}}();
I would have expected the Closure compiler to catch this and remove the dead branches
I realize that this is an issue of the Closure compiler and not of CLJS, but I guess I'll have to accept it? 😕
@dnolen: I see, I still can use externs, it’s ok if it is my responsibility to care about that..
sure if you export or use externs, then yes you can resolve things at runtime but you don’t really need ClojureScript to help you in that case
so OK for apps - I wouldn’t do it in libraries intended to be shared with other people since that won’t compile under advanced
@dnolen: I opened an issue at the Google Closure repo, for what it's worth. I'll continu with using separate source-paths for now, but hopefully they will get better at this in the future. Thanks for your help anyway. It's amazing how supportive the CLJ(S) community is. Three weeks into the Clojure world I'm still amazed.
@vincentdm: ok then I misrememberd you wanted nested JS if/else
. cond
+ identical?
should work in this case
@vincentdm: I just thought switch
worked - I know if/else
does
the condp doesn't work either. Well, to be clear: the code runs correctly (it always has), it's just that the unreachable branches are also included in the minified output.
@vincentdm: doesn’t work is less informative then a gist showing what you tried
But the problem seems to be the Closure Compiler, since the flags are properly parsed when cljsbuild generates the javascript.
@vincentdm: just gist the ClojureScript and the generated code
I’ve got it all working under lein, but I can’t get the tests to run under mvn test
, which is needed for the CI stuff.
@vincentdm: simple optimization + pretty-print will suffice for the generated output
Exception in thread "main" java.io.FileNotFoundException: Could not locate clojure/data/test_runner__init.class or clojure/data/test_runner.clj on classpath. Please check that namespaces with dashes use underscores in the Clojure file name., compiling:(/var/folders/ps/3v9y4vt15r1083hq6ymj0q980000gn/T/run-test521275451258951945.clj:21:1)
@dnolen: I tried to replicate my problem in a simple folder using the cljs.jar compiler with three source files but there it works correctly. The condp identical?
branching is transformed into a scalar in the output. So it must be something about the config of my project (cljsbuild project with latest clojurescript version as a dependency). But I'm glad that it is in fact possible to eliminate branches based on the goog.LOCALE setting. I'll just have to find out what difference is causing this...
@dnolen: turns out my test was wrong and the problem does exist. I made a gist like you asked: https://gist.github.com/vincent-dm/30701e1dbd5d13beb30b8e5e856e6fda
@vincent: it appears condp
introduces locals and for some reason doesn’t propagate the boolean return when assigning the predicate fn to a local
@dnolen: it seems the cond
+ identical
works, but given my previous jumping to conclusions, I'm going to try a few variants. Thanks for the pointer, as I could never have guessed that such subtleties would have such impact on the compilation.
@vincentdm: the subtleties are really an illusion
I have quick question. I have js file i load that contains a function handleSomething(args). How do i call that directly in my cljs file. (js/handleSomething args) doesn’t do the trick. Any ideas?
I said that several times - the problem is whether the ClojureScript you’re writing produces that identical JavaScript
I can see that now. But I guess a lot of people are wrongly assuming that any conditional based on a goog.* compiler option would lead to DCE. For example, the template I based my project on uses (def debug? ^boolean js/goog.DEBUG)
, and it turns out that branches based on that debug var are still included (not executed though).
So I'm not saying that anything is broken or should be changed, but maybe we can add a pointer in the docs about it?
For example here: https://github.com/clojure/clojurescript/wiki/Compiler-Options#closure-defines
@vincentdm: no PRs needed for the wiki just change it
@dnolen I have quick question. I have js file i load that contains a function handleSomething(args). How do i call that directly in my cljs file. (js/handleSomething args) doesn’t do the trick. Any ideas?
assuming you either aren’t using advanced compilation - if you are you must supply an extern for that fn
@dnolen: I updated the wiki https://github.com/clojure/clojurescript/wiki/Compiler-Options#closure-defines
@vincentdm: thanks much! I tweaked the formatting a bit - but otherwise looks great
Hi all, I have a perhaps very naive question: I see that CLJS -> JS compiler seem to generate a number of document.write operations, making it hard to use that sort of scripts with “async” or “defer” keywords in the script tag. Is there some known workaround for this (aside of not using async)?
@mksenzov: that’s only for dev, not for production - so it doesn’t actually matter in practice
@dnolen: thank you, that make sense. So when you refer to the ‘production’ mode - is this something enabled by one of the multiple optimization modes in CLJS?
A question related to extend-type
for IFn
protocol
Why the transpiled code contains implementation for call
, apply
and also cljs$core$IFn$_invoke$arity$1
?
In my understanding, the code for cljs$core$IFn$_invoke$arity$1
is not required