This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2018-03-07
Channels
- # aleph (4)
- # arachne (2)
- # aws (2)
- # beginners (42)
- # boot (4)
- # cider (47)
- # cljs-dev (352)
- # clojure (278)
- # clojure-dusseldorf (6)
- # clojure-italy (6)
- # clojure-russia (1)
- # clojure-spec (15)
- # clojure-uk (94)
- # clojurescript (197)
- # community-development (34)
- # cursive (3)
- # data-science (1)
- # datomic (64)
- # emacs (3)
- # figwheel (16)
- # fulcro (7)
- # hoplon (5)
- # jobs (3)
- # luminus (3)
- # mount (2)
- # nyc (1)
- # off-topic (31)
- # onyx (22)
- # parinfer (1)
- # protorepl (7)
- # re-frame (9)
- # reagent (61)
- # ring-swagger (3)
- # shadow-cljs (149)
- # spacemacs (18)
- # specter (4)
- # timbre (1)
- # unrepl (38)
- # vim (17)
- # yada (14)
Why is this:
app:filippos.translations=> (keyword "unit" "4g")
:unit/4g
app:filippos.translations=> :unit/4g
clojure.lang.ExceptionInfo: NO_SOURCE_FILE [line 1, col 9] Invalid keyword: :unit/4g. {:type :reader-exception, :ex-kind :reader-error, :file "NO_SOURCE_FILE", :line 1, :col 9}
...
So I know the spec says ;; A keyword string, like a symbol, begins with a non-numeric
;; character and can contain alphanumeric characters and *, +, !, -,
;; _, and ?. (see for details).
but why can I construct one without namespace, eg. :4g
, with (keyword "unit" "4g")
but not :unit/4g
?The problem (that can really be circumvented in many ways is that I have a fixed set of constants (defined by a standard) and I’d hoped to just make them keys to translation maps that are stored as EDN. They are keyword-mapped and prefixed by their use (ie. unit/
for unit-like keys)
can anybody answer this https://groups.google.com/forum/?fromgroups#!topic/clojurescript/RHD05R77B7c ?
@sonnyto I guess this script file will generate cljs.jar. https://github.com/clojure/clojurescript/blob/master/script/uberjar This script is used from travis-ci. See https://github.com/clojure/clojurescript/blob/b23c77e230137840241a1ee3da45733813e647ac/.travis.yml#L20 .
Ah!
;; keyword does not validate input strings for ns and name, and may
;; return improper keywords with undefined behavior for non-conformant
;; ns and name.
That explains it.
Did not read that far below 😄
people should ask questions on the google groups instead of slack so that there is a searchable record. slack wouldnt let you search unless you pay
Better with http://clojureverse.org/
@mikko the keyword function is kind of counterintuitive (keyword "(+ foo bar baz)")
- no validation or sanity
a distribution question - does anyone have experience using yarn to publish cljs CLI scripts? Any gotchas?
@raymcdermott I have experience. no gotchas.
@thheller excellent - which toolchain did you use to create the scripts?
shadow-cljs
of course which is also the package on npm I made the experiences with 😉
yeah, I was looking at that and it does look excellent for this purpose
thanks
@thheller [ I understand that you’re biased but still, it does look right ]
based on this conversation https://github.com/kkinnear/zprint/issues/45 I made a little toy example of how I'd structure things https://github.com/thheller/zprint-npm
oh that’s great - thanks very much
basics is simple. the package
directory is what gets published to npm
. the build config writes package/main.js
looks like you use npm rather than yarn, no?
sure, ok just wanted to confirm - thanks
hmmm …. I’m missing something
when I run npm install
I don’t get the package installed anywhere
hmm - I’ll have to go read the manual properly
yes that’s what I mean
I did cd package; npm install
and that did not work
also now npm install ./package
barfs
enoent ENOENT: no such file or directory, chmod ‘/Users/ray/dev/oss/zprint-npm/node_modules/not-the-official-zprint/main.js’
so there is a step before this..
haha, no
like I said - I need to read the manual
shadow-cljs release script
compiles and optimizes the CLJS and writes the output to package/main.js
of course yes, sorry I was assuming that it was all hooked up
I will leave you alone now
yeah you’re a terrible person
it seems I have to call process.exit
even in the normal case - seems odd
otherwise I get JS runtime connected.
and I have to Ctrl-C
you are talking about watch
? that is the REPL client connecting to the server which will also keep the process alive.
{:source-paths
["src"]
:dependencies
[[zprint "0.4.6"]]
:builds
{:script {:target :node-script
:output-to "package/main.js"
:main zprint.npm/main
:compiler-options {:infer-externs :auto
:optimizations :advanced}
:devtools {:enabled false}}}}
regardless of that setting, I get the JS runtime connected
message with code like this …
(defn main
"obtain the tenant from the command line and save it to the config file"
[tenant]
(set-config!)
(if tenant
(spit (get-config-file-str) (vouch/set-tenant! tenant))
(js/process.stderr.write "Please specify the tenant\n")))
if I adjust the code to add js/process.exit
I don’t get the runtime connected message
whats your config? are you sure its in the correct location? don't use process.exit please 😛
so maybe I’m missing something about whether stdin
is hooked in somehow
I know - I don’t want to 🙂
JS runtime connected
is the REPL which gets injected by default connecting to the server.
I took the config from the zprint project you made
{:source-paths
["src"]
:dependencies
[[zprint "0.4.6"]]
:builds
{:script {:target :node-script
:output-to "package/main.js"
:main zprint.npm/main
:compiler-options {:infer-externs :auto
:optimizations :advanced}
:devtools
{:enabled false}}}}
ah, that’s possible
(in fact it did of course)
ok - phew
glad I asked
the watch still works so what do I lose
I’m writing a script so that’s not a concern on this one
how can I help you to document this?
good question. maybe I should mention it somewhere here? https://shadow-cljs.github.io/docs/UsersGuide.html#target-node
I get it now
yes, I think it would to have it mentioned for node CLI scripts
just had an idea. it should be possible to figure out if the REPL websocket is the only thing keeping the process alive. if so close it down and let the process exit.
that would be nice
then nothing to doc
I’ll fork it and give it a spin
this might sound like a silly question, but whenever I create an app using clojurescript (re-frame + reagent to be more specific), to deploy the app, I usually upload contents in my resources/public
to the server. is this not the way I should be deploying it?
@bravilogy depends on what is in your resources/public
😉
i was reading a tutorial on how to deploy a clojure application to digitalocean, and every single tutorial I’ve seen, they just talk about lein uberjar
command, but none of them mention the folder structure and clojurescript
part
yeah many people just bundle an uberjar and use a clj webserver to serve the files out of that jar
yeah, then you have to start doing server management since you have a static OS dependent thing specific to that server
(unless you use a bucket API like s3)
@bravilogy it depends on the server you use. ring can serve files from a directory just fine.
yeah I use ring. so a pseudo structure of the application would be
my-app
\
application.jar
uploads/
use ring.middleware.file
to serve the uploads
directory under whichever path you want
it's handy - in the end using a file system is the weird / inflexible thing
it's nice when I know putting my one uberjar on a server that can run java is all I need
I don't like using uberjars for .cljs since you have to restart the java process in order to update the cljs
complexity comes when I start trying to use resources tied to that server
@thheller: sure but at that point you are taking on the complexity of managing the server as a stateful resource, in exchange for the optimization of new cljs without restarts
it works, just be aware of the tradeoffs you are making complexity wise
@noisesmith given that I do CLJS updates with a frequency of like 10:1 compared to CLJ updates
right, sounds like that is worth it for you - for the app I've been working on for the last few years, there are rarely cljs updates that are not tied to new clj code, so it's simpler to just treat the whole app as a single uberjar package
and I’m guessing there’s no threat for end users to ‘read’ the BE code somehow, even though everything is served from 1 file right?
@bravilogy depends on how you expose those jar contents but typically no
@bravilogy in theory no more risk than it is to serve files from a file system that also include secrets
I mean, if you are serving from the fs, a misconfiguration means you could serve up the whole app as source code for download, right?
at least with serving inside a jar, the simple failure case is limited to things inside that jar :P
(in past ring versions there have been file system path traversal exploits btw, there's been no jar traversal exploits that I know of)
yeah I get that, but what I mean is for example in typical LEMP, you have a public or public_html folder which has index.php
file that loads the application that lives at the upper level of that public
folder
sure, and someone asks for ../../ and gets all your other files :P
I know what you mean, but in practice the management of resource paths inside a jar is actually simpler than managing them on the os level
@thheler ring had that bug very recently on file systems, but not serving from a jar
I know php has been fine, they got abused so much they had to fix it
if security matters to you at all, consider using nginx as a reverse proxy for actual access to things on disk though
@bravilogy but to your original point, I haven't heard of bugs serving unintended resources from jars - the classpath is managed relatively strictly. I have heard of bugs on the file system though.
yeah, that’s what I was trying to understand. I guess that standalone jar sort of ‘knows’ to only serve stuff from resources/public
specifically the wrap-resource ring handler is configured to look at a specific subpath
@bravilogy jars are basically zip files. nothing more.
a key thing here is that the java concept of classpath abstracts over things inside zip files as well as things on disk
I usually use travisCI to trigger my cljs compilations and then it automatically deploys whatever is in resources/public
so the same code can access things from either place, depending on what's visible at runtime (the classpath argument to the vm)
@olical Yes; fixed in 1.10.x https://dev.clojure.org/jira/browse/CLJS-2529
I'm guessing there will be another release before it's marked as stable. The current latest jar gives us errors around MapEntry in the schema lib, it looks like a fix for that went onto master a little while ago.
So we can't upgrade just yet, we're just going to drop our JDK version down until then.
@olical Having said that, if your toolchain is using deps.edn
ClojureScript can itself now be used as a git dep, so you can depend on the latest :sha
in the interim
Yeah, if you want the caching behavior, you need to depend on a built dep anyway (not a git dep)
Hi folks, have a rookie-level question: In the context of a CLJS web app, when we make network call from the client-side, an obvious idea is to execute it when the client triggers an event (ex: onClick). Are there other places/stages that can be good fit for network calls? Executing it within component lifecycle doesn't seem to be a great idea. What has been your experience?
depends on what kind of call, I work on an app where a websocket connection is initiated by the client (or else fail-over to long polling) and async callbacks are set up so the rest of the system doesn't start up until that facility is available
@mfikes clojurescript 1.10 has know issue with cyclic deps? I'm having problems trying to load my user.cljs
namespace.
@souenzzo No new regressions AFAIK. There is an older issue https://dev.clojure.org/jira/browse/CLJS-2055 where it fails to indicate cyclic deps and locks up. If you see a lock up do a jps
and then a jstack
on the compiler process to get the stack trace.
@noisesmith One common use-case is similar to the one you described - say, I want to render a component that shows the data for an user. But, before I render the component, I need to have this data (for certain user-id).
sure, I think a common thing (certainly what we do) is to start with the data parts empty and fill them in when the data comes back
It's on #figwheel repl. my hotreload isn't working anymore cos it cant load user.cljs. I'm deploying some patches, I will debug this problem soon.
@noisesmith hmm, yeah, this can work
How do I call await
on a js promise?
(.await p ...)
@lee.justin.m oh, I thought it was a method, if it's a syntax I don't know
and in that case .await ... might not even work
I’d be interested if there was actually a way to do that without a library. You can’t call await outside of a function that has been declared async
oh, right, that is special
thanks for the correction
but promisa has a macro to let you do this: http://funcool.github.io/promesa/latest/#async-await-syntax
i'm really just trying to simulate a long-running function call
(sleep x)
doesn't exist
oh wait, by long running, do you mean blocking and long running or async and long running
i'll be simulating an ajax call, so async. js/setTimeout
should work
it’s a slight pain because the scoping rules are different but a straight setTimeout or the combination of a Promise + timeout will almost always serve
thanks