This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
2015-09-10
Channels
- # admin-announcements (1)
- # beginners (109)
- # boot (59)
- # cljs-dev (1)
- # clojure (101)
- # clojure-android (1)
- # clojure-denmark (4)
- # clojure-france (1)
- # clojure-japan (5)
- # clojure-russia (39)
- # clojurescript (186)
- # clojurex (3)
- # clojutre (2)
- # cursive (20)
- # datomic (6)
- # devops (6)
- # events (3)
- # hoplon (25)
- # jobs (1)
- # ldnclj (5)
- # off-topic (4)
- # reagent (3)
- # ring (2)
@potetm: Yeah, if you need something now, Zachary Kim's Vee is interesting. But React Native Android is RSN http://www.reactnativeandroid.com which leads to the all-important (= view (f data))
Anybody playing with using CLJS to build an Apple TV app?
cljs-ajax is async aljs-http + core.async is also async. So should I use cljs-ajax or aljs-http + core.async
@dnolen @maria: continuing with trying to get modular React libraries run as-is where I left off yesterday I've came across two more problems:
1)
absolute requires don't seem to work. That is even if I have React in foreign libs and another foreign lib does require('react');
I get an error like this
ERROR: JSC_ES6_MODULE_LOAD_ERROR. Failed to load module "react" at node_modules/react-motion/lib/Spring.js line 5 : 13
that indicates the library can't find react even though it's specified in foreign-libs. When using relative require (that is require('./react');
) everything works, provided react sits next to that file of course. Here's some sample code to demonstrate the problem - https://github.com/jaen/require-paths (there's branch broken
when for non-working code and working
for working code).
Of course if the goal is using the libraries as-is then we need to finda a better solution than manually changing all absolute requires to relative ones and possibly shuffling the files around (and you would either have to force each programmer to do this by hand on each lib update or keep the libs in source control),
2)
I've also noticed that output for foreign libs is flat - that is all foreign libs seems to be dumped to the root output folder. This seems problematic, since having a library with just an index.js
file is a pattern that seem to recur in node packages (in sgrove's sample it's 5 libs that do that) and that will result in libs clobbering each other. I imagine this could be solved by letting the user specify the output name/folder of the foreign lib.
I can provide a repo with reproduction for that later if needed (figured it's better to deal with the former issue first).
Of course I don't know what the best solution for those issues would be, so I'm leaving this here for discussion.So I wanted to generate some CSV data in ClojureScript and present it to the user as a downloadable file. Turns out the only reliable way to do this is: generate data — ship to the server — have the server expose it at a temporary URL — return the URL — redirect the browser to the URL. I feel like I'm reinventing FTP.
@jrychter: why not just generate and open a data uri? https://en.wikipedia.org/wiki/Data_URI_scheme
@crisptrutski: I want all browsers to reliably download the file, not display it in a browser window, which often happens for CSV data.
maybe a shim like https://github.com/dcneiner/Downloadify can help
@crisptrutski: No Flash, I'm trying to look forward. I also looked at FileSaver.js, but it requires additional shims for IE, and even then the W3C deprecated the File Writer API http://www.w3.org/TR/file-writer-api/
disappointing, yeah i see that download attribute below 50% support in browsers still 😞
From what I found, there is simply no good way to present a download from JavaScript. The "bounce through the server" solution works very well, but it really is FTP reinvented, from the early, non-PASV days (with a command channel and a separate data channel).
It's also a good example of how seemingly simple tasks ("let the user download tables as CSV") can explode into complex solutions.
it is truly ridiculous
imagine faking your ftp service at least with service worker if that lands first 😛
@jrychter: I would probably just go with a Flash solution if reach was the primary concern.
@jaen yeah the whole thing needs more consideration. Probably part of the issue is overloading :foreign-libs
when we should be focusing on :libs
. The whole point of module conversion is to allow these JS libs to be part of the build.
@dnolen: the exact distinction being?
If I understand docs correctly :foreign-libs
seem to deal in single files (possibly non-Closure compatible) that are used as-is, while :libs
can take both single files and library roots (provided they are Closure libs) that are then processed with GClosure like the rest of the codebase, or is this understanding wrong?
I'm just trying to understand how using :libs
instead of :foreign-libs
will help - will that for example mean I would specify something like, say, :libs [{:root "some/library" :module-type :commonjs :language-in :ecmascript6}]
and all requires will resolve properly, modules get translated to Closure modules and they take part in the build? Or is that a misreading of what you mean?
@jaen @maria @sgrove I’ve enumerated my thoughts here https://github.com/clojure/clojurescript/wiki/Enhanced-JavaScript-Module-Support
@dnolen: The author of Cursive mentioned that you may have gotten the js debugger of the commercial version of IDEA to work with ClojureScript. Is that true? Sounds awesome
@grav it's a little hacky but works thanks to source maps. The Node.js REPL supports :debug-port
option. I haven't bothered with investigating browser integration since the browser already works pretty well.
@cfleming: cool. I’ve tried setting it up by making sense of the Jetbrains' help pages in this regard, but they point to IDEA’s own source map generation, which doesn’t make sense
@dnolen: in the node shim path.resolve(".”)
is used but this is set to where node
was executed and not the path of the current file. Wouldn’t __dirname
be more appropriate here?
@martinklepsch: more importantly what problem are you trying to solve.
@dnolen: read the wiki page, sounds like a good plan (incidentally it seems I almost hit the right proposed syntax for :libs
in the comment right above yours, funny).
The :libs
part especially mirrors how I expect this to work - say I have package.json
with npm dependencies and then some Clojure code in boot that enumerates that and puts appropriate module roots in :libs
and then Clojurescript takes it from there.
One thing I noticed playing with sgrove's ReactMotion sample though that might be worth taking into consideration, is that some libs do have their own node_module
directories (as in they have a separate set of dependencies from the rest of libs, presumably to avoid conflicts). With :libs
as described in proposal I don't see any way to reflect that. Or do you think that's not an issue?
there’s really very little pressure to use ClojureScript + Node.js for server side stuff
so the end result would be to make it easy to package up any old random Node.js thing into a JAR and deploy that.
but really the most popular libs - jQuery, Underscore, lo-dash … no one’s going to bother with these.
@dnolen: when you invoke the shim from the commandline it fails loading any module unless you are in the directory the shim is in.
@dnolen: can easily be solved by :asset-path
but I’m just wondering if that’s intended
@martinklepsch: ok, I haven’t really put much thought into it since I don’t really use Node.js for anything other than library dev myself. Issue/patch welcome that clearly states the use case and a reasonable amount of testing that verifies it won’t break anything people are currently doing.
@dnolen: I'm not saying it is a goal for Clojurescript compiler to handle NPM directly, but a lot of frontend Javascript uses NPM to distribute their packages.
And I'm just wondering how a hypothetical tool (external to Clojurescript compiler) could tell the Clojurescript compiler that this lib a
here expects foo
to resolve to a/foo
, while this lib b
there expects foo
to resolve to b/foo
without having to modify any source code. Though I agree a case
@dnolen: not sure if patch without any breakage will be possible. I assume people have workarounds in place that expect current behaviour.
*cases where this might be needed will probably be far and between, so this might as well be ignored until someone complains with an example.
@jaen anything NPM related simply cannot work without more compiler support which we’re not going to bother with.
@jaen: I hear boot-npm
😛
@martinklepsch: right now I'm not thinking much further than "I want to get MaterialUI to work as-is", but if some useful code results from that, then why not
more neat boostrapped usage https://twitter.com/hirammadelaine/status/641960832373510144
@dnolen: so basically if something like that ever comes up in practice one would be doomed to fork the lib and maintain it for compatibility with Clojurescript compiler, right? Not that I'm complaining (since that hopefully sounds like once in a blue moon occurence), just wanted to clarify.
Isn’t there some material ui thing in cljsjs?
@jaen no, the whole point of including all this compilation machinery is to not have to fork the lib
@martinklepsch: this one is specifically React components, those two libs in cljsjs are not as far as I can tell.
That could very well be the case.
@jaen this is really about taking the cljsjs thing to the next logical step. Except you can dump needing to write externs and the thing is susceptible to all of Closure optimization, code splitting etc.
@dnolen: yeah, I was just wondering that if Clojurescript can't scope dependencies like NPM does (and there's no plans to do so) it might result in breakages for certain NPM packages that are sensitive to their dependencies being some exact version (hence having to fork them to somehow deal with that in their source). That said I think I'm somewhat convinced now that this can be addressed only if it ever comes up in practice (I tend to overengineer and this totally sounds like a case of this) and the proposal sounds good as-is.
Anyway, if there's anything else to be done wrt module enhancements I can try to help insofar my wits and time permits.
@dnolen: the download solution I implemented (bouncing from the server) works without flash and works well, so I'm happy with it for now. I just feel it is unnecessarily complex.
@jaen right but those issues are ones that anyone trying to use NPM for client side development will encounter. Again this is precisely the reason Bower happened. And why Browserify and other things have to use some de-duping which can’t eliminate these issues.
short answer, ClojureScript will never directly address the complexities introduced by NPM style package management.
leveraging the proposed solutions in some 3rd party thing is of course possible (though not recommended
Honestly I didn't do any complex frontend development before Clojurscript and React (just some usual Rails jQuery wrangling) so I wasn't aware of those issues and how that factors in.
@jaen ha, Browserify doesn’t dedupe - this is the NPM horrowshow https://github.com/substack/node-browserify/issues/692
@dnolen: Hi! What's the preferred way of "porting" clojure issues that also affect clojurescript? I've fixed a destructuring bug (http://dev.clojure.org/jira/browse/CLJ-1778) that I believe also applies to cljs. Report in jira and attach new patch?
@ragge, you can do that but for stuff like this we generally wait until it’s been vetted and applied to Clojure.
just wondering if there is a better way to coerce value into boolean, I don’t want to call 2 functions to do this: https://gist.github.com/darwin/5f7e0a5e8e5c1353c8cd
but it basically does the same thing, calls nil?, I guess I will leave it as is, ^boolean type-hint should inline it in advanced build I believe
@darwin I would not waste time worrying about 2 trivial fn calls. nil? not both inline
@dnolen @jaen: For consuming libraries that aren’t in e.g. cljsjs, I’m thinking about a preprocess step that takes a :libs-like declaration, and matches each :provides to a dir/file, and then generates a top-level js file with just those requires/exports that webpack can process into a single browser-loadable file, and then that file is all that the closure compiler ever sees
@sgrove: I also don’t know why you would want to use what you’re proposing, might as well just use JS if you want huge blobs of unoptimizable stuff.
@dnolen: That’s pretty bombastic. ReactMotion is a awesome library that fits in really well with functional nature of cljs, and I really don’t want to rewrite that library. I just want to consume it, and I’m looking for ways to do so that won’t hopelessly hobble my productivity or the deliverability of my apps
Anyway, I appreciate the work that’s happening, I’ll keep trying to figure out a way to make it work a bit more seamlessly.
@sgrove: Also remember that HTTP-2.0 is on the horizon. You don't want to merge libraries together anymore. Many JS files are just fine to load in modern browsers.
pretty much everything I’m hearing from the Google folks is that it doesn’t buy you anything in actuality and may even be detrimental.
but we’re talking about a distributed system, and after the first load, the server isn’t going to know what’s in the browser cache.
and once you realize that, Google Closure trying to just make the smallest thing possible still sounds like a rock-solid fast strategy
sgrove: you can consume a library without including it in the closure compilation pass -- most of the time that's the right thing for JS libs, as they're not designed for adv compilation -- most CLJSJS stuff works this way
@sgrove: that's one way to do it I suppose, but that would mean all Maria's work would have been for naught if we would just work around it. I'd wait to see if what @dnolen proposes is enough for most NPM-distributed libraries (and barring scoped dependencies it looks like it just might) and then decide what to do next. In the mean time you can follow what this library does I suppose - https://github.com/taylorSando/om-material-ui/tree/master/build-mui
you can certainly use something like webpack externally to translate it to directly browser consumable stuff, the std foreign-libs / CLJSJS plumbing will handle the concat
the asterisk there is you need externs, but such is the cost of advanced compilation!
@nullptr: I would not put too much weight into “not designed for advanced compilation"
hilariously ES6 and React-like perf sensitive libraries are becoming Closure compatible out of necessity
@dnolen: I didn't necessarily mean server-push, but mostly the multiplexing which makes downloading multiple JS files just as fast as one big JS file
@rauh yeah sorry, right. But my point stands client requests one thing, server believes it know what deps client needs (but it doesn’t)
it may turn out to be a win eventually, but I’ll remain skeptical until a very big company working at scale says it delivers anything of value.
YUI3 tried to do a smart server-side loader (you ask for a module and it provides it and any dependency modules you didn't already have) and it ended up being very difficult to manage and they eventually deprecated it.
@dnolen: Full disclosure: I haven't really tried (and measured) HTTP-2.0. I only re-stated this presentation: http://bit.ly/http2-opt (slide 29)
@jaen @sgrove I actually now think that the hack-y React @providesModule directive might turn out to work in our favor in this regard. In order to avoid the deduping issue they have their own packaging tool. But this means their model is actually inline with ours.
@dnolen: but that only helps us with React itself (and whomever decides to use that), right? Other libraries might not use that (for eg. libraries I or sgrove tried to integrate don't). But if they are there they do seem helpful, that's for sure.
@jaen this is true but once you venture out of React-land and other critical UI bits, JS libraries become less interesting to adopt - Closure has a crazy amount of stuff.
a lot of the JS integration stuff isn’t about being able to use anything, but filling in gaps not filled by the standard lib or Closure
Well, that's true that if you are doing React you suddenly have a lot less of need for things like tooltip or select libs or whatnot. But both ReactMotion and MaterialUI are React-land and don't have those annotations, so it's not universal.
but my suspicion is that stuff that needs to run on the client will naturally avoid things with deep deps for reasons I talked about earlier
Yeah, the dependencies remark makes sense, if it's really as problematic as you say it is (and that issue you linked certainly shows it can be).
So I imagine if Clojurescript will be able to handle ReactMotion and MaterialUI it will be able to handle most useful libraries
And if there's something that won't work, then potential fixes can be evaluated if that happens, I suppose
fwiw both Ember.js and React.js have had to deal with this problem - so we are not alone in working around it
@dnolen: Are build times like this expected with pseudo-names? https://gist.github.com/sgrove/49ad5f412add4c350c5d#file-build-L271
Trying to debug an issue that only happens under advanced compilation, so pseudo-names are fantastic, just surprised by the compilation time (although I think I remember some ml thread saying I should expect longer compile times for it)
@sgrove: no idea, make sure you are giving the JVM adequate memory settings, something between 1g-2g
@dnolen @jaen I am probably a bit late to the party, but here are my thoughts on the wiki entry to enhanced module support. I like the idea of supporting library specs in :libs
for converting JavaScript modules, since it highlights that those JavaScript moudules can be used in the same way as Google Closure modules after conversion. This would probably mean that we wouldn't support the :module-type
option in :foreign-libs
? But I think we would still need to support the :preprocess
option in :foreign-libs
since users might want to use this functionality separately without module conversion.
And :path
in the :libs
spec should probably either point to a single file or a directory?
@maria yes I agree that :module-type
+ :foreign-lib
doesn’t make that much sense in the context of the ideas expressed in the wiki entry. Agree with :preprocess
.
and yes to :path
pointing to a single file or directory, not sure what that key should actually be called, open to ideas.
@maria and no, not late to the party - won’t start working on anything or greenlighting anything without your feedback
it's probably already the best platform for working with closure and react, we've already won!
I'm already doing effortless live js coding. Now with module preprocessing I will probably be able to code arbitrary js modules live as well. and with externs generation ... I'll get all the GCComplier goodness as well.
@bhauman: I saw a couple people bringing up issues with Figwheel and auto-reloading in the latest releases. I’m seeing a version of that, where Figwheel is pushing JS files with an incorrect path. Known issue?
okay, I’ve cleaned the heck out of my project, but the paths that Figwheel is pushing are still wonky.
Ex: ("../imageatlas/pages/home.js" "../imageatlas/components/page.js" "../imageatlas/core.js”)
@dnolen :path
sounds good to me, it works for both, file or directory One thing we need to keep in mind is that the Google Closure compiler can only handle requires
that use a relative or absolute path when converting modules. That’s why jaen got the error mentioned above where the Google Closure compiler couldn’t locate react. And we always need to pass all the required files as source files to the Google Closure compiler when converting a module.
@maria right the relative or absolute path is an interesting problem - that’s not how Node.js require
actually works for installed modules.
passing all the inputs doesn’t seem like too hard a problem, @juhoteperi’s recent ticket to calculate all deps seems like it would do the trick
Hi #C03S1L9DN, I'm new to clj(s) and I'd like to try building an app on top of Parse. I found my way to cljsjs and noticed the Parse JS SDK wasn't packaged, so just submitted [my first PR](https://github.com/cljsjs/packages/pull/221). Following [these docs](https://github.com/cljsjs/packages/wiki/Creating-Packages), boot package build-jar
seems to have worked, but now I'm not sure how to test it locally. I have a (boot2-based) Hoplon6 app I'd like to include it in but not sure how. Anyone have a minute to pair with me?
weird. it just cropped up with the latest figwheel version. i’ve been working with the same setup for weeks.
@al3x: I'm deferring to goog.require and following it's conventions. But you know I can/should probably fix the relative path before the request.