This page is not created by, affiliated with, or supported by Slack Technologies, Inc.
@crocket See this exposition https://github.com/clojure/clojurescript/wiki/Dependencies#bundling-foreign-javascript-code and the :foreign-libs
compiler option https://github.com/clojure/clojurescript/wiki/Compiler-Options#foreign-libs in particular the :es6
:module-type
. (This is a relatively new compiler feature.)
On node.js, I could just use js/require. On web browsers, I could bundle npm dependencies with browserify in advance.
@crocket Well, npm
is a whole system for downloading deps, installing them locally etc., right? But, there is now support in ClojureScript at least for CommonJS libs, ignoring how you obtain them.
@crocket: yeah. If you have the path to the JavaScript, do that plus :module-type
:commonjs
@crocket if you are running in Node, perhaps js/require
followed by just using JavaScript interop leads to another valid approach
If I'm on a web browser, I could just bundle npm dependencies with browserify and include it in HTML before clojurescript bundle.
@crocket I can't speak to its reliability. It maps into capabilities provided by the Google Closure infrastructure. But, I personally have only limited experience with it (see http://blog.fikesfarm.com/posts/2015-12-22-foreign-libs-processing-in-repl.html)
jquery and other plain js libraries do not indicate which global variable is the module.
@crocket: My guess is there is no magic. Plain libs are just brought in and you can use JavaScript interop. Again, my experience is limited. Here I am using a plain lib (there are probably other more sophisticated examples out there): https://github.com/mfikes/replete/commit/5c2c6d85f89420b9ce4a52c8d5cfeab8f0d5217f
@crocket: You can use foreign libs in a REPL without the stuff in that blog post. The post is just about having the processing done without first doing a separate explicit build step.
I think :foreign-libs should capture a single global variable in a plain js module as the module to export.
I think someone should build something like Planck, but on Node; maybe name it Max, and flesh it out and maintain it. It could use @richiardiandrea's Replumb.
@mfikes: It takes 0.75second to compile and execute a very simple cljs program on cljs-repl. How long does it take on planck?
@crocket I think twice as fast in general. This is the best I've seen: https://mobile.twitter.com/mfikes/status/630157629495615488
I'm away from a computer right now. FWIW Planck can cache compilation. http://blog.fikesfarm.com/posts/2015-11-26-planck-caching.html
By the way in replumb there is a Repl demo with nodejs..at the moment it is missing eval cache though. I will add it after the holidays
@crocket: re: your modules question the :foreign-libs
:module-type
functionality is what I was referring to when I said "work done during GSoC". It works reliably, but it is limited in that you have to specify each file separately in foreign libs and the code should preferably be under your control, since you can only use relative requires with it. Here are examples using this functionality - https://github.com/mneise/circle-color and https://github.com/mneise/cljs-present
I know, so? I'm not sure what does have to do with using :module-type
, which I was talking about.
Unless I guess you want to turn a non-modular lib into a module before using :foreign-libs
which I guess you could, but since all Clojurescript code is namespaced, there's not all that much reason to.
For example take this - https://github.com/callemall/material-ui
And really, at the moment the easiest way is to make a browserify or webpack or whatever bundle
On web browsers, exposing require from a browserify bundle would be easy, but it feels like a hack.
Well, require
, import
and such work with :foreign-libs
that have :module-type
, but like I mentioned - with caveats
You can't, I don't know, do require("react/something")
and expect it to work. You have to put the lib in a folder besides the one you have your code in and do require("./react/src/something")
. That's how it was IIRC.
As for non-modular libs - it is only problematic in so far as a foreign lib could conflict with a foreign lib, which in practice is not that much of a problem (never happened to me when I was doing Rails with plain JS). It won't really conflict with your Clojurescript code since it's namespaced as GClosure modules.
So if you want to not expose globals at the toplevel by using shims, it's mostly your stylistic choice
As for foreign libs becoming simpler - I did work on that as I mentioned. Here are some experiments I did along the way - https://github.com/jaen/react-with-modular-cljs and https://github.com/jaen/custom-module-loaders (not sure if the latter would work right now), but there just wasn't enough interest from maintainers to keep it up.
Due to awesome powers of boot I can just use middleman to handle things like that - https://github.com/jgdavey/boot-middleman
crocket: if you do want to have kind of framework, create your own lein template and use it in every project
@crocket: well, I've meant a la carte (that is a menu of complete dishes) as opposed to smorgasbord where you compose your meal yourself, but now I've looked up the exact definition of that I can see how it could be confusing.
And yeah, there are templates, but nothing approaching the Rails level of just-rails-generate-it.
> I am investigating into clojure's CSS generator, but I used SASS before. then use sass :) lein-sass is good enough. It requires sassC installed, but it's ok, just install and use.
But nonetheless libsass not supporting extending SASS with Ruby is a thing that happens to be true, so it's good to be aware of that.
jaen: > without having to install Ruby. middleman is ruby gem: https://github.com/middleman/middleman so you still have to install ruby
Though last time I tried it (that was 2-ish years ago though) it would not compile my stylesheets to the same CSS Ruby SASS would.
@rm: it's true that's a Ruby gem, but boot-middleman
runs it in an embedded jRuby. So no, no need to have Ruby installed.
Sure. I like boot-middleman
because I can keep that Ruby workflow that is friendly to frontend developers, without having to force anyone else to install Ruby.
crocket: https://github.com/quile/node-cljs-template found this in google, readme looks nice
Yeah, that is a pretty annoying thing. Would be a nice feature to able to overlay (or underlay) some functions over all namespaces.
I created https://clojars.org/nrepl-figwheel-node/lein-template for developing nodejs clojurescript apps with figwheel on nREPL.
So as long as you have proper externs to avoid renaming on the Clojruescript output side, this should work.
GClosure doesn't care what the external Javascript is, it just needs to know what references in your code are references to libs external to the compilation
I never used Clojurescript with node.js, but I don't imagine it would be all that different than compiling for the browser - Clojurescript compiler outputs Javascript after all, you just have to run it. You would use node/require
as usual, but you will have to provide externs for functions you use from required modules if you use advanced optimisations, so Clojurescript doesn't rename the references in the compilation output. And you would probably not specify node libs as :foreign-libs
(foreign libs are pasted into the output verbatim), but rely on npm and node to resolve those.
But you would probably have to wait for someone with actual expertise for more concrete information.
That was good, but I wanted to hear about how to package an app and deliver it to end users.
I'd put that in .gitignore
and just require the end user to do npm install
before using your application.
This seems to be a working example of a Cljs node app - https://github.com/kissaten/cljs-nodejs-example
npm install -g cljs-module
is an option, but I was looking for a more elegant solution.
But isn't npm install -g whatever
what node world does for modules that have executables anyway?
For example that's how Arch does it - https://projects.archlinux.org/svntogit/community.git/tree/trunk/PKGBUILD?h=packages/stylus
According to my benchmark, the simplest program takes 0.09 second to launch after advanced optimization.
Blogposts here will be informative why Clojure is so slow to boot - http://blog.ndk.io/
A gloomy prospect is that clojurescript might be slow to boot in non-trivial programs
I wouldn't know - in general the bigger the program is, the slower it is to boot, but that's how it is for any sufficiently complex program.
I don't imagine boot time would be prohibitive for Clojurescript and node, but I don't have or know of any big enough codebase
That is certainly true, but I don't think it should be this much of a problem. But maybe then again there is someone here with a bigger node codebase to say how it behaves in practice.
One can cheat at getting the JVM/Clojure to start fast by using nailgun http://www.martiansoftware.com/nailgun/
ie. http://stackoverflow.com/questions/19107683/speed-up-clojure-startup-time-with-nailgun
Does anybody know how I can access an "id" property on a JS object? I can access all properties except for the one with the key "id"
chrome debugging console says the object has an "id" property and also shows a value for it
Try if get
here works maybe? https://closure-library.googlecode.com/git-history/docs/namespace_goog_object.html
it's the first i've heard of that fn, most docs I could find tell you to use "aget" or the ".-" form, do you know why neither of these work in my case?
No idea. What I know is .-
is equivalent to dot access (`a.b`), aget
is eqivalent to indexing (`a[b]`).
That's the code for get
- https://closure-library.googlecode.com/git-history/docs/local_closure_goog_object_object.js.source.html#line402
An idea I had to increase Leiningen speed, port it to self-hosted ClojureScript! 😄