Hey all! I'm having trouble using planck to load a file with dependencies. I want to use moment.js form the clsjs repository
Here's my main file:
(ns jims-bas-ic-cljs-cron.derp
(:require [cljsjs.moment :as m])
)
(defn hola [hey]
(apply max [1 4 5 8 12 1.3]))
And my project.clj
(defproject jims-bas-ic-cljs-cron "0.1.0-SNAPSHOT"
:dependencies [[org.clojure/clojure "1.8.0"]
[org.clojure/clojurescript "1.8.51"]
[io.nervous/cljs-lambda "0.3.5"]
[cljsjs/moment "2.17.1-1"]]
:plugins [[lein-npm "0.6.2"]
[io.nervous/lein-cljs-lambda "0.6.6"]
[org.bodil/lein-noderepl "0.1.11"]]
:npm {:dependencies [[serverless-cljs-plugin "0.1.2"]]}
:repl-options {:init-ns jims-bas-ic-cljs-cron.core} ; *** note: dashes in namespaces ***
:cljs-lambda {:compiler
{:inputs ["src"]
:options {:output-to "target/jims-bas-ic-cljs-cron/jims_bas_ic_cljs_cron.js"
:output-dir "target/jims-bas-ic-cljs-cron"
:target :nodejs
:language-in :ecmascript5
:optimizations :none
}}})
I load up planck with planck -c src/
then (require 'jims-bas-ic-cljs-cron.derp)
But I get an error No such namespace: cljsjs.moment, could not locate cljsjs/moment.cljs, cljsjs/moment.cljc, or JavaScript source providing "cljsjs.moment" in file /Users/jameslynch/Git-Projects/Basic-Cron-Job-Clojurescript-Lambda/jims-bas-ic-cljs-cron/src/jims_bas_ic_cljs_cron/derp.cljs
Surely it must be possible to somehow use clsjs libraries in planck?
@derpocious as far as I see planck doesn't use your project.clj https://github.com/mfikes/planck/blob/master/site/src/dependencies.md
ah, so then I should explicitly try to load each library when I start planck?
when I try to do (require 'cljsjs.moment)
I get the error No such namespace: cljsjs.moment, could not locate cljsjs/moment.cljs, cljsjs/moment.cljc, or JavaScript source providing "cljsjs.moment"
. I don't see where that link addresses this
Thanks @noisesmith. Can you please clarify how I can load this library from the repl?
Responded in https://github.com/mfikes/planck/issues/553
@derpocious I'll take a look today to see what is occuring when it process the internal deps.cljs
to load cljsjs/development/moment.inc.js
as a foreign lib
Tanks @mfikes! I thought that "foreign lib" was referred to when you use straight up javascript library.
Ah, I see now on here https://github.com/cljsjs/packages/tree/master/moment that it wants me to use deps.clj
Yeah, it is essentially loading it as a JavaScript file.
And Planck loads cljsjs/development/moment.inc.js
into JavaScript core "straight up". But then the question is what happens when you do that.
idk, what happens? 🙂
you can use it like a namespace?
Well the JavaScript file is written to assume support for certain loading systems. So, I haven't figure it out beyond that yet.
It works in Lumo, FWIW, probably because the moment
library makes use of Node.js in an interesting way:
$ lumo -qD cljsjs/moment:2.17.1-1
cljs.user=> (require 'cljsjs.moment)
nil
cljs.user=> js/moment
#object[hooks]
But, to answer your question, you can't use foreign libs as a namespace (no Vars, nor namespace aliases, for example). After loading a foreign lib, you then use JavaScript interop to work with it.
ahhh, ok
If you look at cljsjs/development/moment.inc.js
, you will see what I'm talking about.
interesting. wow, thanks a lot! 🙂
but suppose I want to load multiple libs into my project. Can I do that? Do I have to explicitly write all of them in the startup command?
@derpocious Yes. Essentially, with regular ClojureScript, Planck, and Lumo, each lib you want to use needs to be on the classpath. With regular ClojureScript, you can use downstream tooling like lein
to accomplish this. But with Planck and Lumo, you either hand-craft -c
or use -D
as sugar to specify libraries in .m2
Having said that, there is a general move to have ClojureScript also support loading npm libraries (so from node_modules
instead of the classpath)
Yeah that would be great to be able to just do npm install - -save and just use it like a namespace. But can't we just use a package.json file?
And I've heard that project.clj is only for lein. Is there no "project file" for planck or lumo? Why not hook into a project.clj and automatically require all the namespaces? :)
I'm working on serverless nodejs aws lambda functions so everything is little functions, and I just want to be able to call them each from the repl.
@derpocious It would probably be relatively easy to have Planck look for project.clj
and deduce what the classpath needs to be. But a more difficult problem is ensuring that the libraries in project.clj
have been dowloaded from a public repo and placed in your local Maven artifact cache.
(The difficulty is that, while a lot of this tooling exists, it is based on the JVM, which Planck doesn't have at its disposal.)
@derpocious For now, a workaround in Planck is to use (.. js/planck -repl -moment)
in lieu of js/moment
.
Hmm ok, thanks!
I'm going to see if I can fix it https://github.com/mfikes/planck/issues/554
Can you suggest how I could use this js library https://github.com/ttezel/twit/blob/master/README.md in a clojurescript function and call it from planck?
Ok great :)
@derpocious It looks like that library is heavily set up to use Node.js. It has require
calls in its source, which don't exist in Planck's JavaScriptCore runtime. You might be able to do something funky like use ClojureScript's new npm support, ultimately having Google Closure converting the stuff to Closure Compatible code. What you really want, though is plain JavaScript
Thanks for the report @derpocious. Landed a fix on master.
$ planck -qD cljsjs/moment:2.17.1-1
cljs.user=> (require 'cljsjs.moment)
nil
cljs.user=> js/moment
#object[hooks]
If on macOS, master can be installed via brew install --HEAD planck